Skip to content

Commit

Permalink
Move some more stub author guidance from Type Stubs to Writing Stubs. (
Browse files Browse the repository at this point in the history
…#1826)

See #1815 for context.
  • Loading branch information
rchen152 authored Aug 1, 2024
1 parent 9648576 commit 947f9e6
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 57 deletions.
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

0 comments on commit 947f9e6

Please sign in to comment.