@@ -243,10 +243,16 @@ be assignable to ``TypeForm``::
243243
244244 v5: TypeForm[set[str]] = "set[str]" # OK
245245
246+ The typing spec defines syntactic rules for type expressions in the form of a
247+ :ref: `formal grammar <typing:expression-grammar >`. Semantic rules are specified
248+ as comments along with the grammar definition. Contextual requirements are detailed
249+ throughout the typing spec in sections that discuss concepts that appear within
250+ type expressions. For example, the special form ``Self `` can be used in a
251+ type expression only within a class, and a type variable can be used within
252+ a type expression only when it is associated with a valid scope.
253+
246254Expressions that violate one or more of the syntactic, semantic, or contextual
247- rules for type expressions should not evaluate to a ``TypeForm `` type. The rules
248- for type expression validity are explained in detail within the typing spec, so
249- they are not repeated here::
255+ rules for type expressions should not evaluate to a ``TypeForm `` type.::
250256
251257 bad1: TypeForm = tuple() # Error: Call expression not allowed in type expression
252258 bad2: TypeForm = (1, 2) # Error: Tuple expression not allowed in type expression
@@ -300,14 +306,6 @@ Assignability
300306 t1: TypeForm[int | str] = get_type_form() # OK
301307 t2: TypeForm[str] = get_type_form() # Error
302308
303- ``type[T] `` is a subtype of ``TypeForm[T] ``, which means that ``type[B] `` is
304- assignable to ``TypeForm[A] `` if ``B `` is assignable to ``A ``::
305-
306- def get_type() -> type[int]: ...
307-
308- t3: TypeForm[int | str] = get_type() # OK
309- t4: TypeForm[str] = get_type() # Error
310-
311309``TypeForm `` is a subtype of ``object `` and is assumed to have all of the
312310attributes and methods of ``object ``.
313311
@@ -532,6 +530,35 @@ of ``type``.
532530.. _
designed :
https://mail.python.org/archives/list/[email protected] /message/D5FHORQVPHX3BHUDGF3A3TBZURBXLPHD/ 533531
534532
533+ Treat ``type[T] `` as a subtype of ``TypeForm[T] ``
534+ -------------------------------------------------
535+
536+ It was suggested that type ``type[T] `` should be considered a subtype
537+ of ``TypeForm[T] ``. This was ultimately rejected because there are ways to
538+ create an object of type ``type[T] `` that does not encode a valid type expression.
539+ For example, the expression ``type[1] `` is not a valid type expression. Likewise,
540+ the expression ``type[S] `` is not a valid type expression if ``S `` is an
541+ out-of-scope type variable. This same argument applies to other special forms
542+ like objects of type ``UnionType ``, which may or may not encode a valid type
543+ expression. Rather than carving out a special case for ``type[T] `` that would
544+ allow for potential unsoundness, it was decided to treat all type forms
545+ consistently. Therefore, ``type[T] `` is not considered a subtype of ``TypeForm[T] ``.
546+
547+ It was also pointed out that the expression ``C | C `` (where ``C `` is a class
548+ object) is a valid type expression - and therefore a valid ``TypeForm ``,
549+ but its runtime type form encoding is an instance of ``UnionType `` and
550+ therefore is not compatible with ``type[C] ``.
551+
552+ If a function wishes to indicate that it accepts values of type ``TypeForm[T] ``
553+ _and_ ``type[T] ``, the parameter can simply be annotated with a union of these
554+ two types.
555+
556+ ::
557+
558+ def func[T](t: TypeForm[T] | type[T]) -> None: ...
559+
560+
561+
535562Accept arbitrary annotation expressions
536563---------------------------------------
537564
@@ -547,7 +574,7 @@ not as a parameter type or a return type:
547574
548575 def foo(not_reassignable: Final[object]): ... # Error: Final not allowed here
549576
550- def nonsense() -> Final[object]: ... # Error: Final not alowed here
577+ def nonsense() -> Final[object]: ... # Error: Final not allowed here
551578
552579With the exception of ``Annotated ``, type qualifiers are not allowed in type
553580expressions. ``TypeForm `` is limited to type expressions because its
0 commit comments