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.

Author serhiy.storchaka
Recipients eric.snow, rhettinger, serhiy.storchaka
Date 2015-10-17.17:21:34
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <4304260.CpbrLUAp50@raxxla>
In-reply-to <1445097680.66.0.821868605697.issue25410@psf.upfronthosting.co.za>
Content
> Regarding Py_TYPE(od) vs. od.__class__, there is a difference for
> subclasses, as you demonstrated in your example. [1]  Thanks for explaining
> your rationale.  I now understand your argument about using PyTYPE() for
> repr and pickle in C types.  I still have concerns, though, regarding
> parity between the two OrderedDict implementations.
> 
> The key difference is that we're talking about an after-the-fact C port of
> an existing pure Python implementation.

There is no a difference. io, pickle, ElementTree, bz2, virtually all 
accelerator classes was created as replacements of pure Python 
implementations. All C implementations use Py_TYPE(self) for repr() and 
pickling. I think this deviation is common and acceptable.

Backward compatibility related to __class__ assignment was already broken in C 
implementation. In 3.4 following code works:

>>> from collections import *
>>> class foo(OrderedDict):
...     def bark(self): return "spam"
... 
>>> class bar(OrderedDict):
...     pass
... 
>>> od = bar()
>>> od.__class__ = foo
>>> od.bark()
'spam'

In 3.5 it doesn't.

> That particular difference in the implementations (i.e. you *can* change
> od.__class__ for the pure Python one) is an acceptable compatibility break
> since it's unlikely anyone is changing od.__class__ *and* if they are then
> they can just switch to a simple subclass that wraps OrderedDict:
> 
>     # before:
>     from collections import OrderedDict
>     od = OrderedDict()
>     od.__class__ = SomethingElse
> 
>     # after:
>     import collections
>     class OrderedDict(collections.OrderedDict):
>         pass
>     od = OrderedDict()
>     od.__class__ = SomethingElse

No, this assignment is forbidden (due to #24912). You can't set __class_ for 
an instance of a subclass of non-heap type.

> It may be worth taking this to python-dev to get a clearer consensus on both
> "Py_TYPE(obj) vs. obj.__class__", as well as about parity between dual
> pure-Python/C implementations in the stdlib, regardless of the outcome of
> this issue.  Both are points about which we should be consistent throughout
> Python.  The type() vs. __class__ question may deserve an entry in the
> language reference and both may deserve a PEP.

Could you please raise a discussion on Python-Dev? You will formulate the 
problem better.
History
Date User Action Args
2015-10-17 17:21:35serhiy.storchakasetrecipients: + serhiy.storchaka, rhettinger, eric.snow
2015-10-17 17:21:35serhiy.storchakalinkissue25410 messages
2015-10-17 17:21:34serhiy.storchakacreate