Unmangle private names ('__' prefix) in class declarations.
Fixes #166.
This commit is contained in:
@@ -1942,6 +1942,11 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
|
||||
break;
|
||||
}
|
||||
|
||||
// Return private names back to their original name
|
||||
const std::string class_prefix = std::string("_") + code->name()->strValue();
|
||||
if (varname->startsWith(class_prefix + std::string("__")))
|
||||
varname->setValue(varname->strValue().substr(class_prefix.size()));
|
||||
|
||||
PycRef<ASTNode> name = new ASTName(varname);
|
||||
|
||||
if (curblock->blktype() == ASTBlock::BLK_FOR
|
||||
|
@@ -14,10 +14,18 @@ public:
|
||||
bool isEqual(PycRef<PycObject> obj) const override;
|
||||
bool isEqual(const std::string& str) const { return m_value == str; }
|
||||
|
||||
bool startsWith(const std::string& str) const
|
||||
{
|
||||
return m_value.substr(0, str.size()) == str;
|
||||
}
|
||||
|
||||
void load(class PycData* stream, class PycModule* mod) override;
|
||||
|
||||
int length() const { return (int)m_value.size(); }
|
||||
const char* value() const { return m_value.c_str(); }
|
||||
const std::string &strValue() const { return m_value; }
|
||||
|
||||
void setValue(std::string str) { m_value = std::move(str); }
|
||||
|
||||
private:
|
||||
std::string m_value;
|
||||
|
BIN
tests/compiled/private_name.1.5.pyc
Normal file
BIN
tests/compiled/private_name.1.5.pyc
Normal file
Binary file not shown.
BIN
tests/compiled/private_name.2.2.pyc
Normal file
BIN
tests/compiled/private_name.2.2.pyc
Normal file
Binary file not shown.
BIN
tests/compiled/private_name.2.5.pyc
Normal file
BIN
tests/compiled/private_name.2.5.pyc
Normal file
Binary file not shown.
BIN
tests/compiled/private_name.2.7.pyc
Normal file
BIN
tests/compiled/private_name.2.7.pyc
Normal file
Binary file not shown.
28
tests/input/private_name.py
Normal file
28
tests/input/private_name.py
Normal file
@@ -0,0 +1,28 @@
|
||||
# Python mangles methods with a leading double-underscore with a leading
|
||||
# _<classname> prefix. This should be removed when emitting the source
|
||||
#
|
||||
# Valid Pythons: all
|
||||
|
||||
class Klass:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def method(self):
|
||||
pass
|
||||
|
||||
def _internal_name(self):
|
||||
pass
|
||||
|
||||
def __private_name(self):
|
||||
pass
|
||||
|
||||
var = 1
|
||||
_internal_var = 2
|
||||
__private_var = 3
|
||||
|
||||
k = Klass()
|
||||
k.method()
|
||||
k._internal_name()
|
||||
|
||||
# The following is not accessible due to mangling
|
||||
k.__private_name()
|
26
tests/tokenized/private_name.txt
Normal file
26
tests/tokenized/private_name.txt
Normal file
@@ -0,0 +1,26 @@
|
||||
class Klass : <EOL>
|
||||
<INDENT>
|
||||
def __init__ ( self ) : <EOL>
|
||||
<INDENT>
|
||||
pass <EOL>
|
||||
<OUTDENT>
|
||||
def method ( self ) : <EOL>
|
||||
<INDENT>
|
||||
pass <EOL>
|
||||
<OUTDENT>
|
||||
def _internal_name ( self ) : <EOL>
|
||||
<INDENT>
|
||||
pass <EOL>
|
||||
<OUTDENT>
|
||||
def __private_name ( self ) : <EOL>
|
||||
<INDENT>
|
||||
pass <EOL>
|
||||
<OUTDENT>
|
||||
var = 1 <EOL>
|
||||
_internal_var = 2 <EOL>
|
||||
__private_var = 3 <EOL>
|
||||
<OUTDENT>
|
||||
k = Klass ( ) <EOL>
|
||||
k . method ( ) <EOL>
|
||||
k . _internal_name ( ) <EOL>
|
||||
k . __private_name ( ) <EOL>
|
BIN
tests/xfail/private_name.3.0.pyc
Normal file
BIN
tests/xfail/private_name.3.0.pyc
Normal file
Binary file not shown.
BIN
tests/xfail/private_name.3.7.pyc
Normal file
BIN
tests/xfail/private_name.3.7.pyc
Normal file
Binary file not shown.
Reference in New Issue
Block a user