Skip to content
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

Allow inverting --local-partial-types #18377

Merged
merged 1 commit into from
Dec 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion mypy/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1184,7 +1184,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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making --local-partial-types invertible will certainly help which it's adoption. E.g. we could also consider adding it to --strict as a first step before making it the default in 2.0.

I do just wonder what change made the test diffs necessary. Adding add_invertible_flag with default=False shouldn't change anything, does it?

It will probably make sense to enable it for all our tests by default, but in that case the test config should probably be changed in the same PR. E.g. it could be added here.

mypy/mypy/test/testcheck.py

Lines 128 to 131 in 55d4c17

options = parse_options(original_program_text, testcase, incremental_step)
options.use_builtins_fixtures = True
options.show_traceback = True

--
Feel free to split that up into a different PR if you like though.

Copy link
Collaborator Author

@hauntsaninja hauntsaninja Dec 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, it wasn't necessary, I was just testing that the PR worked by changing the default locally and proactively added it to test cases where I felt confident it was what we needed

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, changing default in tests is not a bad idea

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
Loading