Skip to content

Commit 2f6b9f1

Browse files
committed
PEP 827: Produce errors for invalid type operations
Currently the PEP calls for returning `Never`.
1 parent 454541c commit 2f6b9f1

1 file changed

Lines changed: 25 additions & 14 deletions

File tree

peps/pep-0827.rst

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,7 @@ which produce aliases that have some dunder methods overloaded for
588588
Many of the operators specified have type bounds listed for some of
589589
their operands. These should be interpreted more as documentation than
590590
as exact type bounds. Trying to evaluate operators with invalid
591-
arguments will produce ``Never`` as the return. (There is some
591+
arguments will produce an error. (There is some
592592
discussion of potential alternatives :ref:`below <pep827-strict-kinds>`.)
593593

594594
Note that in some of these bounds below we write things like
@@ -622,10 +622,11 @@ Basic operators
622622
'''''''''''''''
623623

624624
* ``GetArg[T, Base, Idx: Literal[int]]``: returns the type argument
625-
number ``Idx`` to ``T`` when interpreted as ``Base``, or ``Never``
626-
if it cannot be. (That is, if we have ``class A(B[C]): ...``, then
625+
number ``Idx`` to ``T`` when interpreted as ``Base``, or generates a type
626+
error if it cannot be or if the index is invalid.
627+
(That is, if we have ``class A(B[C]): ...``, then
627628
``GetArg[A, B, Literal[0]] == C``
628-
while ``GetArg[A, A, Literal[0]] == Never``).
629+
while ``GetArg[A, A, Literal[0]]`` is a type error).
629630

630631
Negative indexes work in the usual way.
631632

@@ -640,7 +641,7 @@ Basic operators
640641
``Param`` types.
641642

642643
* ``GetArgs[T, Base]``: returns a tuple containing all of the type
643-
arguments of ``T`` when interpreted as ``Base``, or ``Never`` if it
644+
arguments of ``T`` when interpreted as ``Base``, or an error if it
644645
cannot be.
645646

646647
* ``Length[T: tuple]`` - Gets the length of a tuple as an int literal
@@ -688,7 +689,7 @@ Object inspection
688689
methods).
689690

690691
* ``GetMember[T, S: Literal[str]]``: Produces a ``Member`` type for the
691-
member named ``S`` from the class ``T``, or ``Never`` if it does not exist.
692+
member named ``S`` from the class ``T``, or an error if it does not exist.
692693

693694
* ``GetMemberType[T, S: Literal[str]]``: Extract the type of the
694695
member named ``S`` from the class ``T``, or ``Never`` if it does not exist.
@@ -1784,18 +1785,30 @@ This proposal is less "strictly-typed" than TypeScript
17841785

17851786
TypeScript has better typechecking at the alias definition site:
17861787
For ``P[K]``, ``K`` needs to have ``keyof P``. The ``extends``
1787-
conditional type operator narrows the type to help spuport this.
1788+
conditional type operator narrows the type to help support this.
1789+
1790+
It's not possible to define a type alias in TypeScript that fails at
1791+
expansion time, but it *is* possible to do so in this system.
17881792

1789-
We could do potentially better but it would require quite a bit more
1790-
machinery.
1793+
We could potentially also make this impossible but it would require
1794+
quite a bit more machinery.
17911795

17921796
* ``KeyOf[T]`` - literal keys of ``T``
17931797
* ``Member[T]``, when statically checking a type alias, could be
17941798
treated as having some type like ``tuple[Member[KeyOf[T], object,
17951799
str, ..., ...], ...]``
1796-
* ``GetMemberType[T, S: KeyOf[T]]`` - but this isn't supported yet.
1797-
TypeScript supports it.
1798-
* We would also need to do context sensitive type bound inference
1800+
* ``GetMemberType[T, S: KeyOf[T]]`` - Make ``GetMember`` have a bound
1801+
requiring the index be a key... but this kind of dependent bound
1802+
isn't supported currently. (TypeScript supports it.)
1803+
* We would also need to do context sensitive type bound
1804+
inference. This is subtle but obviously this sort of thing is done
1805+
at term level.
1806+
1807+
We think that this isn't worth the complexity, and is also not even
1808+
obviously better. TypeScript commonly requires doing many conditionals where
1809+
often it is always intended that they take the true branch--typically
1810+
the false branch returns ``never``, and these can be quite difficult
1811+
to track down.
17991812

18001813

18011814
Potential Future Extensions
@@ -1886,8 +1899,6 @@ simulated in other ways.
18861899
Open Issues
18871900
===========
18881901

1889-
* What invalid operations should be errors and what should return ``Never``?
1890-
18911902
* :ref:`Unpack of typevars for **kwargs <pep827-unpack-kwargs>`: Should
18921903
whether we try to infer literal types for extra arguments be
18931904
configurable in the ``TypedDict`` serving as the bound somehow? If

0 commit comments

Comments
 (0)