diff --git a/docs/source/config_file.rst b/docs/source/config_file.rst index 663a0d2229a6..92236f861488 100644 --- a/docs/source/config_file.rst +++ b/docs/source/config_file.rst @@ -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 diff --git a/mypy/checker.py b/mypy/checker.py index 076f9e3763d9..8c6c5ca19bb5 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -2,7 +2,6 @@ from __future__ import annotations -import fnmatch import itertools from collections import defaultdict from contextlib import contextmanager, nullcontext @@ -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. @@ -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 @@ -5580,8 +5572,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] = [] @@ -5681,9 +5671,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. diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index b0a4ec5644cc..9bc65e9d7596 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -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, @@ -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, diff --git a/mypy/checkmember.py b/mypy/checkmember.py index 3be961ee9fdc..a025d1e04c86 100644 --- a/mypy/checkmember.py +++ b/mypy/checkmember.py @@ -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) @@ -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) @@ -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) diff --git a/mypy/config_parser.py b/mypy/config_parser.py index 55cc0fea3720..3c321a30f702 100644 --- a/mypy/config_parser.py +++ b/mypy/config_parser.py @@ -132,7 +132,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)], @@ -161,7 +160,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)), diff --git a/mypy/main.py b/mypy/main.py index 7388e9a375ff..695a1917a192 100644 --- a/mypy/main.py +++ b/mypy/main.py @@ -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", @@ -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 diff --git a/mypy/options.py b/mypy/options.py index ac46b70f8ebe..aef468f76641 100644 --- a/mypy/options.py +++ b/mypy/options.py @@ -45,11 +45,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", @@ -160,13 +158,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 diff --git a/test-data/unit/check-basic.test b/test-data/unit/check-basic.test index 5beabe0f72b4..f8a905351156 100644 --- a/test-data/unit/check-basic.test +++ b/test-data/unit/check-basic.test @@ -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] diff --git a/test-data/unit/check-optional.test b/test-data/unit/check-optional.test index a0383a35c623..03b076fb09db 100644 --- a/test-data/unit/check-optional.test +++ b/test-data/unit/check-optional.test @@ -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]: diff --git a/test-data/unit/check-overloading.test b/test-data/unit/check-overloading.test index 62e3d08b9aff..a5e6cefc2af0 100644 --- a/test-data/unit/check-overloading.test +++ b/test-data/unit/check-overloading.test @@ -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: