Skip to content
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

Move some more stub author guidance from Type Stubs to Writing Stubs. #1826

Merged
merged 1 commit into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions docs/guides/writing_stubs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,46 @@ No::
DAY_FLAG: int
NIGHT_FLAG: int

Overloads
---------

All variants of overloaded functions and methods must have an ``@overload``
decorator. Do not include the implementation's final non-`@overload`-decorated
definition.

Yes::

@overload
def foo(x: str) -> str: ...
@overload
def foo(x: float) -> int: ...

No::

@overload
def foo(x: str) -> str: ...
@overload
def foo(x: float) -> int: ...
def foo(x: str | float) -> Any: ...

Decorators
----------

Include only the decorators listed :ref:`here <stub-decorators>`, whose effects
are understood by all of the major type checkers. The behavior of other
decorators should instead be incorporated into the types. For example, for the
following function::

import contextlib
@contextlib.contextmanager
def f():
yield 42

the stub definition should be::

from contextlib import AbstractContextManager
def f() -> AbstractContextManager[int]: ...

Documentation or Implementation
-------------------------------

Expand Down Expand Up @@ -581,3 +621,30 @@ No::
from typing import NamedTuple, TypedDict
Point = NamedTuple("Point", [('x', float), ('y', float)])
Thing = TypedDict("Thing", {'stuff': str, 'index': int})

Built-in Generics
-----------------

:pep:`585` built-in generics are supported and should be used instead
of the corresponding types from ``typing``::

from collections import defaultdict

def foo(t: type[MyClass]) -> list[int]: ...
x: defaultdict[int]

Using imports from ``collections.abc`` instead of ``typing`` is
generally possible and recommended::

from collections.abc import Iterable

def foo(iter: Iterable[int]) -> None: ...

Unions
------

Declaring unions with the shorthand `|` syntax is recommended and supported by
all type checkers::

def foo(x: int | str) -> int | None: ... # recommended
def foo(x: Union[int, str]) -> Optional[int]: ... # ok
59 changes: 2 additions & 57 deletions docs/reference/stubs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -165,33 +165,6 @@ specified in ``__all__`` are imported::

Type checkers support cyclic imports in stub files.

Built-in Generics
-----------------

:pep:`585` built-in generics are supported and should be used instead
of the corresponding types from ``typing``::

from collections import defaultdict

def foo(t: type[MyClass]) -> list[int]: ...
x: defaultdict[int]

Using imports from ``collections.abc`` instead of ``typing`` is
generally possible and recommended::

from collections.abc import Iterable

def foo(iter: Iterable[int]) -> None: ...

Unions
------

Declaring unions with the shorthand syntax or ``Union`` and ``Optional`` is
supported by all type checkers::

def foo(x: int | str) -> int | None: ... # recommended
def foo(x: Union[int, str]) -> Optional[int]: ... # ok

Module Level Attributes
-----------------------

Expand Down Expand Up @@ -325,23 +298,6 @@ individual type checkers how to interpret them::
def foo(): ... # compatible
def bar(): pass # behavior undefined

All variants of overloaded functions and methods must have an ``@overload``
decorator::

@overload
def foo(x: str) -> str: ...
@overload
def foo(x: float) -> int: ...

The following (which would be used in the implementation) is wrong in
type stubs::

@overload
def foo(x: str) -> str: ...
@overload
def foo(x: float) -> int: ...
def foo(x: str | float) -> Any: ...

Aliases and NewType
-------------------

Expand Down Expand Up @@ -378,6 +334,8 @@ generic class definitions.

``typing.NewType`` is also supported in stubs.

.. _stub-decorators:

Decorators
----------

Expand All @@ -391,19 +349,6 @@ fixed set of additional ones:
* ``dataclasses.dataclass``
* ``asyncio.coroutine`` (although ``async`` should be used instead)

The behavior of other decorators should instead be incorporated into the types.
For example, for the following function::

import contextlib
@contextlib.contextmanager
def f():
yield 42

the stub definition should be::

from contextlib import AbstractContextManager
def f() -> AbstractContextManager[int]: ...

Version and Platform Checks
---------------------------

Expand Down