Skip to content

Commit 8ef98cc

Browse files
JukkaLhauntsaninja
authored andcommitted
Various documentation and error message tweaks (#14574)
I looked at `git diff v0.991 master -- docs` and did some editing. There no major changes to content. Also updated one error message.
1 parent 9aa1776 commit 8ef98cc

File tree

5 files changed

+60
-41
lines changed

5 files changed

+60
-41
lines changed

docs/source/error_code_list2.rst

+27-15
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,11 @@ Example:
8585
Check that methods do not have redundant Self annotations [redundant-self]
8686
--------------------------------------------------------------------------
8787

88-
Such annotations are allowed by :pep:`673` but are redundant, so if you want
89-
warnings about them, enable this error code.
88+
If a method uses the ``Self`` type in the return type or the type of a
89+
non-self argument, there is no need to annotate the ``self`` argument
90+
explicitly. Such annotations are allowed by :pep:`673` but are
91+
redundant. If you enable this error code, mypy will generate an error if
92+
there is a redundant ``Self`` type.
9093

9194
Example:
9295

@@ -97,7 +100,7 @@ Example:
97100
from typing import Self
98101
99102
class C:
100-
# Error: Redundant Self annotation on method first argument
103+
# Error: Redundant "Self" annotation for the first method argument
101104
def copy(self: Self) -> Self:
102105
return type(self)()
103106
@@ -236,29 +239,34 @@ mypy generates an error if it thinks that an expression is redundant.
236239
Check that expression is not implicitly true in boolean context [truthy-bool]
237240
-----------------------------------------------------------------------------
238241

239-
Warn when an expression whose type does not implement ``__bool__`` or ``__len__`` is used in boolean context,
240-
since unless implemented by a sub-type, the expression will always evaluate to true.
242+
Warn when the type of an expression in a boolean context does not
243+
implement ``__bool__`` or ``__len__``. Unless one of these is
244+
implemented by a subtype, the expression will always be considered
245+
true, and there may be a bug in the condition.
246+
247+
As an exception, the ``object`` type is allowed in a boolean context.
248+
Using an iterable value in a boolean context has a separate error code
249+
(see below).
241250

242251
.. code-block:: python
243252
244253
# Use "mypy --enable-error-code truthy-bool ..."
245254
246255
class Foo:
247-
pass
256+
pass
248257
foo = Foo()
249258
# Error: "foo" has type "Foo" which does not implement __bool__ or __len__ so it could always be true in boolean context
250259
if foo:
251-
...
252-
253-
The check is similar in concept to ensuring that an expression's type implements an expected interface (e.g. ``Sized``),
254-
except that attempting to invoke an undefined method (e.g. ``__len__``) results in an error,
255-
while attempting to evaluate an object in boolean context without a concrete implementation results in a truthy value.
260+
...
256261
257262
258263
Check that iterable is not implicitly true in boolean context [truthy-iterable]
259264
-------------------------------------------------------------------------------
260265

261-
``Iterable`` does not implement ``__len__`` and so this code will be flagged:
266+
Generate an error if a value of type ``Iterable`` is used as a boolean
267+
condition, since ``Iterable`` does not implement ``__len__`` or ``__bool__``.
268+
269+
Example:
262270

263271
.. code-block:: python
264272
@@ -270,9 +278,13 @@ Check that iterable is not implicitly true in boolean context [truthy-iterable]
270278
return [42]
271279
return [x + 1 for x in items]
272280
273-
If called with a ``Generator`` like ``int(x) for x in []``, this function would not return ``[42]`` unlike
274-
what the author might have intended. Of course it's possible that ``transform`` is only passed ``list`` objects,
275-
and so there is no error in practice. In such case, it is recommended to annotate ``items: Collection[int]``.
281+
If ``transform`` is called with a ``Generator`` argument, such as
282+
``int(x) for x in []``, this function would not return ``[42]`` unlike
283+
what might be intended. Of course, it's possible that ``transform`` is
284+
only called with ``list`` or other container objects, and the ``if not
285+
items`` check is actually valid. If that is the case, it is
286+
recommended to annotate ``items`` as ``Collection[int]`` instead of
287+
``Iterable[int]``.
276288

277289

278290
.. _ignore-without-code:

docs/source/generics.rst

+29-22
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,11 @@ Generic methods and generic self
193193
********************************
194194

195195
You can also define generic methods — just use a type variable in the
196-
method signature that is different from class type variables. In particular,
197-
``self`` may also be generic, allowing a method to return the most precise
198-
type known at the point of access. In this way, for example, you can typecheck
199-
chaining of setter methods:
196+
method signature that is different from class type variables. In
197+
particular, the ``self`` argument may also be generic, allowing a
198+
method to return the most precise type known at the point of access.
199+
In this way, for example, you can type check a chain of setter
200+
methods:
200201

201202
.. code-block:: python
202203
@@ -222,7 +223,9 @@ chaining of setter methods:
222223
circle: Circle = Circle().set_scale(0.5).set_radius(2.7)
223224
square: Square = Square().set_scale(0.5).set_width(3.2)
224225
225-
Without using generic ``self``, the last two lines could not be type-checked properly.
226+
Without using generic ``self``, the last two lines could not be type
227+
checked properly, since the return type of ``set_scale`` would be
228+
``Shape``, which doesn't define ``set_radius`` or ``set_width``.
226229

227230
Other uses are factory methods, such as copy and deserialization.
228231
For class methods, you can also define generic ``cls``, using :py:class:`Type[T] <typing.Type>`:
@@ -255,16 +258,18 @@ In the latter case, you must implement this method in all future subclasses.
255258
Note also that mypy cannot always verify that the implementation of a copy
256259
or a deserialization method returns the actual type of self. Therefore
257260
you may need to silence mypy inside these methods (but not at the call site),
258-
possibly by making use of the ``Any`` type.
261+
possibly by making use of the ``Any`` type or a ``# type: ignore`` comment.
259262

260-
Note that this feature may accept some unsafe code for the purpose of
261-
*practicality*. For example:
263+
Note that mypy lets you use generic self types in certain unsafe ways
264+
in order to support common idioms. For example, using a generic
265+
self type in an argument type is accepted even though it's unsafe:
262266

263267
.. code-block:: python
264268
265269
from typing import TypeVar
266270
267271
T = TypeVar("T")
272+
268273
class Base:
269274
def compare(self: T, other: T) -> bool:
270275
return False
@@ -273,25 +278,27 @@ Note that this feature may accept some unsafe code for the purpose of
273278
def __init__(self, x: int) -> None:
274279
self.x = x
275280
276-
# This is unsafe (see below), but allowed because it is
277-
# a common pattern, and rarely causes issues in practice.
281+
# This is unsafe (see below) but allowed because it's
282+
# a common pattern and rarely causes issues in practice.
278283
def compare(self, other: Sub) -> bool:
279284
return self.x > other.x
280285
281286
b: Base = Sub(42)
282287
b.compare(Base()) # Runtime error here: 'Base' object has no attribute 'x'
283288
284-
For some advanced uses of self-types see :ref:`additional examples <advanced_self>`.
289+
For some advanced uses of self types, see :ref:`additional examples <advanced_self>`.
285290

286291
Automatic self types using typing.Self
287292
**************************************
288293

289-
The patterns described above are quite common, so there is a syntactic sugar
290-
for them introduced in :pep:`673`. Instead of defining a type variable and
291-
using an explicit ``self`` annotation, you can import a magic type ``typing.Self``
292-
that is automatically transformed into a type variable with an upper bound of
293-
current class, and you don't need an annotation for ``self`` (or ``cls`` for
294-
class methods). The above example can thus be rewritten as:
294+
Since the patterns described above are quite common, mypy supports a
295+
simpler syntax, introduced in :pep:`673`, to make them easier to use.
296+
Instead of defining a type variable and using an explicit annotation
297+
for ``self``, you can import the special type ``typing.Self`` that is
298+
automatically transformed into a type variable with the current class
299+
as the upper bound, and you don't need an annotation for ``self`` (or
300+
``cls`` in class methods). The example from the previous section can
301+
be made simpler by using ``Self``:
295302

