Unmangle private names ('__' prefix) in class declarations.

Fixes #166.
This commit is contained in:
Michael Hansen
2019-10-10 14:47:48 -07:00
parent 375b8b0c68
commit de78e1b882
10 changed files with 67 additions and 0 deletions

View File

@@ -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

View File

@@ -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;

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View 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()

View 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>

Binary file not shown.

Binary file not shown.