python / cpython

The Python programming language
https://www.python.org
Other
62.75k stars 30.08k forks source link

Descriptors get invoked in old-style objects and classes #62247

Closed 0b0bcf20-2b68-4990-b6c4-a0088e594eb9 closed 11 years ago

0b0bcf20-2b68-4990-b6c4-a0088e594eb9 commented 11 years ago
BPO 18047
Nosy @rhettinger, @ezio-melotti, @merwok, @phmc
Files
  • desc.py
  • 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: ```python assignee = None closed_at = created_at = labels = ['interpreter-core', 'type-bug'] title = 'Descriptors get invoked in old-style objects and classes' updated_at = user = 'https://bugs.python.org/icecrime' ``` bugs.python.org fields: ```python activity = actor = 'rhettinger' assignee = 'none' closed = True closed_date = closer = 'rhettinger' components = ['Interpreter Core'] creation = creator = 'icecrime' dependencies = [] files = ['30356'] hgrepos = [] issue_num = 18047 keywords = [] message_count = 4.0 messages = ['189896', '190135', '190237', '190273'] nosy_count = 5.0 nosy_names = ['rhettinger', 'ezio.melotti', 'eric.araujo', 'pconnell', 'icecrime'] pr_nums = [] priority = 'normal' resolution = 'rejected' stage = 'needs patch' status = 'closed' superseder = None type = 'behavior' url = 'https://bugs.python.org/issue18047' versions = ['Python 2.7'] ```

    0b0bcf20-2b68-4990-b6c4-a0088e594eb9 commented 11 years ago

    In the Data Model section of the documentation regarding descriptors invokations (http://docs.python.org/2/reference/datamodel.html#invoking-descriptors), it is said:

    Note that descriptors are only invoked for new style objects or classes (ones that subclass object() or type()).

    However, it seems this restriction isn't enforced in practice:

        Python 2.7.4 (default, May 16 2013, 13:28:03)
        [GCC 4.2.1 Compatible Apple Clang 4.0 ((tags/Apple/clang-421.0.60))] on darwin
        Type "help", "copyright", "credits" or "license" for more information.
        >>> class Desc(object):
        ...     def __get__(self, obj, cls):
        ...             return 'test'
        ...
        >>> class A:  # Not inheriting object here
        ...     desc = Desc()
        ...
        >>> A().desc
        'test'

    I dived into CPython's code and saw no trace of a test for new-style classes in the descriptor invokation code path (down in classobject.c / instance_getattr2).

    Unfortunately, fixing this behavior doesn't seem trivial as class methods appear to be implemented as descriptor themselves. In other words, and from my understanding, restricting descriptor invokation to new-style objects and classes would prevent method calls on old-style classes.

    rhettinger commented 11 years ago

    IMO nothing should change here (either the docs or the implementation).

    The OP has observed an implementation detail of old-style classes (which were reimplemented in Python 2.2 using descriptor logic instead of their former hard-wired behaviors).

    0b0bcf20-2b68-4990-b6c4-a0088e594eb9 commented 11 years ago

    Sorry if I am missing something, but it seems that the documentation doesn't match the behavior: the doc says that descriptors are invoked only for new styles objects and classes, while the attached code seems to prove the contrary.

    If my understanding is correct, either the doc or the code should be changed accordingly.

    rhettinger commented 11 years ago

    We document what we're willing to guarantee. The exposure of descriptors in old-style classes was an incidental implementation detail.

    Sorry, I'm going to close this one. Besides, it's time to start forgetting Python 2 and move along :-)