Skip to content

Convert more examples to doctests in typing module #112194

Closed
@sobolevn

Description

@sobolevn

Feature or enhancement

There are multiple examples that are very similar to doctests, but are not doctests.
I propose adding >>> and ... to them, so these examples would be checked during tests (since now we have this feature).

There are some easy ones, where just adding >>> (and some imports are enough).
There are also some more complex ones, where some new types / vars are needed, but I don't think it is worth doing, because it will increase the complexity of these examples.

Examples:

  • cpython/Lib/typing.py

    Lines 207 to 217 in 0ee2d77

    def _should_unflatten_callable_args(typ, args):
    """Internal helper for munging collections.abc.Callable's __args__.
    The canonical representation for a Callable's __args__ flattens the
    argument types, see https://github.com/python/cpython/issues/86361.
    For example::
    assert collections.abc.Callable[[int, int], str].__args__ == (int, int, str)
    assert collections.abc.Callable[ParamSpec, str].__args__ == (ParamSpec, str)
  • cpython/Lib/typing.py

    Lines 252 to 259 in 0ee2d77

    def _collect_parameters(args):
    """Collect all type variables and parameter specifications in args
    in order of first appearance (lexicographic order).
    For example::
    assert _collect_parameters((T, Callable[P, T])) == (T, P)
    """
  • cpython/Lib/typing.py

    Lines 672 to 686 in 0ee2d77

    - Unions of unions are flattened, e.g.::
    assert Union[Union[int, str], float] == Union[int, str, float]
    - Unions of a single argument vanish, e.g.::
    assert Union[int] == int # The constructor actually returns int
    - Redundant arguments are skipped, e.g.::
    assert Union[int, str, int] == Union[int, str]
    - When comparing unions, the argument order is ignored, e.g.::
    assert Union[int, str] == Union[str, int]
  • cpython/Lib/typing.py

    Lines 2239 to 2255 in 0ee2d77

    def get_origin(tp):
    """Get the unsubscripted version of a type.
    This supports generic types, Callable, Tuple, Union, Literal, Final, ClassVar,
    Annotated, and others. Return None for unsupported types.
    Examples::
    assert get_origin(Literal[42]) is Literal
    assert get_origin(int) is None
    assert get_origin(ClassVar[int]) is ClassVar
    assert get_origin(Generic) is Generic
    assert get_origin(Generic[T]) is Generic
    assert get_origin(Union[T, int]) is Union
    assert get_origin(List[Tuple[T, T]][int]) is list
    assert get_origin(P.args) is P
    """
  • cpython/Lib/typing.py

    Lines 2268 to 2280 in 0ee2d77

    def get_args(tp):
    """Get type arguments with all substitutions performed.
    For unions, basic simplifications used by Union constructor are performed.
    Examples::
    assert get_args(Dict[str, int]) == (str, int)
    assert get_args(int) == ()
    assert get_args(Union[int, Union[T, int], str][int]) == (int, str)
    assert get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int])
    assert get_args(Callable[[], T][int]) == ([], int)
    """
  • cpython/Lib/typing.py

    Lines 2293 to 2304 in 0ee2d77

    def is_typeddict(tp):
    """Check if an annotation is a TypedDict class.
    For example::
    class Film(TypedDict):
    title: str
    year: int
    is_typeddict(Film) # => True
    is_typeddict(Union[list, str]) # => False
    """
  • cpython/Lib/typing.py

    Lines 2899 to 2909 in 0ee2d77

    Usage::
    class Point2D(TypedDict):
    x: int
    y: int
    label: str
    a: Point2D = {'x': 1, 'y': 2, 'label': 'good'} # OK
    b: Point2D = {'z': 3, 'label': 'bad'} # Fails type check
    assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first')

This actually reveals a bug:

cpython/Lib/typing.py

Lines 207 to 219 in 0ee2d77

def _should_unflatten_callable_args(typ, args):
"""Internal helper for munging collections.abc.Callable's __args__.
The canonical representation for a Callable's __args__ flattens the
argument types, see https://github.com/python/cpython/issues/86361.
For example::
assert collections.abc.Callable[[int, int], str].__args__ == (int, int, str)
assert collections.abc.Callable[ParamSpec, str].__args__ == (ParamSpec, str)
As a result, if we need to reconstruct the Callable from its __args__,
we need to unflatten it.

assert collections.abc.Callable[ParamSpec, str].__args__ == (ParamSpec, str) example is invalid:

File "/Users/sobolev/Desktop/cpython2/Lib/typing.py", line 218, in typing._should_unflatten_callable_args
Failed example:
    assert collections.abc.Callable[ParamSpec, str].__args__ == (ParamSpec, str)
Exception raised:
    Traceback (most recent call last):
      File "/Users/sobolev/Desktop/cpython2/Lib/doctest.py", line 1374, in __run
        exec(compile(example.source, filename, "single",
      File "<doctest typing._should_unflatten_callable_args[2]>", line 1, in <module>
        assert collections.abc.Callable[ParamSpec, str].__args__ == (ParamSpec, str)
               ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
      File "/Users/sobolev/Desktop/cpython2/Lib/_collections_abc.py", line 477, in __new__
        raise TypeError(f"Expected a list of types, an ellipsis, "
    TypeError: Expected a list of types, an ellipsis, ParamSpec, or Concatenate. Got <class 'typing.ParamSpec'>

Linked PRs

Metadata

Metadata

Assignees

Labels

docsDocumentation in the Doc dirtestsTests in the Lib/test dirtopic-typingtype-featureA feature request or enhancement

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions