This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Identifiers begining with __ renamed
Type: Stage:
Components: Interpreter Core Versions: Python 2.4
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: georg.brandl, w_barnes
Priority: normal Keywords:

Created on 2006-08-14 07:47 by w_barnes, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (5)
msg29509 - (view) Author: W Barnes (w_barnes) Date: 2006-08-14 07:47
Identifiers used in a class function that start with 
__ are renamed to _classname__identifer even if the 
identifier is owned by some other object.

Code snippet:

size = len(Data.__entry_dates)

Here I'm trying to access the identifier 
__entry_dates in the module Data from the function 
DataTestCase.testEntryDates() but I get the following:

Traceback (most recent call last):
  File "DataTest.py", line 247, in testEntryDates
    size = len(Data.__entry_dates)
AttributeError: 'module' object has no 
attribute '_DataTestCase__entry_dates'

I'm using Python 2.4.3 on Windows XP sp2

Thanks,
Walter
msg29510 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2006-08-14 08:07
Logged In: YES 
user_id=849994

This is exactly how __ name mangling is supposed to work.
These are meant to be private, and thus shouldn't be
accessed from another class.

If the attribute was in another class, you could do the
mangling (with the correct class name!) yourself, as it's on
a module in this case, use __dict__:
size = len(Data.__dict__['__entry_dates'])
msg29511 - (view) Author: W Barnes (w_barnes) Date: 2006-08-16 02:10
Logged In: YES 
user_id=1541460

Thanks!

I was unaware that name mangling applied to global 
attributes as well as class attributes.

The error message is a bit misleading though. If I define 
__widget in foo then access it from bar as foo.__widget 
why does it rename it as _bar__widget if it was not 
defined there? If it needs to do this internally why not 
use the unmangled name for the error message?
msg29512 - (view) Author: W Barnes (w_barnes) Date: 2006-08-16 04:29
Logged In: YES 
user_id=1541460

I just noticed some more weirdness in regards to name 
mangling...

Apparently there is no way for a class to access global 
attributes that are declared private. That is if a 
module 'foo' has a global attribute '__widget' a 
class 'bar' also defined in foo will get the following 
error if it attempts to access __widget:

NameError: global name '_bar__widget' is not defined

Using either _foo__widget directly or __dict__ doesn't 
work.

For now, I can get around this by using a non-private 
global helper function as a middle man.

I'm a Python newbie but, for what it's worth, here are 
some suggestions:

First, if an attribute is accessed as a child of some 
object other than 'self' or the name of the enclosing 
class no name mangling should be done. It seems that name 
mangling isn't necessary here as an attribute error will 
all ways be raised whether or not the object has that 
attribute.

Second, when searching for a global attribute that begins 
with __ it should be renamed to reflect the name of the 
module not the enclosing class. In the example above, if 
_bar__widget cannot be found in bar then it should look 
for _foo__widget in the global namespace.

Finally, as I mentioned before, for clarity if no match is 
found the error message should include the unmangled name.
msg29513 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2006-08-16 06:34
Logged In: YES 
user_id=849994

> The error message is a bit misleading though. If I define 
> __widget in foo then access it from bar as foo.__widget 
> why does it rename it as _bar__widget if it was not 
> defined there? If it needs to do this internally why not 
> use the unmangled name for the error message?

This is how name mangling works. All __x attribute access in
a class is mangled with *this* class's name -- it happens in
the compiling stage, where the compiler doesn't know
anything but this name (this also rules out changing the
error message). In case of other classes' attributes this is
fine since the attribute is *supposed* to be private to this
other class.

With global __x variables, the advice is "don't do that".
Still, I have no problem accessing them through the module's
__dict__, unmangled of course.
History
Date User Action Args
2022-04-11 14:56:19adminsetgithub: 43815
2006-08-14 07:47:16w_barnescreate