Skip to content

Commit

Permalink
Allow inverting --local-partial-types (#18377)
Browse files Browse the repository at this point in the history
Also add it to a bunch of test cases where it is needed
  • Loading branch information
hauntsaninja authored Dec 30, 2024
1 parent 55d4c17 commit b2b32e7
Show file tree
Hide file tree
Showing 12 changed files with 30 additions and 18 deletions.
2 changes: 1 addition & 1 deletion mypy/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1185,7 +1185,7 @@ def add_invertible_flag(
parser.add_argument("--test-env", 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
Expand Down
4 changes: 2 additions & 2 deletions test-data/unit/check-bound.test
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ z = G(B())


[case testBoundVoid]
# flags: --no-strict-optional
# flags: --no-strict-optional --no-local-partial-types
from typing import TypeVar, Generic
T = TypeVar('T', bound=int)
class C(Generic[T]):
Expand Down Expand Up @@ -75,7 +75,7 @@ z: C


[case testBoundHigherOrderWithVoid]
# flags: --no-strict-optional
# flags: --no-strict-optional --no-local-partial-types
from typing import TypeVar, Callable
class A: pass
T = TypeVar('T', bound=A)
Expand Down
2 changes: 1 addition & 1 deletion test-data/unit/check-classes.test
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ A().f = None # E: Cannot assign to a method \
from typing import Protocol

class Base:
__hash__ = None
__hash__: None = None

class Derived(Base):
def __hash__(self) -> int: # E: Signature of "__hash__" incompatible with supertype "Base" \
Expand Down
1 change: 1 addition & 0 deletions test-data/unit/check-columns.test
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ y: Dict[int, int] = {
[builtins fixtures/dict.pyi]

[case testColumnCannotDetermineType]
# flags: --no-local-partial-types
(x) # E:2: Cannot determine type of "x" # E:2: Name "x" is used before definition
x = None

Expand Down
2 changes: 1 addition & 1 deletion test-data/unit/check-custom-plugin.test
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,7 @@ reveal_type(Cls.attr) # N: Revealed type is "builtins.int"
plugins=<ROOT>/test-data/unit/plugins/class_attr_hook.py

[case testClassAttrPluginPartialType]
# flags: --config-file tmp/mypy.ini
# flags: --config-file tmp/mypy.ini --no-local-partial-types

class Cls:
attr = None
Expand Down
2 changes: 1 addition & 1 deletion test-data/unit/check-errorcodes.test
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,7 @@ Foo = TypedDict("Bar", {}) # E: First argument "Bar" to TypedDict() does not ma
[builtins fixtures/dict.pyi]

[case testTruthyBool]
# flags: --enable-error-code truthy-bool
# flags: --enable-error-code truthy-bool --no-local-partial-types
from typing import List, Union, Any

class Foo:
Expand Down
1 change: 1 addition & 0 deletions test-data/unit/check-incremental.test
Original file line number Diff line number Diff line change
Expand Up @@ -6317,6 +6317,7 @@ class C: ...
[out3]

[case testNoCrashOnPartialLambdaInference]
# flags: --no-local-partial-types
import m
[file m.py]
from typing import TypeVar, Callable
Expand Down
20 changes: 11 additions & 9 deletions test-data/unit/check-inference.test
Original file line number Diff line number Diff line change
Expand Up @@ -1728,12 +1728,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
Expand Down Expand Up @@ -1921,6 +1923,7 @@ reveal_type(C().a) # N: Revealed type is "builtins.dict[Any, Any]"
[builtins fixtures/dict.pyi]

[case testInferAttributeInitializedToNoneAndAssignedClassBody]
# flags: --no-local-partial-types
class C:
a = None
def __init__(self) -> None:
Expand Down Expand Up @@ -2069,6 +2072,7 @@ x = 1
[out]

[case testPartiallyInitializedVariableDoesNotEscapeScope2]
# flags: --no-local-partial-types
x = None
def f() -> None:
x = None
Expand Down Expand Up @@ -2114,36 +2118,32 @@ class C:
-- ------------------------

[case testPartialTypeErrorSpecialCase1]
# flags: --no-local-partial-types
# This used to crash.
class A:
x = None
def f(self) -> None:
for a in self.x:
for a in self.x: # E: "None" has no attribute "__iter__" (not iterable)
pass
[builtins fixtures/for.pyi]
[out]
main:5: error: "None" has no attribute "__iter__" (not iterable)

[case testPartialTypeErrorSpecialCase2]
# This used to crash.
class A:
x = []
x = [] # E: Need type annotation for "x" (hint: "x: List[<type>] = ...")
def f(self) -> None:
for a in self.x:
pass
[builtins fixtures/for.pyi]
[out]
main:3: error: Need type annotation for "x" (hint: "x: List[<type>] = ...")

[case testPartialTypeErrorSpecialCase3]
# flags: --no-local-partial-types
class A:
x = None
def f(self) -> None:
for a in A.x:
for a in A.x: # E: "None" has no attribute "__iter__" (not iterable)
pass
[builtins fixtures/for.pyi]
[out]
main:4: error: "None" has no attribute "__iter__" (not iterable)

[case testPartialTypeErrorSpecialCase4]
# This used to crash.
Expand Down Expand Up @@ -2492,6 +2492,7 @@ main:4: error: Unsupported target for indexed assignment ("Type[C[T]]")
main:4: error: Invalid type: try using Literal[0] instead?

[case testNoCrashOnPartialMember]
# flags: --no-local-partial-types
class C:
x = None
def __init__(self) -> None:
Expand All @@ -2512,6 +2513,7 @@ reveal_type(x) # N: Revealed type is "builtins.str"
[out]

[case testNoCrashOnPartialVariable2]
# flags: --no-local-partial-types
from typing import Tuple, TypeVar
T = TypeVar('T', bound=str)

Expand Down
1 change: 1 addition & 0 deletions test-data/unit/check-narrowing.test
Original file line number Diff line number Diff line change
Expand Up @@ -2354,6 +2354,7 @@ def fn_while(arg: T) -> None:
[builtins fixtures/primitives.pyi]

[case testRefinePartialTypeWithinLoop]
# flags: --no-local-partial-types

x = None
for _ in range(2):
Expand Down
7 changes: 5 additions & 2 deletions test-data/unit/check-optional.test
Original file line number Diff line number Diff line change
Expand Up @@ -321,10 +321,13 @@ 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"

c = None
reveal_type(c and b) # N: Revealed type is "None"

[case testNoneMatchesObjectInOverload]
import a
a.f(None)
Expand Down Expand Up @@ -581,7 +584,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]

Expand Down
4 changes: 3 additions & 1 deletion test-data/unit/check-protocols.test
Original file line number Diff line number Diff line change
Expand Up @@ -2906,6 +2906,7 @@ hs(None)


[case testPartialTypeProtocol]
# flags: --no-local-partial-types
from typing import Protocol

class Flapper(Protocol):
Expand Down Expand Up @@ -2944,7 +2945,7 @@ class DataArray(ObjectHashable):


[case testPartialAttributeNoneType]
# flags: --no-strict-optional
# flags: --no-strict-optional --no-local-partial-types
from typing import Optional, Protocol, runtime_checkable

@runtime_checkable
Expand All @@ -2962,6 +2963,7 @@ class MyClass:


[case testPartialAttributeNoneTypeStrictOptional]
# flags: --no-local-partial-types
from typing import Optional, Protocol, runtime_checkable

@runtime_checkable
Expand Down
2 changes: 2 additions & 0 deletions test-data/unit/deps.test
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,7 @@ class C:
<m.f> -> m.C.__init__

[case testPartialNoneTypeAttributeCrash1]
# flags: --no-local-partial-types
class C: pass

class A:
Expand All @@ -612,6 +613,7 @@ class A:
<m.C> -> <m.A.x>, m.A.f, m.C

[case testPartialNoneTypeAttributeCrash2]
# flags: --no-local-partial-types
class C: pass

class A:
Expand Down

0 comments on commit b2b32e7

Please sign in to comment.