Skip to content

Commit 0cc549e

Browse files
committed
format and fix link
1 parent 076d101 commit 0cc549e

File tree

1 file changed

+37
-33
lines changed

1 file changed

+37
-33
lines changed

docs/guides/writing_stubs.rst

Lines changed: 37 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -215,15 +215,15 @@ Incomplete Stubs
215215

216216
When writing new stubs, it is not necessary to fully annotate all arguments,
217217
return types, and fields. Some items may be left unannotated or
218-
annotated with `_typeshed.Incomplete` (`documentation <https://github.com/python/typeshed/blob/main/stdlib/_typeshed/README.md>`_).::
218+
annotated with ``_typeshed.Incomplete`` (`documentation <https://github.com/python/typeshed/blob/main/stdlib/_typeshed/README.md>`_)::
219219

220220
from _typeshed import Incomplete
221221

222222
field: Incomplete # unannotated
223223

224224
def foo(x): ... # unannotated argument and return type
225225

226-
`Incomplete` can also be used for partially known types::
226+
``_typeshed.Incomplete`` can also be used for partially known types::
227227

228228
def foo(x: Incomplete | None = None) -> list[Incomplete]: ...
229229

@@ -267,39 +267,16 @@ annotated function ``bar()``::
267267

268268
def bar(x: str, y, *, z=...): ...
269269

270-
`Any` vs. `Incomplete`
271-
----------------------
270+
``Any`` vs. ``Incomplete``
271+
--------------------------
272272

273-
While `Incomplete` is a type alias of `Any`, they serve difference purposes:
274-
`Incomplete` is a placeholder where a proper type might be substituted.
275-
It's a "to do" item and should be replaced if possible. `Any` is used when
276-
it's not possible to accurately type an item using the current type system.
277-
It should be used sparingly.
273+
While ``Incomplete`` is a type alias of ``Any``, they serve difference purposes:
274+
``Incomplete`` is a placeholder where a proper type might be substituted.
275+
It's a "to do" item and should be replaced if possible.
278276

279-
The `Any` trick
280-
---------------
281-
282-
In cases where a function or method can return `None`, but where forcing the
283-
user to explicitly check for `None` can be detrimental, use
284-
`_typeshed.MaybeNone` (an alias to `Any`), instead of `None`.
285-
286-
Consider the following (simplified) signature of `re.Match[str].group`::
287-
288-
class Match:
289-
def group(self, group: str | int, /) -> str | MaybeNone: ...
290-
291-
This avoid forcing the user to check for `None`::
292-
293-
match = re.fullmatch(r"\d+_(.*)", some_string)
294-
assert match is not None
295-
name_group = match.group(1) # The user knows that this will never be None
296-
return name_group.uper() # This typo will be flagged by the type checker
297-
298-
In this case, the user of `match.group()` must be prepared to handle a `str`,
299-
but type checkers are happy with `if name_group is None` checks, because we're
300-
saying it can also be something else than an `str`.
301-
302-
This is sometimes called "the Any trick".
277+
``Any`` is used when it's not possible to accurately type an item using the current
278+
type system. It should be used sparingly, as described in the :ref:`using-any`
279+
section of the style guide.
303280

304281
Attribute Access
305282
----------------
@@ -799,6 +776,8 @@ all type checkers::
799776
def foo(x: int | str) -> int | None: ... # recommended
800777
def foo(x: Union[int, str]) -> Optional[int]: ... # ok
801778

779+
.. _using-any:
780+
802781
Using `Any` and `object`
803782
------------------------
804783

@@ -814,6 +793,31 @@ that some function can accept literally anything: in those cases use
814793
When using `Any`, document the reason for using it in a comment. Ideally,
815794
document what types could be used.
816795

796+
The `Any` Trick
797+
-----------------
798+
799+
In cases where a function or method can return ``None``, but where forcing the
800+
user to explicitly check for ``None`` can be detrimental, use
801+
``_typeshed.MaybeNone`` (an alias to ``Any``), instead of ``None``.
802+
803+
Consider the following (simplified) signature of ``re.Match[str].group``::
804+
805+
class Match:
806+
def group(self, group: str | int, /) -> str | MaybeNone: ...
807+
808+
This avoid forcing the user to check for ``None``::
809+
810+
match = re.fullmatch(r"\d+_(.*)", some_string)
811+
assert match is not None
812+
name_group = match.group(1) # The user knows that this will never be None
813+
return name_group.uper() # This typo will be flagged by the type checker
814+
815+
In this case, the user of ``match.group()`` must be prepared to handle a ``str``,
816+
but type checkers are happy with ``if name_group is None`` checks, because we're
817+
saying it can also be something else than an ``str``.
818+
819+
This is sometimes called "the Any trick".
820+
817821
Context Managers
818822
----------------
819823

0 commit comments

Comments
 (0)