Skip to content

Commit 027c58a

Browse files
authored
Use --no-implicit-optional by default (#13401)
Fixes #9091 This brings us in line with the PEP 484 updates in 2018
1 parent ab3b98f commit 027c58a

16 files changed

+44
-44
lines changed

docs/source/command_line.rst

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -390,29 +390,23 @@ None and Optional handling
390390
The following flags adjust how mypy handles values of type ``None``.
391391
For more details, see :ref:`no_strict_optional`.
392392

393-
.. _no-implicit-optional:
393+
.. _implicit-optional:
394394

395-
.. option:: --no-implicit-optional
395+
.. option:: --implicit-optional
396396

397-
This flag causes mypy to stop treating arguments with a ``None``
397+
This flag causes mypy to treat arguments with a ``None``
398398
default value as having an implicit :py:data:`~typing.Optional` type.
399399

400-
For example, by default mypy will assume that the ``x`` parameter
401-
is of type ``Optional[int]`` in the code snippet below since
402-
the default parameter is ``None``:
400+
For example, if this flag is set, mypy would assume that the ``x``
401+
parameter is actually of type ``Optional[int]`` in the code snippet below
402+
since the default parameter is ``None``:
403403

404404
.. code-block:: python
405405
406406
def foo(x: int = None) -> None:
407407
print(x)
408408
409-
If this flag is set, the above snippet will no longer type check:
410-
we must now explicitly indicate that the type is ``Optional[int]``:
411-
412-
.. code-block:: python
413-
414-
def foo(x: Optional[int] = None) -> None:
415-
print(x)
409+
**Note:** This was disabled by default starting in mypy 0.980.
416410

417411
.. option:: --no-strict-optional
418412

docs/source/config_file.rst

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -503,13 +503,15 @@ None and Optional handling
503503
For more information, see the :ref:`None and Optional handling <none-and-optional-handling>`
504504
section of the command line docs.
505505

506-
.. confval:: no_implicit_optional
506+
.. confval:: implicit_optional
507507

508508
:type: boolean
509509
:default: False
510510

511-
Changes the treatment of arguments with a default value of ``None`` by not implicitly
512-
making their type :py:data:`~typing.Optional`.
511+
Causes mypy to treat arguments with a ``None``
512+
default value as having an implicit :py:data:`~typing.Optional` type.
513+
514+
**Note:** This was True by default in mypy versions 0.980 and earlier.
513515

514516
.. confval:: strict_optional
515517

docs/source/kinds_of_types.rst

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -388,12 +388,8 @@ case you should add an explicit ``Optional[...]`` annotation (or type comment).
388388
.. note::
389389

390390
``Optional[...]`` *does not* mean a function argument with a default value.
391-
However, if the default value of an argument is ``None``, you can use
392-
an optional type for the argument, but it's not enforced by default.
393-
You can use the :option:`--no-implicit-optional <mypy --no-implicit-optional>` command-line option to stop
394-
treating arguments with a ``None`` default value as having an implicit
395-
``Optional[...]`` type. It's possible that this will become the default
396-
behavior in the future.
391+
It simply means that ``None`` is a valid value for the argument. This is
392+
a common confusion because ``None`` is a common default value for arguments.
397393

398394
.. _alternative_union_syntax:
399395

mypy/fastparse.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1003,7 +1003,7 @@ def do_func_def(
10031003
return retval
10041004

10051005
def set_type_optional(self, type: Type | None, initializer: Expression | None) -> None:
1006-
if self.options.no_implicit_optional:
1006+
if not self.options.implicit_optional:
10071007
return
10081008
# Indicate that type should be wrapped in an Optional if arg is initialized to None.
10091009
optional = isinstance(initializer, NameExpr) and initializer.name == "None"

mypy/main.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -720,10 +720,9 @@ def add_invertible_flag(
720720
"https://mypy.readthedocs.io/en/stable/kinds_of_types.html#no-strict-optional",
721721
)
722722
add_invertible_flag(
723-
"--no-implicit-optional",
723+
"--implicit-optional",
724724
default=False,
725-
strict_flag=True,
726-
help="Don't assume arguments with default values of None are Optional",
725+
help="Assume arguments with default values of None are Optional",
727726
group=none_group,
728727
)
729728
none_group.add_argument("--strict-optional", action="store_true", help=argparse.SUPPRESS)

mypy/options.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,14 @@ class BuildType:
3939
"disallow_untyped_defs",
4040
"enable_error_code",
4141
"enabled_error_codes",
42-
"follow_imports",
4342
"follow_imports_for_stubs",
43+
"follow_imports",
4444
"ignore_errors",
4545
"ignore_missing_imports",
46+
"implicit_optional",
4647
"implicit_reexport",
4748
"local_partial_types",
4849
"mypyc",
49-
"no_implicit_optional",
5050
"strict_concatenate",
5151
"strict_equality",
5252
"strict_optional",
@@ -162,8 +162,8 @@ def __init__(self) -> None:
162162
self.color_output = True
163163
self.error_summary = True
164164

165-
# Don't assume arguments with default values of None are Optional
166-
self.no_implicit_optional = False
165+
# Assume arguments with default values of None are Optional
166+
self.implicit_optional = False
167167

168168
# Don't re-export names unless they are imported with `from ... as ...`
169169
self.implicit_reexport = True

test-data/unit/check-classes.test

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2979,8 +2979,9 @@ class B: pass
29792979

29802980

29812981
[case testConstructInstanceWith__new__]
2982+
from typing import Optional
29822983
class C:
2983-
def __new__(cls, foo: int = None) -> 'C':
2984+
def __new__(cls, foo: Optional[int] = None) -> 'C':
29842985
obj = object.__new__(cls)
29852986
return obj
29862987

test-data/unit/check-fastparse.test

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ class C:
106106
[builtins fixtures/property.pyi]
107107

108108
[case testFastParsePerArgumentAnnotations]
109+
# flags: --implicit-optional
109110

110111
class A: pass
111112
class B: pass
@@ -130,6 +131,7 @@ def f(a, # type: A
130131
[out]
131132

132133
[case testFastParsePerArgumentAnnotationsWithReturn]
134+
# flags: --implicit-optional
133135

134136
class A: pass
135137
class B: pass

test-data/unit/check-flags.test

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -843,6 +843,7 @@ standard.f(None)
843843
[file mypy.ini]
844844
\[mypy]
845845
strict_optional = False
846+
implicit_optional = true
846847
\[mypy-optional]
847848
strict_optional = True
848849

@@ -862,6 +863,7 @@ standard.f(None)
862863
[file pyproject.toml]
863864
\[tool.mypy]
864865
strict_optional = false
866+
implicit_optional = true
865867
\[[tool.mypy.overrides]]
866868
module = 'optional'
867869
strict_optional = true

test-data/unit/check-functions.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,7 @@ if int():
465465

466466

467467
[case testCallingFunctionsWithDefaultArgumentValues]
468+
# flags: --implicit-optional --no-strict-optional
468469

469470
a, b = None, None # type: (A, B)
470471
if int():

0 commit comments

Comments
 (0)