On Mon, 2021-12-13 at 09:57 +1100, Steven D'Aprano wrote: > On Sun, Dec 12, 2021 at 12:48:36PM -0800, Paul Bryan wrote: > > > But what's being annotated, the type or the attribute? > > That's easy to test: > > > > > > class A: > ... attr: Annotated[int, "Doc string"] > ... > > > > int.__annotations__ > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > AttributeError: type object 'int' has no attribute '__annotations__' > > > Okay, so it's not the type. *wink*
OK, so it's not the type, except it kind of is. In my other example, I used `Annotated` to create what I guess is (and what you suggested) a pseudo-type? When it was annotated it had nothing to do with any attribute. To reiterate: SomeType = Annotated[str, "some type"] No attribute here (yet). Only when this is applied as a type hint to an attribute would it then apply. class A: attr: SomeType `Annotated` certainly appears to be intended to provide hints about the type. In PEP 593, `MaxLen` is an example of prescribing constraints on value. It would apply to an attribute if that attribute was annotated with it as a type hint. By the way, to see real code implementing this convention see: https://github.com/fondat/fondat-core/blob/main/fondat/validation.py#L41 Here's another place that defines annotations that can be used to enhance API documentation (e.g. OpenAPI): https://github.com/fondat/fondat-core/blob/main/fondat/annotation.py (Disclosure: this is code I wrote.) Being able to define a new type like this using Annotated has proven to be very powerful. You can apply constraints and > It's the *class* that is annotated. But note that the mapping is > between > the attribute name to annotation, so in the sense that attributes are > represented by their name, it is the attribute that is annotated. It's unfortunate that the name `Annotated` was selected, because it's definitely a point that can result in confusion. An attribute can have an annotation (i.e. has a type hint); however, is `Annotated` annotating the attribute? It's an object that contains multiple values, which can be applied to an attribute as an annotation (type hint). > Unlike modules, classes and functions, the annotation cannot be on > the > attribute's *value*, because the attribute may not even have a value > at > this point. And even if it does, it might be immutable, or like the > type, many different attributes, with different annotations, may be > sharing the same value. Agree. > This rules out putting the docstring on the attribute directly. Agree. > The syntax shows us annotating the attribute, and that's exactly what > got annotated. I'm still not in aligned on this point. I think I agree that if you annotate an attribute with `Annotated`, you're defining a pseudo type that can serve to document the attribute. However, as I've demonstrated, that can be inherited by defining that type in advance and using it to annotate multiple attributes. As I suggested, I think a reasonable approach could be to either take the last string in the annotation, or combine multiple strings if present.
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/YAWO5EUWMC2HLY6XF55GW2NBOW3XTJ4B/ Code of Conduct: http://python.org/psf/codeofconduct/