diff options
-rw-r--r-- | Lib/test/test_compile.py | 13 | ||||
-rw-r--r-- | Python/compile.c | 14 |
2 files changed, 25 insertions, 2 deletions
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 4cb619d..d1b6d8c 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -394,6 +394,19 @@ if 1: del d[..., ...] self.assertEqual((Ellipsis, Ellipsis) in d, False) + def test_mangling(self): + class A: + def f(): + __mangled = 1 + __not_mangled__ = 2 + import __mangled_mod + import __package__.module + + self.assert_("_A__mangled" in A.f.func_code.co_varnames) + self.assert_("__not_mangled__" in A.f.func_code.co_varnames) + self.assert_("_A__mangled_mod" in A.f.func_code.co_varnames) + self.assert_("__package__" in A.f.func_code.co_varnames) + def test_main(): test_support.run_unittest(TestSpecifics) diff --git a/Python/compile.c b/Python/compile.c index 9fa3cb1..9b1af92 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -194,7 +194,17 @@ _Py_Mangle(PyObject *privateobj, PyObject *ident) } p = PyString_AsString(privateobj); nlen = strlen(name); - if (name[nlen-1] == '_' && name[nlen-2] == '_') { + /* Don't mangle __id__ or names with dots. + + The only time a name with a dot can occur is when + we are compiling an import statement that has a + package name. + + TODO(jhylton): Decide whether we want to support + mangling of the module name, e.g. __M.X. + */ + if ((name[nlen-1] == '_' && name[nlen-2] == '_') + || strchr(name, '.')) { Py_INCREF(ident); return ident; /* Don't mangle __whatever__ */ } @@ -2243,7 +2253,7 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) return compiler_error(c, "can not assign to __debug__"); } - mangled = _Py_Mangle(c->u->u_private, name); +mangled = _Py_Mangle(c->u->u_private, name); if (!mangled) return 0; |