On Mon, 2021-12-13 at 11:22 +1100, Steven D'Aprano wrote:
> On Sun, Dec 12, 2021 at 03:38:23PM -0800, Paul Bryan wrote:
> 
> > OK, so it's not the type, except it kind of is.
> 
> Except it isn't annotating the type, it is annotating the attribute.
> 
> We don't annotate *types*:
> 
>     int: Sequence[str]
> 
> That would be a regular variable or attribute called "int" that just 
> shadowed the builtin type int. We annotate *variables* (including 
> function parameters and class attributes).
> 
> 
> > 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"]
> 
> That's not an annotation. That's a type alias.
> 
> Annotations follow a colon, not an equals sign.

1. While I agree that assigning the `Annotated` value to `SomeType`
makes `SomeType` a type alias, what do you call the specific instance
of `Annotated[...]` itself? To date, I've been referring to it as a
type, but that's also muddying the waters here.

2. I've been flyng fast and loose with the term "annotate". No help
from PEP 593, which convolutes the situation with passages such as:

> Annotated is parameterized with a type and an arbitrary list of
> Python values that represent the annotations.

To rephrase, if I add a string "some type" to an `Annotated` instance,
it would not be documenting the (non-existent) attribute, it would
arguably be documenting the type itself. 

Getting concrete:

Coordinate = Annotated[int, "a graph coordinate", ValueRange(-100, 100)]
...
@dataclass
class Point:
  x: Annotated[Coordinate, "the horizontal coordinate"]
  y: Annotated[Coordinate, "the vertical coordinate"]

I suggest that in these uses of strings in `Annotated`, the 1st case
would serve to document the "coordinate" (pseudo-)type, while the 2nd
and 3rd cases would serve to document the attributes themselves. In
some cases, a developer may very well be satisfied with the
documentation of the (pseudo-)type and not override it when annotating
the attribute.

> > `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.
> 
> And until some variable or attribute was actually annotated with it,
> it 
> might as well not exist.

The use of `Annotated` is to decorate an existing type to provide
additional metadata about it. The `Coordinate` type alias in the
example above can be introspected at runtime, independently of its use
in an annotation. If such a type alias were in a module, I would want
its documentation string to be displayed to provide additional context
about it, and help in determining if it's appropriate to use as an
annotation of an variable, parameter, attribute.

> 
> Annotated allows us to create new types, by associating arbitrary 
> metadata with an existing type. The meaning of that metadata is 
> completely unspecified. So we can say:
> 
>     Vec = Annotated[List[Tuple[T, T]], MaxLen(10)]
> 
> but that has no real meaning until you annotate a variable or
> attribute, 
> in which case the Vec type is annotated onto the attribute.

So, I think we agree that an `Annotated` instance results in what's
tantamount to a new type. And I hope by my examples above, we could
agree that it would be reasonable to document such a type in such a way
that its usage in an annotation could either inherit it, or override
it.

> That use-case for Annotated is independent of the proposed use-case 
> here. Sure you can use it to create new types, or type-aliases. But 
> that's not the only thing we can use it for.
> 
> The meaning of MaxLen(10) is unspecified. To a human reader, we can 
> guess that it probably means that the list can have a length of no
> more 
> than 10. Any tooling that comes across it is supposed to ignore it if
> it 
> doesn't know how to interpret it.
> 
> So for all we know, MaxLen(10) is not enforced by any tool, and it is
> purely there as documentation to the reader: "Please don't make your 
> vector longer than ten items".
> 
> We're not limited to only using Annotated to create new types. In an 
> annotation, we can associate arbitrary metadata with the annotated 
> attribute or variable. The interpretation of that metadata is still
> up 
> to the consumer. Is it a type restriction? Is it a docstring? Is it 
> something else? It's entirely up to the tooling.

I agree with the above.

_______________________________________________
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/MVIS6C5H2FYF2ZKMBO6FD76WEEKCW65Q/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to