classification
Title: Behavior of assigning to __dict__ is not documented
Type: enhancement Stage: needs patch
Components: Documentation, Interpreter Core Versions: Python 3.4, Python 3.3, Python 2.7
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: docs@python Nosy List: Arfrever, Malcolm Smith, amaury.forgeotdarc, cvrebert, davide.rizzo, docs@python, ezio.melotti, merwok, pitrou
Priority: normal Keywords:

Created on 2012-07-15 17:25 by davide.rizzo, last changed 2017-07-13 23:10 by Malcolm Smith.

Messages (4)
msg165538 - (view) Author: Davide Rizzo (davide.rizzo) * Date: 2012-07-15 17:25
The documentation (at least the obvious places, see Doc/reference/datamodel.rst) says classes and class instances have the '__dict__' attribute, but nothing is said about what happens when assigning to it (like obj.__dict__ = something).

As far as I understand that's undefined behavior and other implementations may not work the same as CPython (and CPython itself behaves differently between versions).

I'd submit a documentation patch if I knew how to specify this matter. Maybe just say the behavior is not defined?
msg165772 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2012-07-18 13:36
What kind of behavior are you referring to?
Are there really differences between versions?
msg165983 - (view) Author: Davide Rizzo (davide.rizzo) * Date: 2012-07-20 22:37
Amaury, I don't honestly know, I would have proposed something otherwise.

I have been advised on #python (Freenode) not to assign to obj.__dict__ because its behaviour changes between versions and implementations, but I wouldn't know what has changed between CPython version.

One obscure thing is what can be assigned to __dict__. For class dicts no assignment is allowed. Object dicts can be assigned dict objects. If you try to assign a non-dict mapping it will complain.

However you can assign a dict-derived object, something like:

class SillyDict(dict):
    def __getitem__(self, key):
        return "hello"

obj.__dict__ = SillyDict()

Unfortunately accessing the attributes of obj will still use PyDict_* functions, thus ignoring any magic methods.

PyPy's behavior is slightly different. A class __dict__ attribute still is read only, but you can assign any mapping object to an object __dict__.
msg166492 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2012-07-26 16:14
I think assigning to __dict__ is an implementation detail; we shouldn't document it before it is clearly agreed what it should do (which probably deserves asking on python-dev).
History
Date User Action Args
2017-07-13 23:10:20Malcolm Smithsetnosy: + Malcolm Smith
2012-07-26 16:14:58pitrousetnosy: + pitrou
messages: + msg166492
2012-07-26 06:44:08cvrebertsetnosy: + cvrebert
2012-07-22 22:25:06merwoksetnosy: + merwok
2012-07-22 20:03:38ezio.melottisetnosy: + ezio.melotti

type: enhancement
stage: needs patch
2012-07-20 22:37:52davide.rizzosetmessages: + msg165983
2012-07-18 17:02:57Arfreversetnosy: + Arfrever
2012-07-18 13:36:05amaury.forgeotdarcsetnosy: + amaury.forgeotdarc
messages: + msg165772
2012-07-15 17:25:06davide.rizzocreate