Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

super behaviour and abstract base classes (either implementation or documentation/error message is wrong) #64702

Closed
gerritholl mannequin opened this issue Feb 3, 2014 · 7 comments
Assignees
Labels
3.8 only security fixes 3.9 only security fixes 3.10 only security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error

Comments

@gerritholl
Copy link
Mannequin

gerritholl mannequin commented Feb 3, 2014

BPO 20503
Nosy @rhettinger, @gerritholl, @vadmium, @eryksun, @miss-islington
PRs
  • bpo-20503: Show how isinstance() works with ABC registered classes. #25175
  • [3.9] bpo-20503: Show how isinstance() works with ABC registered classes. (GH-25175) #25202
  • Dependencies
  • bpo-23674: super() documentation isn't very clear
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/rhettinger'
    closed_at = <Date 2021-04-05.20:12:39.078>
    created_at = <Date 2014-02-03.15:36:42.585>
    labels = ['interpreter-core', 'type-bug', '3.8', '3.9', '3.10']
    title = 'super behaviour and abstract base classes (either implementation or documentation/error message is wrong)'
    updated_at = <Date 2021-04-05.20:12:39.077>
    user = 'https://github.com/gerritholl'

    bugs.python.org fields:

    activity = <Date 2021-04-05.20:12:39.077>
    actor = 'rhettinger'
    assignee = 'rhettinger'
    closed = True
    closed_date = <Date 2021-04-05.20:12:39.078>
    closer = 'rhettinger'
    components = ['Interpreter Core']
    creation = <Date 2014-02-03.15:36:42.585>
    creator = 'Gerrit.Holl'
    dependencies = ['23674']
    files = []
    hgrepos = []
    issue_num = 20503
    keywords = ['patch']
    message_count = 7.0
    messages = ['210141', '235852', '255686', '387731', '387797', '390254', '390258']
    nosy_count = 6.0
    nosy_names = ['rhettinger', 'docs@python', 'Gerrit.Holl', 'martin.panter', 'eryksun', 'miss-islington']
    pr_nums = ['25175', '25202']
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue20503'
    versions = ['Python 3.8', 'Python 3.9', 'Python 3.10']

    @gerritholl
    Copy link
    Mannequin Author

    gerritholl mannequin commented Feb 3, 2014

    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

    @gerritholl gerritholl mannequin added the interpreter-core (Objects, Python, Grammar, and Parser dirs) label Feb 3, 2014
    @BreamoreBoy BreamoreBoy mannequin changed the 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) Feb 12, 2015
    @eryksun
    Copy link
    Contributor

    eryksun commented Feb 12, 2015

    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'>

    @vadmium
    Copy link
    Member

    vadmium commented Dec 2, 2015

    I am proposing some documentation changes in bpo-23674 which would address this.

    @vadmium vadmium added docs Documentation in the Doc dir and removed interpreter-core (Objects, Python, Grammar, and Parser dirs) labels Dec 2, 2015
    @eryksun
    Copy link
    Contributor

    eryksun commented Feb 26, 2021

    The docs still need to clarified that isinstance(obj, type) is a necessary but not sufficient condition for success. It would also be helpful if the error message were less confusing in the case of registered subclasses such as numbers.Number.

    @eryksun eryksun added 3.8 only security fixes 3.9 only security fixes 3.10 only security fixes type-feature A feature request or enhancement labels Feb 26, 2021
    @meanboy27277 meanboy27277 mannequin added topic-argument-clinic type-bug An unexpected behavior, bug, or error and removed type-feature A feature request or enhancement labels Feb 26, 2021
    @larryhastings larryhastings added interpreter-core (Objects, Python, Grammar, and Parser dirs) and removed docs Documentation in the Doc dir topic-argument-clinic labels Feb 27, 2021
    @rhettinger
    Copy link
    Contributor

    This is a bit out of date. The isinstance() docs now specify that the predicate tests for direct, indirect, and virtual inheritance. Likewise, the super() docs already specify that only the __mro__ is searched. So those docs are already precise.

    Am thinking of adding a FAQ entry about when direct inheritance is required and include the OP's example. FWIW, this isn't really about super(). It affects any attribute lookup or any other property of inheritance. A true result from instance() doesn't imply that actual inheritance has occurred.

    @rhettinger rhettinger assigned rhettinger and unassigned docspython Feb 28, 2021
    @rhettinger
    Copy link
    Contributor

    New changeset 7bc25ec by Raymond Hettinger in branch 'master':
    bpo-20503: Show how isinstance() works with ABC registered classes. (GH-25175)
    7bc25ec

    @rhettinger
    Copy link
    Contributor

    New changeset 028d528 by Miss Islington (bot) in branch '3.9':
    bpo-20503: Show how isinstance() works with ABC registered classes. (GH-25175) (GH-25202)
    028d528

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.8 only security fixes 3.9 only security fixes 3.10 only security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    4 participants