8000 Make bare None a partial type again by ddfisher · Pull Request #3755 · python/mypy · GitHub
[go: up one dir, main page]

Skip to content

Make bare None a partial type again #3755

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations 8000
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Make bare None a partial type again
  • Loading branch information
ddfisher committed Jul 22, 2017
commit 111619ca81aaa849ef89c9db1a7e5d95f8d65a58
12 changes: 2 additions & 10 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -2545,12 +2545,8 @@ def enter_partial_types(self) -> Iterator[None]:
partial_types = self.partial_types.pop()
if not self.current_node_deferred:
for var, context in partial_types.items():
if isinstance(var.type, PartialType) and var.type.type is None:
# None partial type: assume variable is intended to have type None
var.type = NoneTyp()
else:
self.msg.fail(messages.NEED_ANNOTATION_FOR_VAR, context)
var.type = AnyType()
self.msg.fail(messages.NEED_ANNOTATION_FOR_VAR, context)
var.type = AnyType()

def find_partial_types(self, var: Var) -> Optional[Dict[Var, Context]]:
for partial_types in reversed(self.partial_types):
Expand Down Expand Up @@ -3144,10 +3140,6 @@ def is_valid_inferred_type(typ: Type) -> bool:
incompletely defined (i.e. contain UninhabitedType) are invalid.
"""
if is_same_type(typ, NoneTyp()):
# With strict Optional checking, we *may* eventually infer NoneTyp, 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.
return False
return is_valid_inferred_type_component(typ)

Expand Down
1 change: 1 addition & 0 deletions mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -2390,6 +2390,7 @@ def visit_yield_from_expr(self, e: YieldFromExpr, allow_none_return: bool = Fals

if not allow_none_return and isinstance(expr_type, NoneTyp):
self.chk.msg.does_not_return_value(None, e)
return AnyType(implicit=True)
return expr_type

def visit_temp_node(self, e: TempNode) -> Type:
Expand Down
25 changes: 14 additions & 11 deletions test-data/unit/check-inference.test
Original file line number Diff line number Diff line change
Expand Up @@ -246,16 +246,16 @@ class C: pass
[case testInferringLvarTypesInMultiDefWithNoneTypes]
import typing
def f() -> None:
a, b = A(), None
c, d = None, A()
a, b = A(), None # E: Need type annotation for variable
c, d = None, A() # E: Need type annotation for variable

class A: pass
[out]

[case testInferringLvarTypesInNestedTupleAssignmentWithNoneTypes]
import typing
def f() -> None:
a1, (a2, b) = A(), (A(), None)
a1, (a2, b) = A(), (A(), None) # E: Need type annotation for variable

class A: pass
[out]
Expand Down Expand Up @@ -874,7 +874,7 @@ for x in [A()]:
b = x # E: Incompatible types in assignment (expression has type "A", variable has type "B")
a = x

for y in []:
for y in []: # E: Need type annotation for variable
a = y
reveal_type(y) # E: Revealed type is 'builtins.None'

Expand All @@ -896,7 +896,7 @@ for xx, yy, zz in [(A(), B())]: # Fail
pass
for xx, (yy, zz) in [(A(), B())]: # Fail
pass
for xxx, yyy in [(None, None)]:
for xxx, yyy in [(None, None)]: # Needs type annotation
pass

class A: pass
Expand All @@ -909,6 +909,7 @@ main:5: error: Incompatible types in assignment (expression has type "B", variab
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:14: error: Need type annotation for variable

[case testInferenceOfFor3]

Expand All @@ -920,7 +921,7 @@ for x, y in [[A()]]:
a = x
a = y

for e, f in [[]]:
for e, f in [[]]: # E: Need type annotation for variable
reveal_type(e) # E: Revealed type is 'builtins.None'
reveal_type(f) # E: Revealed type is 'builtins.None'

Expand Down Expand Up @@ -1446,7 +1447,7 @@ def f() -> None:
[case testLvarInitializedToNoneWithoutType]
import typing
def f() -> None:
a = None
a = None # E: Need type annotation for variable
a.x() # E: None has no attribute "x"
[out]

Expand Down Expand Up @@ -1494,13 +1495,13 @@ if object():

[case testPartiallyInitializedVariableDoesNotEscapeScope1]
def f() -> None:
x = None
x = None # E: Need type annotation for variable
reveal_type(x) # E: Revealed type is 'builtins.None'
x = 1
[out]

[case testPartiallyInitializedVariableDoesNotEscapeScope2]
x = None
x = None # E: Need type annotation for variable
def f() -> None:
x = None
x = 1
Expand All @@ -1523,8 +1524,8 @@ class A:
self.x = 1
self.x()
[out]
main:6: error: Incompatible types in assignment (expression has type "int", variable has type None)
main:7: error: None not callable
main:3: error: Need type annotation for variable
main:7: error: "int" not callable

[case testGlobalInitializedToNoneSetFromFunction]
a = None
Expand Down Expand Up @@ -1553,6 +1554,7 @@ class A:
pass
[builtins fixtures/for.pyi]
[out]
main:3: error: Need type annotation for variable
main:5: error: None has no attribute "__iter__"

[case testPartialTypeErrorSpecialCase2]
Expand All @@ -1574,6 +1576,7 @@ class A:
pass
[builtins fixtures/for.pyi]
[out]
main:2: error: Need type annotation for variable
main:4: error: None has no attribute "__iter__"


Expand Down
2 changes: 1 addition & 1 deletion test-data/unit/check-modules.test
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ x = 1

[case testAssignToFuncDefViaImport]
from m import * # E: Incompatible import of "x" (imported name has type "int", local name has type "str")
f = None
f = None # E: Need type annotation for variable
x = ''
[file m.py]
def f(): pass
Expand Down
10 changes: 5 additions & 5 deletions test-data/unit/check-optional.test
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
-- Tests for strict Optional behavior

[case testImplicitNoneType]
x = None
x = None # E: Need type annotation for variable
x() # E: None not callable

[case testExplicitNoneType]
Expand Down Expand Up @@ -285,7 +285,7 @@ main:4: error: Incompatible return value type (got "Optional[T]", expected "T")

[case testNoneOrStringIsString]
def f() -> str:
a = None
a = None # type: None
b = ''
return a or b
[out]
Expand All @@ -294,7 +294,7 @@ def f() -> str:
from typing import TypeVar
T = TypeVar('T')
def f(b: T) -> T:
a = None
a = None # type: None
return a or b
[out]

Expand All @@ -305,7 +305,7 @@ def f() -> Generator[None, None, None]:
[out]

[case testNoneAndStringIsNone]
a = None
a = None # type: None
b = "foo"
reveal_type(a and b) # E: Revealed type is 'builtins.None'

Expand Down Expand Up @@ -559,7 +559,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 # type: None
x is not None and x + 42
[builtins fixtures/isinstance.pyi]

Expand Down
6 changes: 4 additions & 2 deletions test-data/unit/check-tuples.test
Original file line number Diff line number Diff line change
Expand Up @@ -633,13 +633,15 @@ for x in t:
[case testForLoopOverEmptyTuple]
import typing
t = ()
for x in t: pass
for x in t: # E: Need type annotation for variable
pass
[builtins fixtures/for.pyi]

[case testForLoopOverNoneValuedTuple]
import typing
t = ()
for x in None, None: pass
for x in None, None: # E: Need type annotation for variable
pass
[builtins fixtures/for.pyi]

[case testForLoopOverTupleAndSubtyping]
Expand Down
0