PEP 728: Address Review Feedback (#3697)
This commit is contained in:
parent
a8cc9106bc
commit
221d07cb9b
|
@ -252,7 +252,11 @@ be rejected by the type checker.
|
||||||
__extra_items__: str # A regular key
|
__extra_items__: str # A regular key
|
||||||
|
|
||||||
a: Movie = {"name": "Blade Runner", "__extra_items__": None} # Not OK. 'None' is incompatible with 'str'
|
a: Movie = {"name": "Blade Runner", "__extra_items__": None} # Not OK. 'None' is incompatible with 'str'
|
||||||
b: Movie = {"name": "Blade Runner", "other_extra_key": None} # OK
|
b: Movie = {
|
||||||
|
"name": "Blade Runner",
|
||||||
|
"__extra_items__": "A required regular key",
|
||||||
|
"other_extra_key": None,
|
||||||
|
} # OK
|
||||||
|
|
||||||
Here, ``"__extra_items__"`` in ``a`` is a regular key defined on ``Movie`` where
|
Here, ``"__extra_items__"`` in ``a`` is a regular key defined on ``Movie`` where
|
||||||
its value type is narrowed from ``ReadOnly[str | None]`` to ``str``,
|
its value type is narrowed from ``ReadOnly[str | None]`` to ``str``,
|
||||||
|
@ -530,6 +534,40 @@ between this type and a closed TypedDict type::
|
||||||
extra_int = not_closed # Not OK. 'ReadOnly[object]' implicitly on 'MovieNotClosed' is not consistent with 'int' for item '__extra_items__'
|
extra_int = not_closed # Not OK. 'ReadOnly[object]' implicitly on 'MovieNotClosed' is not consistent with 'int' for item '__extra_items__'
|
||||||
not_closed = extra_int # OK
|
not_closed = extra_int # OK
|
||||||
|
|
||||||
|
Interaction with Constructors
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
TypedDicts that allow extra items of type ``T`` also allow arbitrary keyword
|
||||||
|
arguments of this type when constructed by calling the class object::
|
||||||
|
|
||||||
|
class OpenMovie(TypedDict):
|
||||||
|
name: str
|
||||||
|
|
||||||
|
OpenMovie(name="No Country for Old Men") # OK
|
||||||
|
OpenMovie(name="No Country for Old Men", year=2007) # Not OK. Unrecognized key
|
||||||
|
|
||||||
|
class ExtraMovie(TypedDict, closed=True):
|
||||||
|
name: str
|
||||||
|
__extra_items__: int
|
||||||
|
|
||||||
|
ExtraMovie(name="No Country for Old Men") # OK
|
||||||
|
ExtraMovie(name="No Country for Old Men", year=2007) # OK
|
||||||
|
ExtraMovie(
|
||||||
|
name="No Country for Old Men",
|
||||||
|
language="English",
|
||||||
|
) # Not OK. Wrong type for extra key
|
||||||
|
|
||||||
|
# This implies '__extra_items__: Never',
|
||||||
|
# so extra keyword arguments produce an error
|
||||||
|
class ClosedMovie(TypedDict, closed=True):
|
||||||
|
name: str
|
||||||
|
|
||||||
|
ClosedMovie(name="No Country for Old Men") # OK
|
||||||
|
ClosedMovie(
|
||||||
|
name="No Country for Old Men",
|
||||||
|
year=2007,
|
||||||
|
) # Not OK. Extra items not allowed
|
||||||
|
|
||||||
Interaction with Mapping[KT, VT]
|
Interaction with Mapping[KT, VT]
|
||||||
--------------------------------
|
--------------------------------
|
||||||
|
|
||||||
|
@ -571,14 +609,17 @@ prohibits additional required keys in its structural subtypes, we can determine
|
||||||
if the TypedDict type and its structural subtypes will ever have any required
|
if the TypedDict type and its structural subtypes will ever have any required
|
||||||
key during static analysis.
|
key during static analysis.
|
||||||
|
|
||||||
If there is no required key, the TypedDict type is consistent with ``dict[KT,
|
The TypedDict type is consistent with ``dict[str, VT]`` if all items on the
|
||||||
VT]`` and vice versa if all items on the TypedDict type satisfy the following
|
TypedDict type satisfy the following conditions:
|
||||||
conditions:
|
|
||||||
|
|
||||||
- ``VT`` is consistent with the value type of the item
|
- ``VT`` is consistent with the value type of the item
|
||||||
|
|
||||||
- The value type of the item is consistent with ``VT``
|
- The value type of the item is consistent with ``VT``
|
||||||
|
|
||||||
|
- The item is not read-only.
|
||||||
|
|
||||||
|
- The item is not required.
|
||||||
|
|
||||||
For example::
|
For example::
|
||||||
|
|
||||||
class IntDict(TypedDict, closed=True):
|
class IntDict(TypedDict, closed=True):
|
||||||
|
@ -601,6 +642,15 @@ In this case, methods that are previously unavailable on a TypedDict are allowed
|
||||||
|
|
||||||
reveal_type(not_required_num.popitem()) # OK. Revealed type is tuple[str, int]
|
reveal_type(not_required_num.popitem()) # OK. Revealed type is tuple[str, int]
|
||||||
|
|
||||||
|
However, ``dict[str, VT]`` is not necessarily consistent with a TypedDict type,
|
||||||
|
because such dict can be a subtype of dict::
|
||||||
|
|
||||||
|
class CustomDict(dict[str, int]):
|
||||||
|
...
|
||||||
|
|
||||||
|
not_a_regular_dict: CustomDict = {"num": 1}
|
||||||
|
int_dict: IntDict = not_a_regular_dict # Not OK
|
||||||
|
|
||||||
How to Teach this
|
How to Teach this
|
||||||
=================
|
=================
|
||||||
|
|
||||||
|
@ -652,8 +702,8 @@ Supporting ``TypedDict(extra=type)``
|
||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
||||||
While this design is potentially viable, there are several partially addressable
|
While this design is potentially viable, there are several partially addressable
|
||||||
concerns to consider. Adding everything up, it is slightly less favorable than
|
concerns to consider. The author of this PEP thinks that it is slightly less
|
||||||
the current proposal.
|
favorable than the current proposal.
|
||||||
|
|
||||||
- Usability of forward reference
|
- Usability of forward reference
|
||||||
As in the functional syntax, using a quoted type or a type alias will be
|
As in the functional syntax, using a quoted type or a type alias will be
|
||||||
|
|
Loading…
Reference in New Issue