This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author larry
Recipients eric.smith, gvanrossum, larry
Date 2021-04-21.22:56:29
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1619045790.07.0.418989332843.issue43901@roundup.psfhosted.org>
In-reply-to
Content
> - Is it possible to create __annotations__ lazily? (IIRC in January we came to a conclusion about this, something like yes for modules but for classes, or the other way around?)

Maybe for modules, definitely not for classes.  The problem is that best practice for classes is to look in the class dict for __annotations__.  That sidesteps the inheritance problem.

Functions already lazily create a dict __annotations__ if not set.  And it's not stored in the function dict.  So nobody ever looks in the function dict for __annotations__.  That all works fine.

Would you prefer that *just classes* lazily create __annotations__?  It's not hard code to write, but I was being cautious.  "always set __annotations__ to an empty dict" is the easiest code to write and get correct.  And since modules are not all that numerous even in the largest projects, it seemed like this un-optimized approach would have a minimal contribution to the heat death of the universe.

It's also remotely possible that someone out there does look in the module dict for __annotations__, though I admit I've never seen it.  It seems like it'd be tempting to write your code that way though:

    if isinstance(o, (type, types.ModuleType)):
        ann = o.__dict__.get("__annotations__", None)
    elif callable(o):
        ann = o.__annotations__
    else:
        raise ValueError(f"{o!r} doesn't support annotations")


> - Why would __annotations__ ever be None?

Simply because it's the cheapest sensible way to indicate "this object has no annotations".  It would be nice if the world accepted __annotations__ being None to mean "no annotations".  But I don't think we're there.

I note that the function object has a special setter for __annotations__ (func_set_annotations()), since at least Python 3.1, which explicitly only allows setting __annotations__ to either a dict or None.  (I didn't have 3.0 handy.)


> Why do you allow setting it to None?

Me?  I've never contributed code to Python that restricts the permissible types of values one is allowed to set on __annotations__.

Function objects are opinionated as mentioned (either dict or None), classes and modules have no opinion whatsoever, and allow you to set __annotations__ to any value.  That was all true long before I started working on annotations.


> Do we know of people ever write '__annotations__ = None' in their class or write 'cls.__annotations__ = None'?

AFAIK I've never seen anyone set __annotations__ to None.


> - And where's your PR?

Not done yet.  I only started it last night, and there were a lot of test failures--it turns out, a *lot* of regression tests do a sanity check that __annotations__ isn't set on classes (and maybe modules too).  For example, I was surprised that test_opcodes has two such test failures.
History
Date User Action Args
2021-04-21 22:56:30larrysetrecipients: + larry, gvanrossum, eric.smith
2021-04-21 22:56:30larrysetmessageid: <1619045790.07.0.418989332843.issue43901@roundup.psfhosted.org>
2021-04-21 22:56:30larrylinkissue43901 messages
2021-04-21 22:56:29larrycreate