classification
Title: super behaviour and abstract base classes (either implementation or documentation/error message is wrong)
Type: Stage:
Components: Documentation Versions: Python 3.6, Python 3.5, Python 3.4, Python 2.7
process
Status: open Resolution:
Dependencies: 23674 Superseder:
Assigned To: docs@python Nosy List: Gerrit.Holl, docs@python, eryksun, martin.panter, rhettinger
Priority: normal Keywords:

Created on 2014-02-03 15:36 by Gerrit.Holl, last changed 2015-12-02 01:02 by martin.panter.

Messages (3)
msg210141 - (view) Author: Gerrit Holl (Gerrit.Holl) * Date: 2014-02-03 15:36
When using an abstract base class, super(type, obj) throws a TypeError stating "obj must be an instance (...) of type", even though isinstance(obj, type) returns True.  I'm not sure what is supposed to happen here, but either the error message and the documentation for super would need to be reformulated, or there is an issue with the implementation, or I am misunderstanding something.

Python 3.3.3 (default, Dec 12 2013, 11:13:02) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numbers
>>> super(numbers.Number, 0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: super(type, obj): obj must be an instance or subtype of type
>>> isinstance(0, numbers.Number)
True
msg235852 - (view) Author: Eryk Sun (eryksun) * Date: 2015-02-12 19:28
Given super(cls, obj), cls needs to be somewhere in type(obj).__mro__. Thus the implementation checks PyType_IsSubtype instead of the more generic PyObject_IsSubclass. 

In this case int's MRO is unrelated to numbers.Number:

    >>> print(*int.__mro__, sep='\n')
    <class 'int'>
    <class 'object'>

It gets registered as a subclass via numbers.Integral.register(int).

    >>> print(*numbers.Integral._abc_registry)
    <class 'int'>

issubclass calls PyObject_IsSubclass, which uses the __subclasscheck__ API. In this case ABCMeta.__subclasscheck__ recursively checks the registry and caches the result to speed up future checks.

    >>> numbers.Number.__subclasscheck__(int)
    True
    >>> print(*numbers.Number._abc_cache)
    <class 'int'>
msg255686 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2015-12-02 01:02
I am proposing some documentation changes in Issue 23674 which would address this.
History
Date User Action Args
2015-12-02 01:02:16martin.pantersetassignee: docs@python
dependencies: + super() documentation isn't very clear
components: + Documentation, - Interpreter Core
versions: + Python 2.7, Python 3.6
nosy: + docs@python, martin.panter

messages: + msg255686
2015-02-12 19:28:51eryksunsetnosy: + eryksun
messages: + msg235852
2015-02-12 14:22:15BreamoreBoysetnosy: + rhettinger
versions: + Python 3.4, Python 3.5, - Python 3.3

title: super behavioru and abstract base classes (either implementation or documentation/error message is wrong) -> super behaviour and abstract base classes (either implementation or documentation/error message is wrong)
2014-02-03 15:36:42Gerrit.Hollcreate