Skip to content

Commit

Permalink
Remove show_none_errors and strict_optional_whitelist (#13507)
Browse files Browse the repository at this point in the history
These are somewhat buggy and modern per-module options should be
preferred. I can't find any use of strict_optional_whitelist.
There is some use of show_none_errors, but it's all set to True;
I think people are just worried and cargo culting and want mypy to
really, actually give them all the errors.

Fixes #6514, fixes #2396
  • Loading branch information
hauntsaninja committed Aug 25, 2022
1 parent caff030 commit 80c09d5
Show file tree
Hide file tree
Showing 10 changed files with 7 additions and 116 deletions.
8 changes: 0 additions & 8 deletions docs/source/config_file.rst
Original file line number Diff line number Diff line change
Expand Up @@ -574,14 +574,6 @@ Suppressing errors
Note: these configuration options are available in the config file only. There is
no analog available via the command line options.

.. confval:: show_none_errors

:type: boolean
:default: True

Shows errors related to strict ``None`` checking, if the global :confval:`strict_optional`
flag is enabled.

.. confval:: ignore_errors

:type: boolean
Expand Down
15 changes: 1 addition & 14 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

from __future__ import annotations

import fnmatch
import itertools
from collections import defaultdict
from contextlib import contextmanager, nullcontext
Expand Down Expand Up @@ -327,8 +326,6 @@ class TypeChecker(NodeVisitor[None], CheckerPluginInterface):
current_node_deferred = False
# Is this file a typeshed stub?
is_typeshed_stub = False
# Should strict Optional-related errors be suppressed in this file?
suppress_none_errors = False # TODO: Get it from options instead
options: Options
# Used for collecting inferred attribute types so that they can be checked
# for consistency.
Expand Down Expand Up @@ -391,12 +388,7 @@ def __init__(
self.is_stub = tree.is_stub
self.is_typeshed_stub = is_typeshed_file(path)
self.inferred_attribute_types = None
if options.strict_optional_whitelist is None:
self.suppress_none_errors = not options.show_none_errors
else:
self.suppress_none_errors = not any(
fnmatch.fnmatch(path, pattern) for pattern in options.strict_optional_whitelist
)

# If True, process function definitions. If False, don't. This is used
# for processing module top levels in fine-grained incremental mode.
self.recurse_into_functions = True
Expand Down Expand Up @@ -5604,8 +5596,6 @@ def check_subtype(
subtype, supertype, context, msg_text, subtype_label, supertype_label, code=code
):
return False
if self.should_suppress_optional_error([subtype]):
return False
extra_info: list[str] = []
note_msg = ""
notes: list[str] = []
Expand Down Expand Up @@ -5705,9 +5695,6 @@ def contains_none(self, t: Type) -> bool:
)
)

def should_suppress_optional_error(self, related_types: list[Type]) -> bool:
return self.suppress_none_errors and any(self.contains_none(t) for t in related_types)

