Skip to content

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

Closed

Description

@gerritholl
mannequin
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']

    Activity

    1. gerritholl commented on Feb 3, 2014

      gerrithollmannequin
      MannequinAuthor

      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
    2. 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)[/+] on Feb 12, 2015
    3. eryksun commented on Feb 12, 2015

      @eryksun
      Contributor

      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'>
    4. vadmium commented on Dec 2, 2015

      @vadmium
      Member

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

    5. added
      docsDocumentation in the Doc dir
      and removed
      interpreter-core(Objects, Python, Grammar, and Parser dirs)
      on Dec 2, 2015
    6. eryksun commented on Feb 26, 2021

      @eryksun
      Contributor

      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.

    7. rhettinger commented on Feb 28, 2021

      @rhettinger
      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.

    8. rhettinger commented on Apr 5, 2021

      @rhettinger
      Contributor

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

    9. rhettinger commented on Apr 5, 2021

      @rhettinger
      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

    10. transferred this issue fromon Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    Labels

    3.10 (EOL)end of life3.8 (EOL)end of life3.9 (EOL)end of lifeinterpreter-core(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions