Skip to content

Commit c237409

Browse files
Address review feedback
1 parent 8f047d4 commit c237409

1 file changed

Lines changed: 13 additions & 22 deletions

File tree

peps/pep-9999.rst

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ that was concise but problematic for type checkers and runtime defaults::
3232
id: int = Field(gt=0)
3333
name: str = Field(min_length=3)
3434

35-
The transition to ``Annotated`` cleanly separated type from metadata but
35+
The transition to ``Annotated`` cleanly separated types from metadata but
3636
introduced visual noise and cognitive overhead. Library authors often surface
3737
"special" types, like ``PositiveInt`` or ``EmailStr``, to hide this verbosity.
3838
These aliases are discoverable but inherently limited. Users needing unique
@@ -125,7 +125,7 @@ The proposed syntax is straightforward to implement. Prototypes for Mypy,
125125
Pyright, and Ruff are compact. Since ``@`` is already a valid expression
126126
operator, these tools do not require parser changes. They handle the new syntax
127127
during semantic analysis. Ruff has already prototyped a ``pyupgrade`` rule
128-
(``UP051``) for automated conversion. This enables large codebases to
128+
for automated conversion. This enables large codebases to
129129
migrate to the new syntax with minimal manual effort.
130130

131131
CPython prototype testing confirms that libraries like ``typer`` and
@@ -201,14 +201,10 @@ The ``repr()`` of an ``AnnotatedType`` uses the shorthand syntax::
201201
>>> int @ Field(gt=0)
202202
int @ Field(gt=0)
203203

204-
``__copy__`` and ``__deepcopy__`` are not supported on ``AnnotatedType``
205-
objects and will raise ``AttributeError``. This is a deliberate design
206-
choice to avoid ambiguity around shared mutable metadata.
207-
208204
``AnnotatedType`` objects support pickling via ``copyreg``, reconstructing
209205
through ``AnnotatedType[origin, *metadata]``.
210206

211-
``None`` on the left-hand side is accepted and uses ``NoneType`` as the
207+
``None`` on the left-hand side is accepted and uses ``None`` as the
212208
origin::
213209

214210
>>> None @ Field()
@@ -218,16 +214,9 @@ Supported Left-Hand Operands
218214
-----------------------------
219215

220216
The ``@`` operator is implemented by adding ``nb_matrix_multiply`` to the
221-
metatype (``type``) and to several typing-related types. The operator fires
222-
when the left-hand operand is any of the following:
223-
224-
- A type object (any class, including built-ins like ``int`` and ``str``)
225-
- ``None`` (treated as ``NoneType``)
226-
- ``types.UnionType`` (e.g., ``int | str``)
227-
- ``types.GenericAlias`` (e.g., ``list[int]``)
228-
- ``typing.TypeVar``, ``typing.ParamSpec``, ``typing.TypeVarTuple``
229-
- ``typing.TypeAliasType``
230-
- ``types.AnnotatedType`` (for chaining)
217+
metatype (``type``) and to several typing-related types. The operator is
218+
supported for any left-hand operand that currently supports the ``|``
219+
operator for making a union.
231220

232221
For all other left-hand operands, the operator returns ``NotImplemented``,
233222
allowing normal ``__matmul__`` dispatch to proceed.
@@ -288,10 +277,12 @@ is trapped inside the unresolved string and cannot be inspected until the
288277
forward reference is resolved. This is a blocking issue for libraries like
289278
Pydantic and FastAPI, which inspect metadata at class-definition time.
290279

291-
This proposal introduces a new format, ``Format.FORWARDREF_STRUCTURAL``,
292-
which evaluates compound type expressions **structurally**. When a name
293-
cannot be resolved, only that name is wrapped in ``ForwardRef``; the
294-
surrounding operators are still evaluated. The example above produces::
280+
This proposal introduces a new format, ``Format.FORWARDREF_STRUCTURAL``.
281+
This format assumes typing semantics and evaluates compound type expressions
282+
**structurally**. It always returns an ``AnnotatedType`` for ``@``, a union
283+
for ``|``, and a ``GenericAlias`` for subscripting. When a name cannot be
284+
resolved, only that name is wrapped in ``ForwardRef``; the surrounding
285+
operators are still evaluated. The example above produces::
295286

296287
AnnotatedType(ForwardRef('NotYetDefined'), Field(gt=0))
297288

@@ -348,7 +339,7 @@ metaclass.
348339
The private ``typing._AnnotatedAlias`` class is retained as a deprecated
349340
compatibility shim. Code using ``isinstance(x, typing._AnnotatedAlias)``
350341
will continue to work but emit a ``DeprecationWarning``. The shim is
351-
scheduled for removal in Python 3.23.
342+
scheduled for removal in Python 3.18.
352343

353344
Code that should be updated:
354345

0 commit comments

Comments
 (0)