def named_type(self, name: str) -> Instance:
"""Return an instance type with given name and implicit Any type args.
Expand Down
14 changes: 5 additions & 9 deletions mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -2032,8 +2032,6 @@ def check_arg(
):
self.msg.concrete_only_call(callee_type, context)
elif not is_subtype(caller_type, callee_type, options=self.chk.options):
if self.chk.should_suppress_optional_error([caller_type, callee_type]):
return
code = self.msg.incompatible_argument(
n,
m,
Expand Down Expand Up @@ -2155,13 +2153,11 @@ def check_overload_call(
else:
# There was no plausible match: give up
target = AnyType(TypeOfAny.from_error)

if not self.chk.should_suppress_optional_error(arg_types):
if not is_operator_method(callable_name):
code = None
else:
code = codes.OPERATOR
self.msg.no_variant_matches_arguments(callee, arg_types, context, code=code)
if not is_operator_method(callable_name):
code = None
else:
code = codes.OPERATOR
self.msg.no_variant_matches_arguments(callee, arg_types, context, code=code)

result = self.check_call(
target,
Expand Down
6 changes: 0 additions & 6 deletions mypy/checkmember.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,6 @@ def _analyze_member_access(
elif isinstance(typ, DeletedType):
mx.msg.deleted_as_rvalue(typ, mx.context)
return AnyType(TypeOfAny.from_error)
if mx.chk.should_suppress_optional_error([typ]):
return AnyType(TypeOfAny.from_error)
return report_missing_attribute(mx.original_type, typ, name, mx)


Expand Down Expand Up @@ -427,8 +425,6 @@ def analyze_none_member_access(name: str, typ: NoneType, mx: MemberContext) -> T
ret_type=literal_false,
fallback=mx.named_type("builtins.function"),
)
elif mx.chk.should_suppress_optional_error([typ]):
return AnyType(TypeOfAny.from_error)
else:
return _analyze_member_access(name, mx.named_type("builtins.object"), mx)

Expand Down Expand Up @@ -545,8 +541,6 @@ def analyze_member_var_access(
mx.msg.undefined_in_superclass(name, mx.context)
return AnyType(TypeOfAny.from_error)
else:
if mx.chk and mx.chk.should_suppress_optional_error([itype]):
return AnyType(TypeOfAny.from_error)
return report_missing_attribute(mx.original_type, itype, name, mx)


Expand Down
2 changes: 0 additions & 2 deletions mypy/config_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ def check_follow_imports(choice: str) -> str:
# types.
ini_config_types: Final[dict[str, _INI_PARSER_CALLABLE]] = {
"python_version": parse_version,
"strict_optional_whitelist": lambda s: s.split(),
"custom_typing_module": str,
"custom_typeshed_dir": expand_path,
"mypy_path": lambda s: [expand_path(p.strip()) for p in re.split("[,:]", s)],
Expand Down Expand Up @@ -172,7 +171,6 @@ def check_follow_imports(choice: str) -> str:
toml_config_types.update(
{
"python_version": parse_version,
"strict_optional_whitelist": try_split,
"mypy_path": lambda s: [expand_path(p) for p in try_split(s, "[,:]")],
"files": lambda s: split_and_match_files_list(try_split(s)),
"follow_imports": lambda s: check_follow_imports(str(s)),
Expand Down
6 changes: 0 additions & 6 deletions mypy/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -733,9 +733,6 @@ def add_invertible_flag(
dest="strict_optional",
help="Disable strict Optional checks (inverse: --strict-optional)",
)
none_group.add_argument(
"--strict-optional-whitelist", metavar="GLOB", nargs="*", help=argparse.SUPPRESS
)

lint_group = parser.add_argument_group(
title="Configuring warnings",
Expand Down Expand Up @@ -1268,9 +1265,6 @@ def set_strict_flags() -> None:
options.disabled_error_codes -= options.enabled_error_codes

# Set build flags.
if options.strict_optional_whitelist is not None:
# TODO: Deprecate, then kill this flag
options.strict_optional = True
if special_opts.find_occurrences:
state.find_occurrences = special_opts.find_occurrences.split(".")
assert state.find_occurrences is not None
Expand Down
9 changes: 0 additions & 9 deletions mypy/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,9 @@ class BuildType:
"local_partial_types",
"mypyc",
"no_implicit_optional",
"show_none_errors",
"strict_concatenate",
"strict_equality",
"strict_optional",
"strict_optional_whitelist",
"warn_no_return",
"warn_return_any",
"warn_unreachable",
Expand Down Expand Up @@ -162,13 +160,6 @@ def __init__(self) -> None:
self.color_output = True
self.error_summary = True

# Files in which to allow strict-Optional related errors
# TODO: Kill this in favor of show_none_errors
self.strict_optional_whitelist: list[str] | None = None

# Alternate way to show/hide strict-None-checking related errors
self.show_none_errors = True

# Don't assume arguments with default values of None are Optional
self.no_implicit_optional = False

Expand Down
9 changes: 0 additions & 9 deletions test-data/unit/check-basic.test
Original file line number Diff line number Diff line change
Expand Up @@ -391,15 +391,6 @@ b = none.__bool__()
reveal_type(b) # N: Revealed type is "Literal[False]"
[builtins fixtures/bool.pyi]

[case testNoneHasBoolShowNoneErrorsFalse]
none = None
b = none.__bool__()
reveal_type(b) # N: Revealed type is "Literal[False]"
[builtins fixtures/bool.pyi]
[file mypy.ini]
\[mypy]
show_none_errors = False

[case testAssignmentInvariantNoteForList]
from typing import List
x: List[int]
Expand Down
52 changes: 0 additions & 52 deletions test-data/unit/check-optional.test
Original file line number Diff line number Diff line change
Expand Up @@ -396,58 +396,6 @@ reveal_type(None if bool() else 0) # N: Revealed type is "Union[Literal[0]?, No
reveal_type([0, None, 0]) # N: Revealed type is "builtins.list[Union[builtins.int, None]]"
[builtins fixtures/list.pyi]

[case testOptionalWhitelistSuppressesOptionalErrors]
# flags: --strict-optional-whitelist
import a
import b
[file a.py]
from typing import Optional
x = None # type: Optional[str]
x + "foo"

[file b.py]
from typing import Optional
x = None # type: Optional[int]
x + 1

[builtins fixtures/primitives.pyi]

[case testOptionalWhitelistPermitsOtherErrors]
# flags: --strict-optional-whitelist
import a
import b
[file a.py]
from typing import Optional
x = None # type: Optional[str]
x + "foo"

[file b.py]
from typing import Optional
x = None # type: Optional[int]
x + 1
1 + "foo"
[builtins fixtures/primitives.pyi]
[out]
tmp/b.py:4: error: Unsupported operand types for + ("int" and "str")

[case testOptionalWhitelistPermitsWhitelistedFiles]
# flags: --strict-optional-whitelist **/a.py
import a
import b
[file a.py]
from typing import Optional
x = None # type: Optional[str]
x + "foo"

[file b.py]
from typing import Optional
x = None # type: Optional[int]
x + 1
[builtins fixtures/primitives.pyi]
[out]
tmp/a.py:3: error: Unsupported left operand type for + ("None")
tmp/a.py:3: note: Left operand is of type "Optional[str]"

[case testNoneContextInference]
from typing import Dict, List
def f() -> List[None]:
Expand Down
2 changes: 1 addition & 1 deletion test-data/unit/check-overloading.test
Original file line number Diff line number Diff line change
Expand Up @@ -5986,10 +5986,10 @@ reveal_type(f2(A())) # E: No overload variant of "f2" matches argument type "A"
if True:
@overload # E: Single overload definition, multiple required
def f3(x: A) -> A: ...
def f3(x): ...
if maybe_true: # E: Name "maybe_true" is not defined
@overload # E: Single overload definition, multiple required
def g3(x: B) -> B: ...
def f3(x): ...
reveal_type(f3(A())) # N: Revealed type is "__main__.A"

if True:
Expand Down

0 comments on commit 80c09d5

Please sign in to comment.