@@ -315,6 +315,53 @@ inferred by mypy. This is not valid:
315315 If you really need this, you can define a generic class with a ``__call__ ``
316316method.
317317
318+ .. _type-variable-upper-bound :
319+
320+ Type variables with upper bounds
321+ ********************************
322+
323+ A type variable can also be restricted to having values that are
324+ subtypes of a specific type. This type is called the upper bound of
325+ the type variable, and it is specified using ``T: <bound> `` when using the
326+ Python 3.12 syntax. In the definition of a generic function or a generic
327+ class that uses such a type variable ``T ``, the type represented by ``T ``
328+ is assumed to be a subtype of its upper bound, so you can use methods
329+ of the upper bound on values of type ``T `` (Python 3.12 syntax):
330+
331+ .. code-block :: python
332+
333+ from typing import SupportsAbs
334+
335+ def max_by_abs[T: SupportsAbs[float ]](* xs: T) -> T:
336+ # We can use abs(), because T is a subtype of SupportsAbs[float].
337+ return max (xs, key = abs )
338+
339+ An upper bound can also be specified with the ``bound=... `` keyword
340+ argument to :py:class: `~typing.TypeVar `.
341+ Here is the example using the legacy syntax (Python 3.11 and earlier):
342+
343+ .. code-block :: python
344+
345+ from typing import TypeVar, SupportsAbs
346+
347+ T = TypeVar(' T' , bound = SupportsAbs[float ])
348+
349+ def max_by_abs (* xs : T) -> T:
350+ return max (xs, key = abs )
351+
352+ In a call to such a function, the type ``T `` must be replaced by a
353+ type that is a subtype of its upper bound. Continuing the example
354+ above:
355+
356+ .. code-block :: python
357+
358+ max_by_abs(- 3.5 , 2 ) # Okay, has type 'float'
359+ max_by_abs(5 + 6j , 7 ) # Okay, has type 'complex'
360+ max_by_abs(' a' , ' b' ) # Error: 'str' is not a subtype of SupportsAbs[float]
361+
362+ Type parameters of generic classes may also have upper bounds, which
363+ restrict the valid values for the type parameter in the same way.
364+
318365.. _generic-methods-and-generic-self :
319366
320367Generic methods and generic self
@@ -400,8 +447,7 @@ or :py:class:`Type[T] <typing.Type>` (Python 3.12 syntax):
400447
401448 a, b = SuperFriend.make_pair()
402449
403- Here is the same example using the legacy syntax (3.11 and earlier, though
404- 3.9 and later can use lower-case ``type[T] ``):
450+ Here is the same example using the legacy syntax (3.11 and earlier):
405451
406452.. code-block :: python
407453
@@ -433,7 +479,7 @@ or a deserialization method returns the actual type of self. Therefore
433479you may need to silence mypy inside these methods (but not at the call site),
434480possibly by making use of the ``Any `` type or a ``# type: ignore `` comment.
435481
436- Note that mypy lets you use generic self types in certain unsafe ways
482+ Mypy lets you use generic self types in certain unsafe ways
437483in order to support common idioms. For example, using a generic
438484self type in an argument type is accepted even though it's unsafe (Python 3.12
439485syntax):
@@ -647,59 +693,13 @@ contravariant, use type variables defined with special keyword arguments
647693 my_box = Box(Square())
648694 look_into(my_box) # OK, but mypy would complain here for an invariant type
649695
650- .. _type-variable-upper-bound :
651-
652- Type variables with upper bounds
653- ********************************
654-
655- A type variable can also be restricted to having values that are
656- subtypes of a specific type. This type is called the upper bound of
657- the type variable, and it is specified using ``T: <bound> `` when using the
658- Python 3.12 syntax. In the definition of a generic function that uses
659- such a type variable ``T ``, the type represented by ``T `` is assumed
660- to be a subtype of its upper bound, so the function can use methods
661- of the upper bound on values of type ``T `` (Python 3.12 syntax):
662-
663- .. code-block :: python
664-
665- from typing import SupportsAbs
666-
667- def max_by_abs[T: SupportsAbs[float ]](* xs: T) -> T:
668- # Okay, because T is a subtype of SupportsAbs[float].
669- return max (xs, key = abs )
670-
671- An upper bound can also be specified with the ``bound=... `` keyword
672- argument to :py:class: `~typing.TypeVar `.
673- Here is the example using the legacy syntax (Python 3.11 and earlier):
674-
675- .. code-block :: python
676-
677- from typing import TypeVar, SupportsAbs
678-
679- T = TypeVar(' T' , bound = SupportsAbs[float ])
680-
681- def max_by_abs (* xs : T) -> T:
682- return max (xs, key = abs )
683-
684- In a call to such a function, the type ``T `` must be replaced by a
685- type that is a subtype of its upper bound. Continuing the example
686- above:
687-
688- .. code-block :: python
689-
690- max_by_abs(- 3.5 , 2 ) # Okay, has type float.
691- max_by_abs(5 + 6j , 7 ) # Okay, has type complex.
692- max_by_abs(' a' , ' b' ) # Error: 'str' is not a subtype of SupportsAbs[float].
693-
694- Type parameters of generic classes may also have upper bounds, which
695- restrict the valid values for the type parameter in the same way.
696-
697696 .. _type-variable-value-restriction :
698697
699698Type variables with value restriction
700699*************************************
701700
702- By default, a type variable can be replaced with any type. However, sometimes
701+ By default, a type variable can be replaced with any type -- or any type that
702+ is a subtype of the upper bound, which defaults to ``object ``. However, sometimes
703703it's useful to have a type variable that can only have some specific types
704704as its value. A typical example is a type variable that can only have values
705705``str `` and ``bytes ``. This lets us define a function that can concatenate
@@ -758,11 +758,10 @@ You may expect that the type of ``ss`` is ``S``, but the type is
758758actually ``str ``: a subtype gets promoted to one of the valid values
759759for the type variable, which in this case is ``str ``.
760760
761- This is thus
762- subtly different from *bounded quantification * in languages such as
763- Java, where the return type would be ``S ``. The way mypy implements
764- this is correct for ``concat ``, since ``concat `` actually returns a
765- ``str `` instance in the above example:
761+ This is thus subtly different from using ``str | bytes `` as an upper bound,
762+ where the return type would be ``S `` (see :ref: `type-variable-upper-bound `).
763+ Using a value restriction is correct for ``concat ``, since ``concat ``
764+ actually returns a ``str `` instance in the above example:
766765
767766.. code-block :: python
768767
@@ -776,8 +775,7 @@ value of :py:func:`re.compile`, where ``S`` can be either ``str``
776775or ``bytes ``. Regular expressions can be based on a string or a
777776bytes pattern.
778777
779- A type variable may not have both a value restriction and an upper bound
780- (see :ref: `type-variable-upper-bound `).
778+ A type variable may not have both a value restriction and an upper bound.
781779
782780Note that you may come across :py:data: `~typing.AnyStr ` imported from
783781:py:mod: `typing `. This feature is now deprecated, but it means the same
0 commit comments