-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
PEP 747: Updated to reflect the latest round of feedback #4204
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -243,10 +243,16 @@ be assignable to ``TypeForm``:: | |
|
|
||
| v5: TypeForm[set[str]] = "set[str]" # OK | ||
|
|
||
| The typing spec defines syntactic rules for type expressions in the form of a | ||
| :ref:`formal grammar <typing:expression-grammar>`. Semantic rules are specified | ||
| as comments along with the grammar definition. Contextual requirements are detailed | ||
| throughout the typing spec in sections that discuss concepts that appear within | ||
| type expressions. For example, the special form ``Self`` can be used in a | ||
| type expression only within a class, and a type variable can be used within | ||
| a type expression only when it is associated with a valid scope. | ||
|
|
||
| Expressions that violate one or more of the syntactic, semantic, or contextual | ||
| rules for type expressions should not evaluate to a ``TypeForm`` type. The rules | ||
| for type expression validity are explained in detail within the typing spec, so | ||
| they are not repeated here:: | ||
| rules for type expressions should not evaluate to a ``TypeForm`` type.:: | ||
|
|
||
| bad1: TypeForm = tuple() # Error: Call expression not allowed in type expression | ||
| bad2: TypeForm = (1, 2) # Error: Tuple expression not allowed in type expression | ||
|
|
@@ -300,14 +306,6 @@ Assignability | |
| t1: TypeForm[int | str] = get_type_form() # OK | ||
| t2: TypeForm[str] = get_type_form() # Error | ||
|
|
||
| ``type[T]`` is a subtype of ``TypeForm[T]``, which means that ``type[B]`` is | ||
| assignable to ``TypeForm[A]`` if ``B`` is assignable to ``A``:: | ||
|
|
||
| def get_type() -> type[int]: ... | ||
|
|
||
| t3: TypeForm[int | str] = get_type() # OK | ||
| t4: TypeForm[str] = get_type() # Error | ||
|
|
||
| ``TypeForm`` is a subtype of ``object`` and is assumed to have all of the | ||
| attributes and methods of ``object``. | ||
|
|
||
|
|
@@ -532,6 +530,35 @@ of ``type``. | |
| .. _designed: https://mail.python.org/archives/list/typing-sig@python.org/message/D5FHORQVPHX3BHUDGF3A3TBZURBXLPHD/ | ||
|
|
||
|
|
||
| Treat ``type[T]`` as a subtype of ``TypeForm[T]`` | ||
| ------------------------------------------------- | ||
|
|
||
| It was suggested that type ``type[T]`` should be considered a subtype | ||
| of ``TypeForm[T]``. This was ultimately rejected because there are ways to | ||
| create an object of type ``type[T]`` that does not encode a valid type expression. | ||
| For example, the expression ``type[1]`` is not a valid type expression. Likewise, | ||
| the expression ``type[S]`` is not a valid type expression if ``S`` is an | ||
| out-of-scope type variable. This same argument applies to other special forms | ||
| like objects of type ``UnionType``, which may or may not encode a valid type | ||
| expression. Rather than carving out a special case for ``type[T]`` that would | ||
| allow for potential unsoundness, it was decided to treat all type forms | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also don't think there is any possible unsoundness that could result from making |
||
| consistently. Therefore, ``type[T]`` is not considered a subtype of ``TypeForm[T]``. | ||
|
|
||
| It was also pointed out that the expression ``C | C`` (where ``C`` is a class | ||
| object) is a valid type expression - and therefore a valid ``TypeForm``, | ||
| but its runtime type form encoding is an instance of ``UnionType`` and | ||
| therefore is not compatible with ``type[C]``. | ||
|
|
||
| If a function wishes to indicate that it accepts values of type ``TypeForm[T]`` | ||
| _and_ ``type[T]``, the parameter can simply be annotated with a union of these | ||
| two types. | ||
|
|
||
| :: | ||
|
|
||
| def func[T](t: TypeForm[T] | type[T]) -> None: ... | ||
|
|
||
|
|
||
|
|
||
| Accept arbitrary annotation expressions | ||
| --------------------------------------- | ||
|
|
||
|
|
@@ -547,7 +574,7 @@ not as a parameter type or a return type: | |
|
|
||
| def foo(not_reassignable: Final[object]): ... # Error: Final not allowed here | ||
|
|
||
| def nonsense() -> Final[object]: ... # Error: Final not alowed here | ||
| def nonsense() -> Final[object]: ... # Error: Final not allowed here | ||
|
|
||
| With the exception of ``Annotated``, type qualifiers are not allowed in type | ||
| expressions. ``TypeForm`` is limited to type expressions because its | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although I agree with the conclusion that
type[T]should not be a subtype ofTypeForm[T], I don't think this argument makes sense.type[1]andtype[S]do not "create an object of typetype[T]" in the first place, so they are irrelevant here. They do create an object of typetypes.GenericAlias, but we are not discussing here whethertypes.GenericAliasshould be a subtype ofTypeForm(it should not).The type
type[C]is inhabited by the Python type/class objectCand its subclasses. Example expressions that evaluate to an object of typetype[C]areCorC().__class__. Note that none of these expressions use thetype[...]syntactic form, because we are also not talking here about whethertype[C]should be a subtype ofTypeForm[type[C]](it clearly should not.)The intuitive reason for thinking that
type[C]might be a subtype ofTypeForm[C]is that the expressionCboth evaluates at runtime to the class objectC(which inhabits the typetype[C]) and is a valid spelling of the typeC. The reasontype[C]is not a subtype ofTypeForm[C]is that the expressionC().__class__also evaluates at runtime to the class objectC(which inhabits the typetype[C]) but is not a valid spelling of the typeC.Since this PR has already landed, I can put up a PR with my suggested changes to this argument.