You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: peps/pep-0835.rst
+59-41Lines changed: 59 additions & 41 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -228,46 +228,11 @@ origin:
228
228
Supported Left-Hand Operands
229
229
-----------------------------
230
230
231
-
The ``@`` operator is implemented by adding ``nb_matrix_multiply`` to the
232
-
metatype (``type``) and to several typing-related types. The operator is
233
-
supported for any left-hand operand that currently supports the ``|``
234
-
operator for making a union.
231
+
The ``@`` operator is implemented by adding ``nb_matrix_multiply`` to the metatype (``type``) and to several typing-related types. The operator is supported for instances of ``type`` and other typing constructs that currently support the ``|`` operator for unions. The specific handling of ``None`` is currently unsettled (see Open Issues).
235
232
236
233
For all other left-hand operands, the operator returns ``NotImplemented``,
237
234
allowing normal ``__matmul__`` dispatch to proceed.
238
235
239
-
Parsing and Grammar
240
-
===================
241
-
242
-
This proposal requires no changes to the Python grammar. Because ``@`` is
243
-
already a valid operator, it is natively parsed as a binary operation. The
244
-
shorthand is resolved during semantic analysis, entirely bypassing the need
245
-
to patch grammar files or update the parser.
246
-
247
-
How to Teach This
248
-
=================
249
-
250
-
In Python, the ``@`` symbol already has an established association with
251
-
metadata through decorators. The annotation shorthand extends this
252
-
intuition to the type system: ``int @ Field(gt=0)`` reads as "``int``,
253
-
decorated with ``Field(gt=0)``."
254
-
255
-
For beginners, the key rule is simple: **in a type annotation, ``@`` means
256
-
"with this metadata."** The full ``Annotated[int, Field(gt=0)]`` syntax
257
-
remains available and is entirely equivalent for those who find it clearer.
258
-
259
-
For experienced developers, the precedence rules follow standard Python
260
-
operator precedence (``@`` binds tighter than ``|``), and chaining
Documentation and teaching materials should introduce the shorthand alongside
315
+
``Annotated``, not as a replacement. The longhand form is still preferred in
316
+
contexts where multiple metadata items are passed as a group and chaining
317
+
would be unwieldy.
318
+
319
+
Backwards Compatibility
320
+
=======================
321
+
324
322
Operator Overloading
325
323
--------------------
326
324
@@ -354,7 +352,7 @@ metaclass.
354
352
The private ``typing._AnnotatedAlias`` class is retained as a deprecated
355
353
compatibility shim. Code using ``isinstance(x, typing._AnnotatedAlias)``
356
354
will continue to work but emit a ``DeprecationWarning``. The shim is
357
-
scheduled for removal in Python 3.18.
355
+
scheduled for removal in Python 3.21.
358
356
359
357
Code that should be updated:
360
358
@@ -481,6 +479,26 @@ References
481
479
- :pep:`727` -- Documentation metadata in typing (Withdrawn)
482
480
- :pep:`749` -- Implementing PEP 649
483
481
482
+
Open Issues
483
+
===========
484
+
485
+
Supporting ``None``
486
+
-------------------
487
+
488
+
While the ``@`` operator naturally applies to instances of ``type``, it is currently unsettled how it should handle ``None``.
489
+
490
+
There are two primary options, both with notable downsides:
491
+
492
+
1. **Implement ``__matmul__`` on ``NoneType``:** This provides the best ergonomics, allowing ``None @ Metadata``. However, it introduces a runtime risk. If a user accidentally uses matrix multiplication on a ``None`` value (e.g., ``a @ b`` where ``a`` is ``None`` instead of a numpy array), it will silently return an ``Annotated`` object instead of raising a ``TypeError``.
493
+
2. **Do not support ``None @ Metadata``:** This avoids the runtime risk, but creates an ergonomic cliff. Users would be forced to write ``type(None) @ Metadata`` or fall back to ``typing.Annotated[None, Metadata]``.
494
+
495
+
The authors of this PEP lean slightly in favor of implementing ``__matmul__`` on ``NoneType`` for its ergonomic benefits, but ultimately defer to the Typing Council and community discussion to decide the best path forward.
496
+
497
+
Deprecation Timeline
498
+
--------------------
499
+
500
+
This PEP schedules the removal of the ``typing._AnnotatedAlias`` compatibility shim for Python 3.21, following the standard 5-year deprecation policy (:pep:`387`). However, given the widespread use of ``typing.Annotated``, the exact timeline for removal—or whether the shim should be retained indefinitely to prevent churn in legacy code—remains open for community discussion.
0 commit comments