Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: python/mypy
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.11.0
Choose a base ref
...
head repository: python/mypy
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v1.11.1
Choose a head ref
  • 6 commits
  • 7 files changed
  • 4 contributors

Commits on Jul 27, 2024

  1. Copy the full SHA
    64c1ebf View commit details
  2. Copy the full SHA
    6cf9180 View commit details
  3. Copy the full SHA
    cb44e4d View commit details
  4. Fix PEP 604 isinstance caching (#17563)

    Mentioned by ngnpope
    hauntsaninja committed Jul 27, 2024
    Copy the full SHA
    aec04c7 View commit details
  5. Fix RawExpressionType.accept crash with --cache-fine-grained (#17588

    )
    
    Commit 1072c78 (#17148) converted all
    quoted types into `RawExpressionType`, which raised an `AssertionError`
    when `accept`ing a `TypeTriggersVisitor`.
    
    - Fixes #17574.
    - Fixes #17587.
    
    Signed-off-by: Anders Kaseorg <andersk@mit.edu>
    andersk authored and hauntsaninja committed Jul 27, 2024
    Copy the full SHA
    b3a102e View commit details

Commits on Jul 30, 2024

  1. Bump version to 1.11

    hauntsaninja committed Jul 30, 2024
    Copy the full SHA
    570b90a View commit details
Showing with 77 additions and 10 deletions.
  1. +9 −3 mypy/checkexpr.py
  2. +11 −2 mypy/types.py
  3. +1 −1 mypy/version.py
  4. +17 −3 test-data/unit/check-functions.test
  5. +17 −0 test-data/unit/check-incremental.test
  6. +10 −1 test-data/unit/check-type-aliases.test
  7. +12 −0 test-data/unit/check-typeddict.test
12 changes: 9 additions & 3 deletions mypy/checkexpr.py
Original file line number Diff line number Diff line change
@@ -4341,7 +4341,7 @@ def visit_index_with_type(
elif isinstance(left_type, FunctionLike) and left_type.is_type_obj():
if left_type.type_object().is_enum:
return self.visit_enum_index_expr(left_type.type_object(), e.index, e)
elif left_type.type_object().type_vars:
elif left_type.type_object().type_vars and self.chk.options.python_version >= (3, 9):
return self.named_type("types.GenericAlias")
elif (
left_type.type_object().fullname == "builtins.type"
@@ -4682,7 +4682,7 @@ def visit_type_application(self, tapp: TypeApplication) -> Type:
"""
if isinstance(tapp.expr, RefExpr) and isinstance(tapp.expr.node, TypeAlias):
if tapp.expr.node.python_3_12_type_alias:
return self.named_type("typing.TypeAliasType")
return self.type_alias_type_type()
# Subscription of a (generic) alias in runtime context, expand the alias.
item = instantiate_type_alias(
tapp.expr.node,
@@ -4746,7 +4746,7 @@ class LongName(Generic[T]): ...
y = cast(A, ...)
"""
if alias.python_3_12_type_alias:
return self.named_type("typing.TypeAliasType")
return self.type_alias_type_type()
if isinstance(alias.target, Instance) and alias.target.invalid: # type: ignore[misc]
# An invalid alias, error already has been reported
return AnyType(TypeOfAny.from_error)
@@ -5862,6 +5862,12 @@ def named_type(self, name: str) -> Instance:
"""
return self.chk.named_type(name)

def type_alias_type_type(self) -> Instance:
"""Returns a `typing.TypeAliasType` or `typing_extensions.TypeAliasType`."""
if self.chk.options.python_version >= (3, 12):
return self.named_type("typing.TypeAliasType")
return self.named_type("typing_extensions.TypeAliasType")

def is_valid_var_arg(self, typ: Type) -> bool:
"""Is a type valid as a *args argument?"""
typ = get_proper_type(typ)
13 changes: 11 additions & 2 deletions mypy/types.py
Original file line number Diff line number Diff line change
@@ -2703,6 +2703,8 @@ def simple_name(self) -> str:
return self.base_type_name.replace("builtins.", "")

def accept(self, visitor: TypeVisitor[T]) -> T:
if self.node is not None:
return self.node.accept(visitor)
assert isinstance(visitor, SyntheticTypeVisitor)
ret: T = visitor.visit_raw_expression_type(self)
return ret
@@ -2898,12 +2900,19 @@ def relevant_items(self) -> list[Type]:
return [i for i in self.items if not isinstance(get_proper_type(i), NoneType)]

def serialize(self) -> JsonDict:
return {".class": "UnionType", "items": [t.serialize() for t in self.items]}
return {
".class": "UnionType",
"items": [t.serialize() for t in self.items],
"uses_pep604_syntax": self.uses_pep604_syntax,
}

@classmethod
def deserialize(cls, data: JsonDict) -> UnionType:
assert data[".class"] == "UnionType"
return UnionType([deserialize_type(t) for t in data["items"]])
return UnionType(
[deserialize_type(t) for t in data["items"]],
uses_pep604_syntax=data["uses_pep604_syntax"],
)


class PartialType(ProperType):
2 changes: 1 addition & 1 deletion mypy/version.py
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
# - Release versions have the form "1.2.3".
# - Dev versions have the form "1.2.3+dev" (PLUS sign to conform to PEP 440).
# - Before 1.0 we had the form "0.NNN".
__version__ = "1.11.0"
__version__ = "1.11.1"
base_version = __version__

mypy_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
20 changes: 17 additions & 3 deletions test-data/unit/check-functions.test
Original file line number Diff line number Diff line change
@@ -1779,6 +1779,7 @@ def Arg(x, y): pass
F = Callable[[Arg(int, 'x')], int] # E: Invalid argument constructor "__main__.Arg"

[case testCallableParsingFromExpr]
# flags: --python-version 3.9
from typing import Callable, List
from mypy_extensions import Arg, VarArg, KwArg
import mypy_extensions
@@ -1799,10 +1800,23 @@ L = Callable[[Arg(name='x', type=int)], int] # ok
# I have commented out the following test because I don't know how to expect the "defined here" note part of the error.
# M = Callable[[Arg(gnome='x', type=int)], int] E: Invalid type alias: expression is not a valid type E: Unexpected keyword argument "gnome" for "Arg"
N = Callable[[Arg(name=None, type=int)], int] # ok
O = Callable[[List[Arg(int)]], int] # E: Invalid type alias: expression is not a valid type # E: Value of type "int" is not indexable # E: Type expected within [...]
O = Callable[[List[Arg(int)]], int] # E: Invalid type alias: expression is not a valid type \
# E: Value of type "int" is not indexable \
# E: Type expected within [...]
P = Callable[[mypy_extensions.VarArg(int)], int] # ok
Q = Callable[[Arg(int, type=int)], int] # E: Invalid type alias: expression is not a valid type # E: Value of type "int" is not indexable # E: "Arg" gets multiple values for keyword argument "type"
R = Callable[[Arg(int, 'x', name='y')], int] # E: Invalid type alias: expression is not a valid type # E: Value of type "int" is not indexable # E: "Arg" gets multiple values for keyword argument "name"
Q = Callable[[Arg(int, type=int)], int] # E: Invalid type alias: expression is not a valid type \
# E: Value of type "int" is not indexable \
# E: "Arg" gets multiple values for keyword argument "type"
R = Callable[[Arg(int, 'x', name='y')], int] # E: Invalid type alias: expression is not a valid type \
# E: Value of type "int" is not indexable \
# E: "Arg" gets multiple values for keyword argument "name"







[builtins fixtures/dict.pyi]

[case testCallableParsing]
17 changes: 17 additions & 0 deletions test-data/unit/check-incremental.test
Original file line number Diff line number Diff line change
@@ -6726,3 +6726,20 @@ from typing_extensions import TypeIs
def guard(x: object) -> TypeIs[int]:
pass
[builtins fixtures/tuple.pyi]

[case testStartUsingPEP604Union]
# flags: --python-version 3.10
import a
[file a.py]
import lib

[file a.py.2]
from lib import IntOrStr
assert isinstance(1, IntOrStr)

[file lib.py]
from typing_extensions import TypeAlias

IntOrStr: TypeAlias = int | str
assert isinstance(1, IntOrStr)
[builtins fixtures/type.pyi]
11 changes: 10 additions & 1 deletion test-data/unit/check-type-aliases.test
Original file line number Diff line number Diff line change
@@ -1074,7 +1074,7 @@ x: TestType = 42
y: TestType = 'a'
z: TestType = object() # E: Incompatible types in assignment (expression has type "object", variable has type "Union[int, str]")

reveal_type(TestType) # N: Revealed type is "typing.TypeAliasType"
reveal_type(TestType) # N: Revealed type is "typing_extensions.TypeAliasType"
TestType() # E: "TypeAliasType" not callable

class A:
@@ -1084,6 +1084,15 @@ yc: A.ClassAlias = "" # E: Incompatible types in assignment (expression has typ
[builtins fixtures/tuple.pyi]
[typing fixtures/typing-full.pyi]

[case testTypeAliasTypePython311]
# flags: --python-version 3.11
# Pinning to 3.11, because 3.12 has `TypeAliasType`
from typing_extensions import TypeAliasType

TestType = TypeAliasType("TestType", int)
x: TestType = 1
[builtins fixtures/tuple.pyi]

[case testTypeAliasTypeInvalid]
from typing_extensions import TypeAliasType

12 changes: 12 additions & 0 deletions test-data/unit/check-typeddict.test
Original file line number Diff line number Diff line change
@@ -1442,6 +1442,18 @@ reveal_type(x) # N: Revealed type is "TypedDict('__main__.X', {'a': TypedDict('_
reveal_type(x['a']['b']) # N: Revealed type is "builtins.int"
[builtins fixtures/dict.pyi]

[case testTypedDictForwardReferenceCacheFineGrained]
# flags: --cache-fine-grained
from mypy_extensions import TypedDict
class A(TypedDict):
b: "B"
class B(TypedDict):
c: "C"
class C(TypedDict):
d: "D"
class D:
pass

[case testSelfRecursiveTypedDictInheriting]
from mypy_extensions import TypedDict