@@ -213,41 +213,52 @@ following should be allowed::
213
213
Syntax
214
214
^^^^^^
215
215
216
- ``Annotated `` is parameterized with a type and an arbitrary list of
217
- Python values that represent the annotations. Here are the specific
218
- details of the syntax:
216
+ ``Annotated `` is parameterized with a *base expression * and at least one
217
+ Python value representing associated *metadata *::
219
218
220
- * The first argument to `` Annotated `` must be a valid type
219
+ from typing import Annotated
221
220
222
- * Multiple type annotations are supported (``Annotated `` supports variadic
221
+ Annotated[BaseExpr, Metadata1, Metadata2, ...]
222
+
223
+ Here are the specific details of the syntax:
224
+
225
+ * The base expression (the first argument to ``Annotated ``) must be valid
226
+ in the context where it is being used:
227
+
228
+ * If ``Annotated `` is used in a place where arbitrary
229
+ :term: `annotation expressions <annotation expression> ` are allowed,
230
+ the base expression may be an annotation expression.
231
+ * Otherwise, the base expression must be a valid :term: `type expression `.
232
+
233
+ * Multiple metadata elements are supported (``Annotated `` supports variadic
223
234
arguments)::
224
235
225
236
Annotated[int, ValueRange(3, 10), ctype("char")]
226
237
227
- * ``Annotated `` must be called with at least two arguments (
228
- ``Annotated[int] `` is not valid)
238
+ * There must be at least one metadata element (``Annotated[int] `` is not valid)
229
239
230
- * The order of the annotations is preserved and matters for equality
240
+ * The order of the metadata is preserved and matters for equality
231
241
checks::
232
242
233
243
Annotated[int, ValueRange(3, 10), ctype("char")] != Annotated[
234
244
int, ctype("char"), ValueRange(3, 10)
235
245
]
236
246
237
247
* Nested ``Annotated `` types are flattened, with metadata ordered
238
- starting with the innermost annotation ::
248
+ starting with the innermost `` Annotated `` expression ::
239
249
240
250
Annotated[Annotated[int, ValueRange(3, 10)], ctype("char")] == Annotated[
241
251
int, ValueRange(3, 10), ctype("char")
242
252
]
243
253
244
- * Duplicated annotations are not removed::
254
+ * Duplicated metadata elements are not removed::
245
255
246
256
Annotated[int, ValueRange(3, 10)] != Annotated[
247
257
int, ValueRange(3, 10), ValueRange(3, 10)
248
258
]
249
259
250
- * ``Annotated `` can be used with nested and generic aliases::
260
+ * ``Annotated `` can be used in definition of nested and generic aliases,
261
+ but only if it wraps a :term: `type expression `::
251
262
252
263
T = TypeVar("T")
253
264
Vec = Annotated[list[tuple[T, T]], MaxLen(10)]
@@ -272,33 +283,51 @@ details of the syntax:
272
283
SmallInt = Annotated[int, ValueRange(0, 100)]
273
284
SmallInt(1) # Type error
274
285
286
+ :pep: `593 ` and an earlier version of this specification used the term
287
+ "annotations" instead of "metadata" for the extra arguments to
288
+ ``Annotated ``. The term "annotations" is deprecated to avoid confusion
289
+ with the parameter, return, and variable annotations that are part of
290
+ the Python syntax.
291
+
292
+ Meaning
293
+ ^^^^^^^
294
+
295
+ The metadata provided by ``Annotated `` can be used for either static
296
+ or runtime analysis. If a library (or tool) encounters an instance of
297
+ ``Annotated[T, x] `` and has no special logic for metadata element ``x ``, it
298
+ should ignore it and treat the expression as equivalent to ``T ``. Thus, in general,
299
+ any :term: `type expression ` or :term: `annotation expression ` may be
300
+ wrapped in ``Annotated `` without changing the meaning of the
301
+ wrapped expression. However, type
302
+ checkers may additionally choose to recognize particular metadata elements and use
303
+ them to implement extensions to the standard type system.
304
+
305
+ ``Annotated `` metadata may apply either to the base expression or to the symbol
306
+ being annotated, or even to some other aspect of the program.
275
307
276
- Consuming annotations
277
- ^^^^^^^^^^^^^^^^^^^^^
308
+ Consuming metadata
309
+ ^^^^^^^^^^^^^^^^^^
278
310
279
- Ultimately, the responsibility of how to interpret the annotations (if
311
+ Ultimately, deciding how to interpret the metadata (if
280
312
at all) is the responsibility of the tool or library encountering the
281
313
``Annotated `` type. A tool or library encountering an ``Annotated `` type
282
- can scan through the annotations to determine if they are of interest
314
+ can scan through the metadata to determine if they are of interest
283
315
(e.g., using ``isinstance() ``).
284
316
285
- **Unknown annotations: ** When a tool or a library does not support
286
- annotations or encounters an unknown annotation it should just ignore it
287
- and treat annotated type as the underlying type. For example, when encountering
288
- an annotation that is not an instance of ``struct2.ctype `` to the annotations
289
- for name (e.g., ``Annotated[str, 'foo', struct2.ctype("<10s")] ``), the unpack
290
- method should ignore it.
317
+ **Unknown metadata: ** When a tool or a library does not support
318
+ metadata or encounters an unknown metadata element, it should ignore it
319
+ and treat the annotation as the base expression.
291
320
292
- **Namespacing annotations : ** Namespaces are not needed for annotations since
293
- the class used by the annotations acts as a namespace.
321
+ **Namespacing metadata : ** Namespaces are not needed for metadata since
322
+ the class of the metadata object acts as a namespace.
294
323
295
- **Multiple annotations : ** It's up to the tool consuming the annotations
296
- to decide whether the client is allowed to have several annotations on
297
- one type and how to merge those annotations .
324
+ **Multiple metadata elements : ** It's up to the tool consuming the metadata
325
+ to decide whether the client is allowed to have several metadata elements on
326
+ one annotation and how to merge those elements .
298
327
299
- Since the ``Annotated `` type allows you to put several annotations of
300
- the same (or different) type(s) on any node , the tools or libraries
301
- consuming those annotations are in charge of dealing with potential
328
+ Since the ``Annotated `` type allows you to put several metadata elements of
329
+ the same (or different) type(s) on any annotation , the tools or libraries
330
+ consuming the metadata are in charge of dealing with potential
302
331
duplicates. For example, if you are doing value range analysis you might
303
332
allow this::
304
333
@@ -313,12 +342,11 @@ Aliases & Concerns over verbosity
313
342
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
314
343
315
344
Writing ``typing.Annotated `` everywhere can be quite verbose;
316
- fortunately, the ability to alias annotations means that in practice we
345
+ fortunately, the ability to alias types means that in practice we
317
346
don't expect clients to have to write lots of boilerplate code::
318
347
319
- T = TypeVar('T')
320
- Const = Annotated[T, my_annotations.CONST]
348
+ type Const[T] = Annotated[T, my_annotations.CONST]
321
349
322
350
class C:
323
- def const_method(self: Const[List [int]]) -> int:
351
+ def const_method(self, x : Const[list [int]]) -> int:
324
352
...
0 commit comments