GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — ModuleType.__annotations__ and type.__annotations__ result in AttributeError · Issue #123242 · python/cpython

ModuleType.__annotations__ and type.__annotations__ result in AttributeError #123242

New issue
Copy link
New issue
Copy link
Closed
#124557
Closed
ModuleType.__annotations__ and type.__annotations__ result in AttributeError#123242
#124557
Copy link
Labels
topic-typingtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

@ndjensen
ndjensen
opened on Aug 22, 2024
Issue body actions

Bug report

Bug description:

If you call dir() on ModuleType or type, it shows __annotations__ as one of the attributes. However, when you attempt to access that attribute, for ModuleType you get AttributeError: type object 'module' has no attribute '__annotations__' and for type you get AttributeError: type object 'type' has no attribute '__annotations__'.

>>> from types import ModuleType
>>> dir(ModuleType)
['__annotations__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
>>> ModuleType.__annotations__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'module' has no attribute '__annotations__'
>>> 
>>> dir(type)
['__abstractmethods__', '__annotations__', '__base__', '__bases__', '__basicsize__', '__call__', '__class__', '__delattr__', '__dict__', '__dictoffset__', '__dir__', '__doc__', '__eq__', '__flags__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__instancecheck__', '__itemsize__', '__le__', '__lt__', '__module__', '__mro__', '__name__', '__ne__', '__new__', '__or__', '__prepare__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__setattr__', '__sizeof__', '__str__', '__subclasscheck__', '__subclasses__', '__subclasshook__', '__text_signature__', '__weakrefoffset__', 'mro']
>>> type.__annotations__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'type' has no attribute '__annotations__'

I found this bug because I have a method that iterates over the attributes returned from dir and gets each attribute. After upgrading from Python 3.8 to 3.11, this caused an interesting failure. I would expect that attributes returned by dir() would be accessible and not result in an AttributeError.

CPython versions tested on:

3.11, 3.13

Operating systems tested on:

Linux

Linked PRs

  • gh-123242: Note that type.__annotations__ may not exist #124557
  • [3.12] gh-123242: Note that type.__annotations__ may not exist (GH-124557) #124562
  • [3.13] gh-123242: Note that type.__annotations__ may not exist (GH-124557) #124569

Activity

  1. ndjensen
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Aug 22, 2024
  2. sobolevn
    added
    topic-typing
    on Aug 22, 2024
  3. sobolevn commented on Aug 23, 2024

    @sobolevn
    sobolevn
    on Aug 23, 2024
    Member
    More actions

    Docs say:

    With an argument, attempt to return a list of valid attributes for that object.
    https://docs.python.org/3/library/functions.html#dir

    So, this seems like a bug to me. __annotations__ is not a valid attribute for this object. It should not be returned.

    I can see __abstractmethods__ there as well, which also raises:

    >>> type.__abstractmethods__
    Traceback (most recent call last):
      File "<python-input-1>", line 1, in <module>
        type.__abstractmethods__
    AttributeError: __abstractmethods__

    And __annotate__ for 3.14+

  4. picnixz commented on Aug 23, 2024

    @picnixz
    picnixz
    on Aug 23, 2024
    Member
    More actions

    Fun fact:

    >>> type.__annotations__
    Traceback (most recent call last):
      File "<python-input-62>", line 1, in <module>
        type.__annotations__
    AttributeError: type object 'type' has no attribute '__annotations__'. Did you mean: '__annotate__'?
    >>> type.__annotate__
    Traceback (most recent call last):
      File "<python-input-63>", line 1, in <module>
        type.__annotate__
    AttributeError: type object 'type' has no attribute '__annotate__'. Did you mean: '__annotations__'?
  5. picnixz commented on Aug 23, 2024

    @picnixz
    picnixz
    on Aug 23, 2024
    Member
    More actions

    @sobolevn Do you want to work on it? or can I take it perhaps?

  6. sobolevn commented on Aug 23, 2024

    @sobolevn
    sobolevn
    on Aug 23, 2024
    Member
    More actions

    @picnixz sure, go ahead!

  7. picnixz
    self-assigned this
    on Aug 23, 2024
  8. picnixz commented on Aug 23, 2024

    @picnixz
    picnixz
    on Aug 23, 2024
    Member
    More actions

    Ok, I see what happens:

    static PyObject *
    type_get_annotations(PyTypeObject *type, void *context)
    {
        if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
            PyErr_Format(PyExc_AttributeError, "type object '%s' has no attribute '__annotations__'", type->tp_name);
            return NULL;
        }
    	...
    }

    So the attribute does exist. It's just that it immediately raises an error. The reason why it's being listed in __dir__ is that it's actually set in the __dict__. So the question is: is it really a bug or not? it results in an AttributeError, yes, but maybe we could return an empty dict in the case of type? or maybe change the error message? (and for non-heap types, we would just return empty dicts everytime, but still disallow to set __annotations__).

    We could outright filter the output of type___dir___impl by rejecting __annotations__ and __annotate__ if we are dealing with a heap type, but only if a parent does not already have __annotations__.

    cc @JelleZijlstra

  9. JelleZijlstra commented on Aug 23, 2024

    @JelleZijlstra
    JelleZijlstra
    on Aug 23, 2024
    Member
    More actions

    I don't think the issue reported here is severe enough to justify changing this behavior. As Nikita noted, type.__abstractmethods__ behaves similarly.

  10. picnixz commented on Aug 24, 2024

    @picnixz
    picnixz
    on Aug 24, 2024
    Member
    More actions

    Well.. maybe amend the docs a little? or at least the error message? (though I don't have an better error message for that). Otherwise, we should close the issue. For beginners and for introspection tools, it could be undesirable (in Sphinx, I think we do getattr(obj, name, sentinel) even if we iterate over the names returned by dir but I should check that's indeed the case, otherwise we could have surprises).

  11. picnixz
    removed their assignment
    on Aug 24, 2024
  12. JelleZijlstra
    added a commit that references this issue on Sep 25, 2024

    pythongh-123242: Note that type.__annotations__ may not exist

    f33444f
  13. JelleZijlstra
    closed this as completedin #124557on Sep 25, 2024
  14. JelleZijlstra
    closed this as completedin 99b23c6on Sep 25, 2024
  15. JelleZijlstra
    added 3 commits that reference this issue on Sep 25, 2024

    pythongh-123242: Note that type.__annotations__ may not exist (python…

    99b23c6

    [3.12] pythongh-123242: Note that type.__annotations__ may not exist (p…

    045504a

    [3.12] gh-123242: Note that type.__annotations__ may not exist (GH-12…

    7ce138f
  16. emilyemorehouse
    added a commit that references this issue on Sep 26, 2024

    Merge branch 'main' into fix-help-double-prompt

    4cdb3ae
  17. JelleZijlstra
    added a commit that references this issue on Sep 26, 2024

    [3.13] pythongh-123242: Note that type.__annotations__ may not exist (p…

    33df56c
  18. Yhg1s
    added a commit that references this issue on Sep 26, 2024

    [3.13] gh-123242: Note that type.__annotations__ may not exist (GH-12…

    b27e227
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    topic-typingtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.