diff --git a/mypy/checker.py b/mypy/checker.py index fce7e7d7a08e..772ab8b122d3 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -133,9 +133,9 @@ ('is_upper_bound', bool), # False => precise type ]) -# Keeps track of partial types in a single scope. In fine-grained incremental -# mode partial types initially defined at the top level cannot be completed in -# a function, and we use the 'is_function' attribute to enforce this. +# Keeps track of partial types in a single scope. By default, partial +# types initially defined at the top level cannot be completed in a +# function, and we use the 'is_function' attribute to enforce this. PartialTypeScope = NamedTuple('PartialTypeScope', [('map', Dict[Var, Context]), ('is_function', bool), ('is_local', bool), @@ -1715,7 +1715,8 @@ def visit_class_def(self, defn: ClassDef) -> None: for base in typ.mro[1:]: if base.is_final: self.fail(message_registry.CANNOT_INHERIT_FROM_FINAL.format(base.name), defn) - with self.tscope.class_scope(defn.info), self.enter_partial_types(is_class=True): + with self.tscope.class_scope(typ), self.enter_partial_types(is_class=True, + is_enum=typ.is_enum): old_binder = self.binder self.binder = ConditionalTypeBinder() with self.binder.top_frame_context(): @@ -2042,11 +2043,11 @@ def visit_assignment_stmt(self, s: AssignmentStmt) -> None: self.fail(message_registry.DEPENDENT_FINAL_IN_CLASS_BODY, s) def check_assignment(self, lvalue: Lvalue, rvalue: Expression, infer_lvalue_type: bool = True, - new_syntax: bool = False) -> None: + new_syntax: bool = False, *, for_stmt: bool = False) -> None: """Type check a single assignment: lvalue = rvalue.""" if isinstance(lvalue, TupleExpr) or isinstance(lvalue, ListExpr): self.check_assignment_to_multiple_lvalues(lvalue.items, rvalue, rvalue, - infer_lvalue_type) + infer_lvalue_type, for_stmt=for_stmt) else: self.try_infer_partial_generic_type_from_assignment(lvalue, rvalue, '=') lvalue_type, index_lvalue, inferred = self.check_lvalue(lvalue) @@ -2082,7 +2083,7 @@ def check_assignment(self, lvalue: Lvalue, rvalue: Expression, infer_lvalue_type # None initializers preserve the partial None type. return - if is_valid_inferred_type(rvalue_type): + if is_valid_inferred_type(rvalue_type, for_stmt): var = lvalue_type.var partial_types = self.find_partial_types(var) if partial_types is not None: @@ -2099,7 +2100,7 @@ def check_assignment(self, lvalue: Lvalue, rvalue: Expression, infer_lvalue_type else: # Try to infer a partial type. No need to check the return value, as # an error will be reported elsewhere. - self.infer_partial_type(lvalue_type.var, lvalue, rvalue_type) + self.infer_partial_type(lvalue_type.var, lvalue, rvalue_type, rvalue) # Handle None PartialType's super type checking here, after it's resolved. if (isinstance(lvalue, RefExpr) and self.check_compatibility_all_supers(lvalue, lvalue_type, rvalue)): @@ -2146,7 +2147,7 @@ def check_assignment(self, lvalue: Lvalue, rvalue: Expression, infer_lvalue_type rvalue_type = self.expr_checker.accept(rvalue) if not inferred.is_final: rvalue_type = remove_instance_last_known_values(rvalue_type) - self.infer_variable_type(inferred, lvalue, rvalue_type, rvalue) + self.infer_variable_type(inferred, lvalue, rvalue_type, rvalue, for_stmt=for_stmt) # (type, operator) tuples for augmented assignments supported with partial types partial_type_augmented_ops = { @@ -2475,7 +2476,9 @@ def check_final(self, def check_assignment_to_multiple_lvalues(self, lvalues: List[Lvalue], rvalue: Expression, context: Context, - infer_lvalue_type: bool = True) -> None: + infer_lvalue_type: bool = True, + *, + for_stmt: bool) -> None: if isinstance(rvalue, TupleExpr) or isinstance(rvalue, ListExpr): # Recursively go into Tuple or List expression rhs instead of # using the type of rhs, because this allowed more fine grained @@ -2545,7 +2548,8 @@ def check_assignment_to_multiple_lvalues(self, lvalues: List[Lvalue], rvalue: Ex for lv, rv in lr_pairs: self.check_assignment(lv, rv, infer_lvalue_type) else: - self.check_multi_assignment(lvalues, rvalue, context, infer_lvalue_type) + self.check_multi_assignment(lvalues, rvalue, context, infer_lvalue_type, + for_stmt=for_stmt) def check_rvalue_count_in_assignment(self, lvalues: List[Lvalue], rvalue_count: int, context: Context) -> bool: @@ -2565,7 +2569,9 @@ def check_multi_assignment(self, lvalues: List[Lvalue], context: Context, infer_lvalue_type: bool = True, rv_type: Optional[Type] = None, - undefined_rvalue: bool = False) -> None: + undefined_rvalue: bool = False, + *, + for_stmt: bool) -> None: """Check the assignment of one rvalue to a number of lvalues.""" # Infer the type of an ordinary rvalue expression. @@ -2584,22 +2590,24 @@ def check_multi_assignment(self, lvalues: List[Lvalue], lv = lv.expr temp_node = self.temp_node(AnyType(TypeOfAny.from_another_any, source_any=rvalue_type), context) - self.check_assignment(lv, temp_node, infer_lvalue_type) + self.check_assignment(lv, temp_node, infer_lvalue_type, for_stmt=for_stmt) elif isinstance(rvalue_type, TupleType): self.check_multi_assignment_from_tuple(lvalues, rvalue, rvalue_type, - context, undefined_rvalue, infer_lvalue_type) + context, undefined_rvalue, infer_lvalue_type, + for_stmt=for_stmt) elif isinstance(rvalue_type, UnionType): self.check_multi_assignment_from_union(lvalues, rvalue, rvalue_type, context, - infer_lvalue_type) + infer_lvalue_type, for_stmt=for_stmt) elif isinstance(rvalue_type, Instance) and rvalue_type.type.fullname == 'builtins.str': self.msg.unpacking_strings_disallowed(context) else: self.check_multi_assignment_from_iterable(lvalues, rvalue_type, - context, infer_lvalue_type) + context, infer_lvalue_type, + for_stmt=for_stmt) def check_multi_assignment_from_union(self, lvalues: List[Expression], rvalue: Expression, rvalue_type: UnionType, context: Context, - infer_lvalue_type: bool) -> None: + infer_lvalue_type: bool, *, for_stmt: bool) -> None: """Check assignment to multiple lvalue targets when rvalue type is a Union[...]. For example: @@ -2622,7 +2630,7 @@ def check_multi_assignment_from_union(self, lvalues: List[Expression], rvalue: E # the inferred lvalue types for each union item. self.check_multi_assignment(lvalues, rvalue, context, infer_lvalue_type=infer_lvalue_type, - rv_type=item, undefined_rvalue=True) + rv_type=item, undefined_rvalue=True, for_stmt=for_stmt) for t, lv in zip(transposed, self.flatten_lvalues(lvalues)): t.append(self.type_map.pop(lv, AnyType(TypeOfAny.special_form))) union_types = tuple(make_simplified_union(col) for col in transposed) @@ -2667,7 +2675,8 @@ def flatten_lvalues(self, lvalues: List[Expression]) -> List[Expression]: def check_multi_assignment_from_tuple(self, lvalues: List[Lvalue], rvalue: Expression, rvalue_type: TupleType, context: Context, undefined_rvalue: bool, - infer_lvalue_type: bool = True) -> None: + infer_lvalue_type: bool = True, *, + for_stmt: bool) -> None: if self.check_rvalue_count_in_assignment(lvalues, len(rvalue_type.items), context): star_index = next((i for i, lv in enumerate(lvalues) if isinstance(lv, StarExpr)), len(lvalues)) @@ -2690,7 +2699,7 @@ def check_multi_assignment_from_tuple(self, lvalues: List[Lvalue], rvalue: Expre if isinstance(reinferred_rvalue_type, UnionType): self.check_multi_assignment_from_union(lvalues, rvalue, reinferred_rvalue_type, context, - infer_lvalue_type) + infer_lvalue_type, for_stmt=for_stmt) return if isinstance(reinferred_rvalue_type, AnyType) and self.current_node_deferred: # Doing more inference in deferred nodes can be hard, so give up for now. @@ -2702,14 +2711,17 @@ def check_multi_assignment_from_tuple(self, lvalues: List[Lvalue], rvalue: Expre rvalue_type.items, star_index, len(lvalues)) for lv, rv_type in zip(left_lvs, left_rv_types): - self.check_assignment(lv, self.temp_node(rv_type, context), infer_lvalue_type) + self.check_assignment(lv, self.temp_node(rv_type, context), infer_lvalue_type, + for_stmt=for_stmt) if star_lv: list_expr = ListExpr([self.temp_node(rv_type, context) for rv_type in star_rv_types]) list_expr.set_line(context.get_line()) - self.check_assignment(star_lv.expr, list_expr, infer_lvalue_type) + self.check_assignment(star_lv.expr, list_expr, infer_lvalue_type, + for_stmt=for_stmt) for lv, rv_type in zip(right_lvs, right_rv_types): - self.check_assignment(lv, self.temp_node(rv_type, context), infer_lvalue_type) + self.check_assignment(lv, self.temp_node(rv_type, context), infer_lvalue_type, + for_stmt=for_stmt) def lvalue_type_for_inference(self, lvalues: List[Lvalue], rvalue_type: TupleType) -> Type: star_index = next((i for i, lv in enumerate(lvalues) @@ -2771,7 +2783,8 @@ def type_is_iterable(self, type: Type) -> bool: def check_multi_assignment_from_iterable(self, lvalues: List[Lvalue], rvalue_type: Type, context: Context, - infer_lvalue_type: bool = True) -> None: + infer_lvalue_type: bool = True, *, + for_stmt: bool) -> None: rvalue_type = get_proper_type(rvalue_type) if self.type_is_iterable(rvalue_type) and isinstance(rvalue_type, Instance): item_type = self.iterable_item_type(rvalue_type) @@ -2779,10 +2792,10 @@ def check_multi_assignment_from_iterable(self, lvalues: List[Lvalue], rvalue_typ if isinstance(lv, StarExpr): items_type = self.named_generic_type('builtins.list', [item_type]) self.check_assignment(lv.expr, self.temp_node(items_type, context), - infer_lvalue_type) + infer_lvalue_type, for_stmt=for_stmt) else: self.check_assignment(lv, self.temp_node(item_type, context), - infer_lvalue_type) + infer_lvalue_type, for_stmt=for_stmt) else: self.msg.type_not_iterable(rvalue_type, context) @@ -2841,24 +2854,25 @@ def is_definition(self, s: Lvalue) -> bool: return False def infer_variable_type(self, name: Var, lvalue: Lvalue, - init_type: Type, context: Context) -> None: + init_type: Type, init_expr: Expression, *, for_stmt: bool) -> None: """Infer the type of initialized variables from initializer type.""" init_type = get_proper_type(init_type) if isinstance(init_type, DeletedType): - self.msg.deleted_as_rvalue(init_type, context) - elif not is_valid_inferred_type(init_type) and not self.no_partial_types: + self.msg.deleted_as_rvalue(init_type, context=init_expr) + elif not is_valid_inferred_type( + init_type, for_stmt=for_stmt) and not self.no_partial_types: # We cannot use the type of the initialization expression for full type # inference (it's not specific enough), but we might be able to give # partial type which will be made more specific later. A partial type # gets generated in assignment like 'x = []' where item type is not known. - if not self.infer_partial_type(name, lvalue, init_type): - self.msg.need_annotation_for_var(name, context, self.options.python_version) + if not self.infer_partial_type(name, lvalue, init_type, init_expr): + self.msg.need_annotation_for_var(name, init_expr, self.options.python_version) self.set_inference_error_fallback_type(name, lvalue, init_type) elif (isinstance(lvalue, MemberExpr) and self.inferred_attribute_types is not None and lvalue.def_var and lvalue.def_var in self.inferred_attribute_types and not is_same_type(self.inferred_attribute_types[lvalue.def_var], init_type)): # Multiple, inconsistent types inferred for an attribute. - self.msg.need_annotation_for_var(name, context, self.options.python_version) + self.msg.need_annotation_for_var(name, init_expr, self.options.python_version) name.type = AnyType(TypeOfAny.from_error) else: # Infer type of the target. @@ -2868,9 +2882,14 @@ def infer_variable_type(self, name: Var, lvalue: Lvalue, self.set_inferred_type(name, lvalue, init_type) - def infer_partial_type(self, name: Var, lvalue: Lvalue, init_type: Type) -> bool: + def infer_partial_type(self, name: Var, lvalue: Lvalue, init_type: Type, + init_expr: Expression) -> bool: init_type = get_proper_type(init_type) if isinstance(init_type, NoneType): + if isinstance(init_expr, CallExpr): + # In cases like 'x = f()', we don't infer a partial type but None. + self.set_inferred_type(name, lvalue, init_type) + return True partial_type = PartialType(None, name) elif isinstance(init_type, Instance): fullname = init_type.type.fullname @@ -3536,7 +3555,9 @@ def analyze_container_item_type(self, typ: Type) -> Optional[Type]: def analyze_index_variables(self, index: Expression, item_type: Type, infer_lvalue_type: bool, context: Context) -> None: """Type check or infer for loop or list comprehension index vars.""" - self.check_assignment(index, self.temp_node(item_type, context), infer_lvalue_type) + self.check_assignment( + index, self.temp_node(item_type, context), infer_lvalue_type, for_stmt=True + ) def visit_del_stmt(self, s: DelStmt) -> None: if isinstance(s.expr, IndexExpr): @@ -4687,7 +4708,7 @@ def lookup_qualified(self, name: str) -> SymbolTableNode: @contextmanager def enter_partial_types(self, *, is_function: bool = False, - is_class: bool = False) -> Iterator[None]: + is_class: bool = False, is_enum: bool = False) -> Iterator[None]: """Enter a new scope for collecting partial types. Also report errors for (some) variables which still have partial @@ -4699,12 +4720,13 @@ def enter_partial_types(self, *, is_function: bool = False, # Don't complain about not being able to infer partials if it is # at the toplevel (with allow_untyped_globals) or if it is in an - # untyped function being checked with check_untyped_defs. + # untyped function being checked with check_untyped_defs, or in an + # enum class (None is a valid value for an item). permissive = (self.options.allow_untyped_globals and not is_local) or ( self.options.check_untyped_defs and self.dynamic_funcs and self.dynamic_funcs[-1] - ) + ) or is_enum partial_types, _, _ = self.partial_types.pop() if not self.current_node_deferred: @@ -5433,7 +5455,7 @@ def infer_operator_assignment_method(typ: Type, operator: str) -> Tuple[bool, st return False, method -def is_valid_inferred_type(typ: Type) -> bool: +def is_valid_inferred_type(typ: Type, for_stmt: bool = False) -> bool: """Is an inferred type valid? Examples of invalid types include the None type or List[]. @@ -5442,11 +5464,15 @@ def is_valid_inferred_type(typ: Type) -> bool: invalid. When doing strict Optional checking, only None and types that are incompletely defined (i.e. contain UninhabitedType) are invalid. """ - if isinstance(get_proper_type(typ), (NoneType, UninhabitedType)): + proper_type = get_proper_type(typ) + if isinstance(proper_type, (NoneType, UninhabitedType)): # With strict Optional checking, we *may* eventually infer NoneType when # the initializer is None, but we only do that if we can't infer a # specific Optional type. This resolution happens in # leave_partial_types when we pop a partial types scope. + if for_stmt and isinstance(proper_type, NoneType): + # For statements shouldn't produce partial types. + return True return False return not typ.accept(NothingSeeker()) diff --git a/mypy/dmypy_server.py b/mypy/dmypy_server.py index eb53935db297..ad1b9d4a2ef2 100644 --- a/mypy/dmypy_server.py +++ b/mypy/dmypy_server.py @@ -143,6 +143,8 @@ def process_start_options(flags: List[str], allow_sources: bool) -> Options: sys.exit("dmypy: start/restart should not disable incremental mode") if options.follow_imports not in ('skip', 'error', 'normal'): sys.exit("dmypy: follow-imports=silent not supported") + if not options.local_partial_types: + sys.exit("dmypy: disabling local-partial-types not supported") return options diff --git a/mypy/main.py b/mypy/main.py index 40c5f39d2239..5dd4142d72a2 100644 --- a/mypy/main.py +++ b/mypy/main.py @@ -778,7 +778,7 @@ def add_invertible_flag(flag: str, parser.add_argument('--semantic-analysis-only', action='store_true', help=argparse.SUPPRESS) # --local-partial-types disallows partial types spanning module top level and a function # (implicitly defined in fine-grained incremental mode) - parser.add_argument('--local-partial-types', action='store_true', help=argparse.SUPPRESS) + add_invertible_flag('--local-partial-types', default=False, help=argparse.SUPPRESS) # --logical-deps adds some more dependencies that are not semantically needed, but # may be helpful to determine relative importance of classes and functions for overall # type precision in a code base. It also _removes_ some deps, so this flag should be never diff --git a/mypy/options.py b/mypy/options.py index 026046af5da4..03c6c2dcd428 100644 --- a/mypy/options.py +++ b/mypy/options.py @@ -277,7 +277,7 @@ def __init__(self) -> None: self.dump_deps = False self.logical_deps = False # If True, partial types can't span a module top level and a function - self.local_partial_types = False + self.local_partial_types = True # Some behaviors are changed when using Bazel (https://bazel.build). self.bazel = False # If True, export inferred types for all expressions as BuildResult.types diff --git a/test-data/stdlib-samples/3.2/shutil.py b/test-data/stdlib-samples/3.2/shutil.py index e7b5e5aacd04..98ff6fd0f7e7 100644 --- a/test-data/stdlib-samples/3.2/shutil.py +++ b/test-data/stdlib-samples/3.2/shutil.py @@ -65,7 +65,7 @@ class RegistryError(Exception): if sys.platform == "win32": _WindowsError = WindowsError else: - _WindowsError = None + _WindowsError = None # type: None # Function aliases to be patched in test cases diff --git a/test-data/unit/check-basic.test b/test-data/unit/check-basic.test index 4fa77b12055e..6cdd4dde3a9a 100644 --- a/test-data/unit/check-basic.test +++ b/test-data/unit/check-basic.test @@ -399,7 +399,7 @@ def foo( pass [case testNoneHasBool] -none = None +none: None = None b = none.__bool__() reveal_type(b) # N: Revealed type is 'builtins.bool' [builtins fixtures/bool.pyi] diff --git a/test-data/unit/check-callable.test b/test-data/unit/check-callable.test index 31a892337a2c..76f5d9513256 100644 --- a/test-data/unit/check-callable.test +++ b/test-data/unit/check-callable.test @@ -429,7 +429,6 @@ def g(o: int) -> None: [builtins fixtures/callable.pyi] [case testCallableTuple] - from typing import NamedTuple Thing = NamedTuple('Thing', [('s', str), ('n', int)]) @@ -440,26 +439,24 @@ def g(o: Thing) -> None: i, s = o i + s # E: Unsupported operand types for + ("str" and "int") o(1,2,3) - [builtins fixtures/callable.pyi] [case testCallableNoArgs] - if callable(): # E: Missing positional argument "x" in call to "callable" pass - [builtins fixtures/callable.pyi] [case testCallableWithNoneArgs] - -fn = None +fn = None # E: Need type annotation for "fn" if callable(fn): fn() +fn2: None = None +if callable(fn2): + fn2() [builtins fixtures/callable.pyi] [case testCallableUnionOfNoneAndCallable] - from typing import Union, Callable def f() -> int: diff --git a/test-data/unit/check-columns.test b/test-data/unit/check-columns.test index 43ff97210947..577d41e8b359 100644 --- a/test-data/unit/check-columns.test +++ b/test-data/unit/check-columns.test @@ -235,6 +235,7 @@ y: Dict[int, int] = { [builtins fixtures/dict.pyi] [case testColumnCannotDetermineType] +# flags: --no-local-partial-types (x) # E:2: Cannot determine type of 'x' x = None diff --git a/test-data/unit/check-errorcodes.test b/test-data/unit/check-errorcodes.test index 800c33c5124a..5ddedbc36c55 100644 --- a/test-data/unit/check-errorcodes.test +++ b/test-data/unit/check-errorcodes.test @@ -462,7 +462,7 @@ c = {} # E: Expected TypedDict key 'x' but found no keys [typeddict-item] [case testErrorCodeCannotDetermineType] y = x # E: Cannot determine type of 'x' [has-type] reveal_type(y) # N: Revealed type is 'Any' -x = None +x = None # E: Need type annotation for "x" [var-annotated] [case testErrorCodeRedundantCast] # flags: --warn-redundant-casts diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test index 8e57ca2a3841..ef10173c5a76 100644 --- a/test-data/unit/check-functions.test +++ b/test-data/unit/check-functions.test @@ -2201,7 +2201,7 @@ from typing import Callable class A: def f(self) -> None: # In particular, test that the error message contains "g" of "A". - self.g() # E: Too few arguments for "g" of "A" + self.g() # E: Too few arguments for "g" of "A" self.g(1) @dec def g(self, x: str) -> None: pass @@ -2525,7 +2525,7 @@ reveal_type(bar(None)) # N: Revealed type is 'None' [out] [case testNoComplainInferredNone] -# flags: --no-strict-optional +# flags: --no-strict-optional --no-local-partial-types from typing import TypeVar, Optional T = TypeVar('T') def X(val: T) -> T: ... @@ -2540,7 +2540,7 @@ xx: Optional[int] = X(x_in) from typing import TypeVar, Optional T = TypeVar('T') def X(val: T) -> T: ... -x_in = None +x_in = X(None) def Y(x: Optional[str] = X(x_in)): ... xx: Optional[int] = X(x_in) diff --git a/test-data/unit/check-inference.test b/test-data/unit/check-inference.test index 1b198f607e1a..12825a53f3a5 100644 --- a/test-data/unit/check-inference.test +++ b/test-data/unit/check-inference.test @@ -979,7 +979,6 @@ class B: pass [builtins fixtures/for.pyi] [case testInferenceOfFor2] - a, b, c = None, None, None # type: (A, B, C) for x, (y, z) in [(A(), (B(), C()))]: b = x # Fail @@ -1000,11 +999,11 @@ class B: pass class C: pass [builtins fixtures/for.pyi] [out] -main:4: error: Incompatible types in assignment (expression has type "A", variable has type "B") -main:5: error: Incompatible types in assignment (expression has type "B", variable has type "C") -main:6: error: Incompatible types in assignment (expression has type "C", variable has type "A") -main:10: error: Need more than 2 values to unpack (3 expected) -main:12: error: '__main__.B' object is not iterable +main:3: error: Incompatible types in assignment (expression has type "A", variable has type "B") +main:4: error: Incompatible types in assignment (expression has type "B", variable has type "C") +main:5: error: Incompatible types in assignment (expression has type "C", variable has type "A") +main:9: error: Need more than 2 values to unpack (3 expected) +main:11: error: '__main__.B' object is not iterable [case testInferenceOfFor3] @@ -1525,12 +1524,14 @@ b[{}] = 1 [builtins fixtures/dict.pyi] [case testInferDictInitializedToEmptyAndUpdatedFromMethod] +# flags: --no-local-partial-types map = {} def add() -> None: map[1] = 2 [builtins fixtures/dict.pyi] [case testInferDictInitializedToEmptyAndUpdatedFromMethodUnannotated] +# flags: --no-local-partial-types map = {} def add(): map[1] = 2 @@ -1720,7 +1721,7 @@ reveal_type(C().a) # N: Revealed type is 'builtins.dict[Any, Any]' [builtins fixtures/dict.pyi] [case testInferAttributeInitializedToNoneAndAssignedClassBody] -# flags: --strict-optional +# flags: --strict-optional --no-local-partial-types class C: a = None def __init__(self) -> None: @@ -1755,7 +1756,7 @@ reveal_type(dd) # N: Revealed type is 'builtins.dict[builtins.str, builtins.int [builtins fixtures/dict.pyi] [case testInferFromEmptyDictWhenUsingInSpecialCase] -d = None +d = None # E: Need type annotation for "d" if 'x' in d: # E: "None" has no attribute "__iter__" (not iterable) pass reveal_type(d) # N: Revealed type is 'None' @@ -1864,7 +1865,7 @@ x = 1 [out] [case testPartiallyInitializedVariableDoesNotEscapeScope2] -x = None +x = None # E: Need type annotation for "x" def f() -> None: x = None x = 1 @@ -1891,19 +1892,19 @@ main:6: error: Incompatible types in assignment (expression has type "int", vari main:7: error: "None" not callable [case testGlobalInitializedToNoneSetFromFunction] +# flags: --no-local-partial-types a = None def f(): global a a = 42 -[out] [case testGlobalInitializedToNoneSetFromMethod] +# flags: --no-local-partial-types a = None class C: def m(self): global a a = 42 -[out] -- More partial type errors -- ------------------------ @@ -1911,13 +1912,11 @@ class C: [case testPartialTypeErrorSpecialCase1] # This used to crash. class A: - x = None + x = None # E: Need type annotation for "x" def f(self) -> None: for a in self.x: pass [builtins fixtures/for.pyi] -[out] -main:5: error: "None" has no attribute "__iter__" (not iterable) [case testPartialTypeErrorSpecialCase2] # This used to crash. @@ -1932,13 +1931,11 @@ main:3: error: Need type annotation for "x" (hint: "x: List[] = ...") [case testPartialTypeErrorSpecialCase3] class A: - x = None + x = None # E: Need type annotation for "x" def f(self) -> None: for a in A.x: pass [builtins fixtures/for.pyi] -[out] -main:4: error: "None" has no attribute "__iter__" (not iterable) -- Multipass @@ -1975,7 +1972,7 @@ T = TypeVar('T') class A: def f(self) -> None: - self.g() # E: Too few arguments for "g" of "A" + self.g() # E: Too few arguments for "g" of "A" self.g(1) @dec def g(self, x: str) -> None: pass @@ -2281,9 +2278,9 @@ main:4: error: Invalid type: try using Literal[0] instead? [case testNoCrashOnPartialMember] class C: - x = None + x = None # E: Need type annotation for "x" def __init__(self) -> None: - self.x = [] # E: Need type annotation for "x" (hint: "x: List[] = ...") + self.x = [] [builtins fixtures/list.pyi] [out] @@ -2305,7 +2302,7 @@ T = TypeVar('T', bound=str) def f() -> Tuple[T]: ... -x = None +x = None # E: Need type annotation for "x" if int(): (x,) = f() [builtins fixtures/tuple.pyi] diff --git a/test-data/unit/check-literal.test b/test-data/unit/check-literal.test index a83df1ff0162..eadd24999a80 100644 --- a/test-data/unit/check-literal.test +++ b/test-data/unit/check-literal.test @@ -1326,7 +1326,7 @@ bool2 = True bool3: bool = True none1: Literal[None] = None -none2 = None +none2 = None # E: Need type annotation for "none2" none3: None = None reveal_type(int1) # N: Revealed type is 'Literal[1]' @@ -1356,7 +1356,7 @@ combined: Literal[1, "foo", True, None] a = 1 b = "foo" c = True -d = None +d = None # E: Need type annotation for "d" w = a # E: Incompatible types in assignment (expression has type "int", variable has type "Literal[1]") x = b # E: Incompatible types in assignment (expression has type "str", variable has type "Literal['foo']") @@ -2456,13 +2456,13 @@ from typing_extensions import Final, Literal var1: Final = 1 var2: Final = "foo" var3: Final = True -var4: Final = None +var4: Final = None # E: Need type annotation for "var4" class Foo: classvar1: Final = 1 classvar2: Final = "foo" classvar3: Final = True - classvar4: Final = None + classvar4: Final = None # E: Need type annotation for "classvar4" def __init__(self) -> None: self.instancevar1: Final = 1 @@ -2487,11 +2487,11 @@ force4(reveal_type(var4)) # N: Revealed type is 'None' reveal_type(Foo.classvar1) # N: Revealed type is 'Literal[1]?' reveal_type(Foo.classvar2) # N: Revealed type is 'Literal['foo']?' reveal_type(Foo.classvar3) # N: Revealed type is 'Literal[True]?' -reveal_type(Foo.classvar4) # N: Revealed type is 'None' +reveal_type(Foo.classvar4) # N: Revealed type is 'Any' force1(reveal_type(Foo.classvar1)) # N: Revealed type is 'Literal[1]' force2(reveal_type(Foo.classvar2)) # N: Revealed type is 'Literal['foo']' force3(reveal_type(Foo.classvar3)) # N: Revealed type is 'Literal[True]' -force4(reveal_type(Foo.classvar4)) # N: Revealed type is 'None' +force4(reveal_type(Foo.classvar4)) # N: Revealed type is 'Any' f = Foo() reveal_type(f.instancevar1) # N: Revealed type is 'Literal[1]?' diff --git a/test-data/unit/check-optional.test b/test-data/unit/check-optional.test index 8d054595d685..3bd18068811c 100644 --- a/test-data/unit/check-optional.test +++ b/test-data/unit/check-optional.test @@ -1,7 +1,7 @@ -- Tests for strict Optional behavior [case testImplicitNoneType] -x = None +x = None # E: Need type annotation for "x" x() # E: "None" not callable [case testImplicitNoneTypeInNestedFunction] @@ -315,7 +315,7 @@ def f() -> Generator[None, None, None]: [out] [case testNoneAndStringIsNone] -a = None +a: None = None b = "foo" reveal_type(a and b) # N: Revealed type is 'None' @@ -627,7 +627,7 @@ x is not None and x + '42' # E: Unsupported operand types for + ("int" and "str [case testInvalidBooleanBranchIgnored] from typing import Optional -x = None +x: None = None x is not None and x + 42 [builtins fixtures/isinstance.pyi] diff --git a/test-data/unit/check-protocols.test b/test-data/unit/check-protocols.test index b7f4fd5bdd8e..a01c31e3801e 100644 --- a/test-data/unit/check-protocols.test +++ b/test-data/unit/check-protocols.test @@ -266,7 +266,7 @@ class MyHashable(Protocol): return 0 class C: - __my_hash__ = None + __my_hash__: None = None var: MyHashable = C() # E: Incompatible types in assignment (expression has type "C", variable has type "MyHashable") @@ -289,7 +289,7 @@ class P(Protocol): x = 0 # type: int class C: - x = None + x: None = None x: P = C() # Error! def f(x: P) -> None: pass @@ -2083,7 +2083,7 @@ class B(Protocol): def execute(self, stmt: Any, *args: Any, **kwargs: Any) -> None: ... def cool(self) -> None: ... -def func1(arg: A) -> None: ... +def func1(arg: A) -> None: ... def func2(arg: Optional[A]) -> None: ... x: B @@ -2571,6 +2571,7 @@ hh(None) [case testPartialTypeProtocol] +# flags: --no-local-partial-types from typing import Protocol class Flapper(Protocol): diff --git a/test-data/unit/check-python2.test b/test-data/unit/check-python2.test index fe51cb4b8c1a..d9028a45381b 100644 --- a/test-data/unit/check-python2.test +++ b/test-data/unit/check-python2.test @@ -358,7 +358,7 @@ def foo( pass [case testNoneHasNoBoolInPython2] -none = None +none = None # type: None b = none.__bool__() # E: "None" has no attribute "__bool__" [case testDictWithoutTypeCommentInPython2] diff --git a/test-data/unit/deps.test b/test-data/unit/deps.test index 8c074abc83a2..4383299ff125 100644 --- a/test-data/unit/deps.test +++ b/test-data/unit/deps.test @@ -1,6 +1,6 @@ -- Test cases for generating dependencies between ASTs nodes. -- --- The dependencies are used for fined-grained incremental checking and +-- The dependencies are used for fined-grained incremental checking in -- the daemon mode. -- -- The output of each test case includes the dependency map for whitelisted @@ -600,7 +600,7 @@ class C: class C: pass class A: - x = None + x = None # type: ignore def f(self) -> None: self.x = C() @@ -609,14 +609,14 @@ class A: -> m.A -> m.A.f -> m.A.f - -> , m.A.f, m.C + -> m.A.f, m.C [case testPartialNoneTypeAttributeCrash2] # flags: --strict-optional class C: pass class A: - x = None + x = None # type: ignore def f(self) -> None: self.x = C() @@ -625,7 +625,7 @@ class A: -> m.A -> m.A.f -> m.A.f - -> , m.A.f, m.C + -> m.A.f, m.C [case testRelativeImport] import pkg # Magic package name in test runner