Skip to content

Commit a1b4e32

Browse files
authored
Document how evil --no-strict-optional is (#16731)
On multiple occasions, I've encountered folks using this, running into issues and then being perplexed when they figure out what `--no-strict-optional` actually does. Most recently in #16718 (comment) This is a non-standard, dangerous option that should not be used in modern typed Python. It's been five and a half years since it was the default behaviour in mypy, so we should deemphasise and warn about its existence.
1 parent f9e8e0b commit a1b4e32

File tree

4 files changed

+17
-78
lines changed

4 files changed

+17
-78
lines changed

docs/source/command_line.rst

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,6 @@ None and Optional handling
415415
**************************
416416

417417
The following flags adjust how mypy handles values of type ``None``.
418-
For more details, see :ref:`no_strict_optional`.
419418

420419
.. _implicit-optional:
421420

@@ -435,16 +434,19 @@ For more details, see :ref:`no_strict_optional`.
435434
436435
**Note:** This was disabled by default starting in mypy 0.980.
437436

437+
.. _no_strict_optional:
438+
438439
.. option:: --no-strict-optional
439440

440-
This flag disables strict checking of :py:data:`~typing.Optional`
441+
This flag effectively disables checking of :py:data:`~typing.Optional`
441442
types and ``None`` values. With this option, mypy doesn't
442-
generally check the use of ``None`` values -- they are valid
443-
everywhere. See :ref:`no_strict_optional` for more about this feature.
443+
generally check the use of ``None`` values -- it is treated
444+
as compatible with every type.
445+
446+
.. warning::
444447

445-
**Note:** Strict optional checking was enabled by default starting in
446-
mypy 0.600, and in previous versions it had to be explicitly enabled
447-
using ``--strict-optional`` (which is still accepted).
448+
``--no-strict-optional`` is evil. Avoid using it and definitely do
449+
not use it without understanding what it does.
448450

449451

450452
.. _configuring-warnings:

docs/source/common_issues.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ and mypy doesn't complain**.
119119
return None # No error!
120120
121121
You may have disabled strict optional checking (see
122-
:ref:`no_strict_optional` for more).
122+
:ref:`--no-strict-optional <no_strict_optional>` for more).
123123

124124
.. _silencing_checker:
125125

docs/source/config_file.rst

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -580,10 +580,15 @@ section of the command line docs.
580580
:type: boolean
581581
:default: True
582582

583-
Enables or disables strict Optional checks. If False, mypy treats ``None``
583+
Effectively disables checking of :py:data:`~typing.Optional`
584+
types and ``None`` values. With this option, mypy doesn't
585+
generally check the use of ``None`` values -- it is treated
584586
as compatible with every type.
585587

586-
**Note:** This was False by default in mypy versions earlier than 0.600.
588+
.. warning::
589+
590+
``strict_optional = false`` is evil. Avoid using it and definitely do
591+
not use it without understanding what it does.
587592

588593

589594
Configuring warnings

docs/source/kinds_of_types.rst

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -429,74 +429,6 @@ the runtime with some limitations (see :ref:`runtime_troubles`).
429429
430430
t2: int | None # equivalent to Optional[int]
431431
432-
.. _no_strict_optional:
433-
434-
Disabling strict optional checking
435-
**********************************
436-
437-
Mypy also has an option to treat ``None`` as a valid value for every
438-
type (in case you know Java, it's useful to think of it as similar to
439-
the Java ``null``). In this mode ``None`` is also valid for primitive
440-
types such as ``int`` and ``float``, and :py:data:`~typing.Optional` types are
441-
not required.
442-
443-
The mode is enabled through the :option:`--no-strict-optional <mypy --no-strict-optional>` command-line
444-
option. In mypy versions before 0.600 this was the default mode. You
445-
can enable this option explicitly for backward compatibility with
446-
earlier mypy versions, in case you don't want to introduce optional
447-
types to your codebase yet.
448-
449-
It will cause mypy to silently accept some buggy code, such as
450-
this example -- it's not recommended if you can avoid it:
451-
452-
.. code-block:: python
453-
454-
def inc(x: int) -> int:
455-
return x + 1
456-
457-
x = inc(None) # No error reported by mypy if strict optional mode disabled!
458-
459-
However, making code "optional clean" can take some work! You can also use
460-
:ref:`the mypy configuration file <config-file>` to migrate your code
461-
to strict optional checking one file at a time, since there exists
462-
the per-module flag
463-
:confval:`strict_optional` to control strict optional mode.
464-
465-
Often it's still useful to document whether a variable can be
466-
``None``. For example, this function accepts a ``None`` argument,
467-
but it's not obvious from its signature:
468-
469-
.. code-block:: python
470-
471-
def greeting(name: str) -> str:
472-
if name:
473-
return f'Hello, {name}'
474-
else:
475-
return 'Hello, stranger'
476-
477-
print(greeting('Python')) # Okay!
478-
print(greeting(None)) # Also okay!
479-
480-
You can still use :py:data:`Optional[t] <typing.Optional>` to document that ``None`` is a
481-
valid argument type, even if strict ``None`` checking is not
482-
enabled:
483-
484-
.. code-block:: python
485-
486-
from typing import Optional
487-
488-
def greeting(name: Optional[str]) -> str:
489-
if name:
490-
return f'Hello, {name}'
491-
else:
492-
return 'Hello, stranger'
493-
494-
Mypy treats this as semantically equivalent to the previous example
495-
if strict optional checking is disabled, since ``None`` is implicitly
496-
valid for any type, but it's much more
497-
useful for a programmer who is reading the code. This also makes
498-
it easier to migrate to strict ``None`` checking in the future.
499-
500432
.. _type-aliases:
501433

502434
Type aliases

0 commit comments

Comments
 (0)