296303
.. code-block:: python
297304
@@ -312,13 +319,13 @@ class methods). The above example can thus be rewritten as:
312319
313320
a, b = SuperFriend.make_pair()
314321
315-
This is more compact than using explicit type variables, plus additionally
316-
you can use ``Self`` in attribute annotations, not just in methods.
322+
This is more compact than using explicit type variables. Also, you can
323+
use ``Self`` in attribute annotations in addition to methods.
317324

318325
.. note::
319326

320-
To use this feature on versions of Python before 3.11, you will need to
321-
import ``Self`` from ``typing_extensions`` version 4.0 or newer.
327+
To use this feature on Python versions earlier than 3.11, you will need to
328+
import ``Self`` from ``typing_extensions`` (version 4.0 or newer).
322329

323330
.. _variance-of-generics:
324331

@@ -911,7 +918,7 @@ defeating the purpose of using aliases. Example:
911918
912919
OIntVec = Optional[Vec[int]]
913920
914-
Using type variable bounds or values in generic aliases, has the same effect
921+
Using type variable bounds or values in generic aliases has the same effect
915922
as in generic classes/functions.
916923

917924

docs/source/index.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ understand, debug, and maintain.
3939

4040
.. note::
4141

42-
Although mypy is production ready, there will be occasional changes
42+
Although mypy is production ready, there may be occasional changes
4343
that break backward compatibility. The mypy development team tries to
4444
minimize the impact of changes to user code. In case of a major breaking
4545
change, mypy's major version will be bumped.

mypy/semanal.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -972,7 +972,7 @@ def prepare_method_signature(self, func: FuncDef, info: TypeInfo, has_self_type:
972972
# This error is off by default, since it is explicitly allowed
973973
# by the PEP 673.
974974
self.fail(
975-
"Redundant Self annotation on method first argument",
975+
'Redundant "Self" annotation for the first method argument',
976976
func,
977977
code=codes.REDUNDANT_SELF_TYPE,
978978
)

test-data/unit/check-selftype.test

+2-2
Original file line numberDiff line numberDiff line change
@@ -1627,13 +1627,13 @@ class C:
16271627
from typing import Self, Type
16281628

16291629
class C:
1630-
def copy(self: Self) -> Self: # E: Redundant Self annotation on method first argument
1630+
def copy(self: Self) -> Self: # E: Redundant "Self" annotation for the first method argument
16311631
d: Defer
16321632
class Defer: ...
16331633
return self
16341634

16351635
@classmethod
1636-
def g(cls: Type[Self]) -> Self: # E: Redundant Self annotation on method first argument
1636+
def g(cls: Type[Self]) -> Self: # E: Redundant "Self" annotation for the first method argument
16371637
d: DeferAgain
16381638
class DeferAgain: ...
16391639
return cls()

0 commit comments

Comments
 (0)