[med-svn] [Git][python-team/packages/mypy][master] 5 commits: New upstream version 1.11.2

Michael R. Crusoe (@crusoe) gitlab at salsa.debian.org
Mon Aug 26 02:30:23 BST 2024



Michael R. Crusoe pushed to branch master at Debian Python Team / packages / mypy


Commits:
1ba6937c by Michael R. Crusoe at 2024-08-26T09:22:13+09:00
New upstream version 1.11.2
- - - - -
216c479c by Michael R. Crusoe at 2024-08-26T09:22:13+09:00
routine-update: New upstream version

- - - - -
aad0a86e by Michael R. Crusoe at 2024-08-26T09:22:25+09:00
Update upstream source from tag 'upstream/1.11.2'

Update to upstream version '1.11.2'
with Debian dir 95ffd3d3859424db15873e325a2cfcb7ce8cc5fa
- - - - -
1db16bbc by Michael R. Crusoe at 2024-08-26T09:30:38+09:00
d/patches: removed the patches that were cherry-picked from upstream that are now apart of the new release.

- - - - -
7f49c62d by Michael R. Crusoe at 2024-08-26T09:31:14+09:00
routine-update: Ready to upload to unstable

- - - - -


24 changed files:

- PKG-INFO
- debian/changelog
- − debian/patches/0004-Revert-Fix-Literal-strings-containing-pipe-character.patch
- − debian/patches/0005-An-alternative-fix-for-a-union-like-literal-string-1.patch
- − debian/patches/0006-Revert-Fix-RawExpressionType.accept-crash-with-cache.patch
- debian/patches/series
- mypy.egg-info/PKG-INFO
- mypy/fastparse.py
- mypy/semanal.py
- mypy/semanal_typeddict.py
- mypy/server/astmerge.py
- mypy/stubutil.py
- mypy/type_visitor.py
- mypy/typeanal.py
- mypy/types.py
- mypy/typetraverser.py
- mypy/version.py
- mypyc/irbuild/classdef.py
- test-data/unit/check-final.test
- test-data/unit/check-namedtuple.test
- test-data/unit/check-parameter-specification.test
- test-data/unit/check-typeddict.test
- test-data/unit/check-typeguard.test
- test-data/unit/check-typeis.test


Changes:

=====================================
PKG-INFO
=====================================
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: mypy
-Version: 1.11.1
+Version: 1.11.2
 Summary: Optional static typing for Python
 Home-page: https://www.mypy-lang.org/
 Author: Jukka Lehtosalo


=====================================
debian/changelog
=====================================
@@ -1,3 +1,11 @@
+mypy (1.11.2-1) unstable; urgency=medium
+
+  * New upstream version
+  * d/patches: removed the patches that were cherry-picked from upstream
+    that are now apart of the new release.
+
+ -- Michael R. Crusoe <crusoe at debian.org>  Mon, 26 Aug 2024 09:31:14 +0900
+
 mypy (1.11.1-2) unstable; urgency=medium
 
   * Upload to unstable.


=====================================
debian/patches/0004-Revert-Fix-Literal-strings-containing-pipe-character.patch deleted
=====================================
@@ -1,643 +0,0 @@
-From: Ivan Levkivskyi <levkivskyi at gmail.com>
-Date: Sun, 4 Aug 2024 12:50:05 +0100
-Subject: Revert "Fix Literal strings containing pipe characters" (#17638)
-
-Reverts python/mypy#17148
----
- mypy/fastparse.py                                 | 11 +++-
- mypy/semanal.py                                   | 31 ++++------
- mypy/server/astmerge.py                           |  3 +-
- mypy/stubutil.py                                  | 16 ++---
- mypy/type_visitor.py                              |  4 --
- mypy/typeanal.py                                  | 21 ++++---
- mypy/types.py                                     | 75 +++++++++++++----------
- mypy/typetraverser.py                             |  3 +-
- mypyc/irbuild/classdef.py                         |  9 +--
- test-data/unit/check-final.test                   |  2 -
- test-data/unit/check-literal.test                 |  4 --
- test-data/unit/check-namedtuple.test              |  8 +--
- test-data/unit/check-parameter-specification.test | 23 +------
- test-data/unit/check-typeguard.test               | 11 ----
- test-data/unit/check-typeis.test                  | 11 ----
- 15 files changed, 90 insertions(+), 142 deletions(-)
-
-diff --git a/mypy/fastparse.py b/mypy/fastparse.py
-index 01f6ed4..0d93c36 100644
---- a/mypy/fastparse.py
-+++ b/mypy/fastparse.py
-@@ -329,7 +329,14 @@ def parse_type_string(
-     """
-     try:
-         _, node = parse_type_comment(f"({expr_string})", line=line, column=column, errors=None)
--        return RawExpressionType(expr_string, expr_fallback_name, line, column, node=node)
-+        if isinstance(node, UnboundType) and node.original_str_expr is None:
-+            node.original_str_expr = expr_string
-+            node.original_str_fallback = expr_fallback_name
-+            return node
-+        elif isinstance(node, UnionType):
-+            return node
-+        else:
-+            return RawExpressionType(expr_string, expr_fallback_name, line, column)
-     except (SyntaxError, ValueError):
-         # Note: the parser will raise a `ValueError` instead of a SyntaxError if
-         # the string happens to contain things like \x00.
-@@ -1046,8 +1053,6 @@ class ASTConverter:
-             return
-         # Indicate that type should be wrapped in an Optional if arg is initialized to None.
-         optional = isinstance(initializer, NameExpr) and initializer.name == "None"
--        if isinstance(type, RawExpressionType) and type.node is not None:
--            type = type.node
-         if isinstance(type, UnboundType):
-             type.optional = optional
- 
-diff --git a/mypy/semanal.py b/mypy/semanal.py
-index f361490..782985e 100644
---- a/mypy/semanal.py
-+++ b/mypy/semanal.py
-@@ -3437,10 +3437,10 @@ class SemanticAnalyzer(
-     def analyze_lvalues(self, s: AssignmentStmt) -> None:
-         # We cannot use s.type, because analyze_simple_literal_type() will set it.
-         explicit = s.unanalyzed_type is not None
--        final_type = self.unwrap_final_type(s.unanalyzed_type)
--        if final_type is not None:
-+        if self.is_final_type(s.unanalyzed_type):
-             # We need to exclude bare Final.
--            if not final_type.args:
-+            assert isinstance(s.unanalyzed_type, UnboundType)
-+            if not s.unanalyzed_type.args:
-                 explicit = False
- 
-         if s.rvalue:
-@@ -3506,19 +3506,19 @@ class SemanticAnalyzer(
- 
-         Returns True if Final[...] was present.
-         """
--        final_type = self.unwrap_final_type(s.unanalyzed_type)
--        if final_type is None:
-+        if not s.unanalyzed_type or not self.is_final_type(s.unanalyzed_type):
-             return False
--        if len(final_type.args) > 1:
--            self.fail("Final[...] takes at most one type argument", final_type)
-+        assert isinstance(s.unanalyzed_type, UnboundType)
-+        if len(s.unanalyzed_type.args) > 1:
-+            self.fail("Final[...] takes at most one type argument", s.unanalyzed_type)
-         invalid_bare_final = False
--        if not final_type.args:
-+        if not s.unanalyzed_type.args:
-             s.type = None
-             if isinstance(s.rvalue, TempNode) and s.rvalue.no_rhs:
-                 invalid_bare_final = True
-                 self.fail("Type in Final[...] can only be omitted if there is an initializer", s)
-         else:
--            s.type = final_type.args[0]
-+            s.type = s.unanalyzed_type.args[0]
- 
-         if s.type is not None and self.is_classvar(s.type):
-             self.fail("Variable should not be annotated with both ClassVar and Final", s)
-@@ -4937,18 +4937,13 @@ class SemanticAnalyzer(
-             return False
-         return sym.node.fullname == "typing.ClassVar"
- 
--    def unwrap_final_type(self, typ: Type | None) -> UnboundType | None:
--        if typ is None:
--            return None
--        typ = typ.resolve_string_annotation()
-+    def is_final_type(self, typ: Type | None) -> bool:
-         if not isinstance(typ, UnboundType):
--            return None
-+            return False
-         sym = self.lookup_qualified(typ.name, typ)
-         if not sym or not sym.node:
--            return None
--        if sym.node.fullname in FINAL_TYPE_NAMES:
--            return typ
--        return None
-+            return False
-+        return sym.node.fullname in FINAL_TYPE_NAMES
- 
-     def fail_invalid_classvar(self, context: Context) -> None:
-         self.fail(message_registry.CLASS_VAR_OUTSIDE_OF_CLASS, context)
-diff --git a/mypy/server/astmerge.py b/mypy/server/astmerge.py
-index e6648fb..174c292 100644
---- a/mypy/server/astmerge.py
-+++ b/mypy/server/astmerge.py
-@@ -507,8 +507,7 @@ class TypeReplaceVisitor(SyntheticTypeVisitor[None]):
-         typ.fallback.accept(self)
- 
-     def visit_raw_expression_type(self, t: RawExpressionType) -> None:
--        if t.node is not None:
--            t.node.accept(self)
-+        pass
- 
-     def visit_literal_type(self, typ: LiteralType) -> None:
-         typ.fallback.accept(self)
-diff --git a/mypy/stubutil.py b/mypy/stubutil.py
-index 2f2db0d..04b36e1 100644
---- a/mypy/stubutil.py
-+++ b/mypy/stubutil.py
-@@ -17,16 +17,7 @@ import mypy.options
- from mypy.modulefinder import ModuleNotFoundReason
- from mypy.moduleinspect import InspectError, ModuleInspect
- from mypy.stubdoc import ArgSig, FunctionSig
--from mypy.types import (
--    AnyType,
--    NoneType,
--    RawExpressionType,
--    Type,
--    TypeList,
--    TypeStrVisitor,
--    UnboundType,
--    UnionType,
--)
-+from mypy.types import AnyType, NoneType, Type, TypeList, TypeStrVisitor, UnboundType, UnionType
- 
- # Modules that may fail when imported, or that may have side effects (fully qualified).
- NOT_IMPORTABLE_MODULES = ()
-@@ -302,11 +293,12 @@ class AnnotationPrinter(TypeStrVisitor):
-         The main difference from list_str is the preservation of quotes for string
-         arguments
-         """
-+        types = ["builtins.bytes", "builtins.str"]
-         res = []
-         for arg in args:
-             arg_str = arg.accept(self)
--            if isinstance(arg, RawExpressionType):
--                res.append(repr(arg.literal_value))
-+            if isinstance(arg, UnboundType) and arg.original_str_fallback in types:
-+                res.append(f"'{arg_str}'")
-             else:
-                 res.append(arg_str)
-         return ", ".join(res)
-diff --git a/mypy/type_visitor.py b/mypy/type_visitor.py
-index e685c49..59e13d1 100644
---- a/mypy/type_visitor.py
-+++ b/mypy/type_visitor.py
-@@ -382,8 +382,6 @@ class TypeQuery(SyntheticTypeVisitor[T]):
-         return self.query_types(t.items.values())
- 
-     def visit_raw_expression_type(self, t: RawExpressionType) -> T:
--        if t.node is not None:
--            return t.node.accept(self)
-         return self.strategy([])
- 
-     def visit_literal_type(self, t: LiteralType) -> T:
-@@ -524,8 +522,6 @@ class BoolTypeQuery(SyntheticTypeVisitor[bool]):
-         return self.query_types(list(t.items.values()))
- 
-     def visit_raw_expression_type(self, t: RawExpressionType) -> bool:
--        if t.node is not None:
--            return t.node.accept(self)
-         return self.default
- 
-     def visit_literal_type(self, t: LiteralType) -> bool:
-diff --git a/mypy/typeanal.py b/mypy/typeanal.py
-index 6651af7..5613e01 100644
---- a/mypy/typeanal.py
-+++ b/mypy/typeanal.py
-@@ -1107,7 +1107,6 @@ class TypeAnalyser(SyntheticTypeVisitor[Type], TypeAnalyzerPluginInterface):
-         return ret
- 
-     def anal_type_guard(self, t: Type) -> Type | None:
--        t = t.resolve_string_annotation()
-         if isinstance(t, UnboundType):
-             sym = self.lookup_qualified(t.name, t)
-             if sym is not None and sym.node is not None:
-@@ -1126,7 +1125,6 @@ class TypeAnalyser(SyntheticTypeVisitor[Type], TypeAnalyzerPluginInterface):
-         return None
- 
-     def anal_type_is(self, t: Type) -> Type | None:
--        t = t.resolve_string_annotation()
-         if isinstance(t, UnboundType):
-             sym = self.lookup_qualified(t.name, t)
-             if sym is not None and sym.node is not None:
-@@ -1144,7 +1142,6 @@ class TypeAnalyser(SyntheticTypeVisitor[Type], TypeAnalyzerPluginInterface):
- 
-     def anal_star_arg_type(self, t: Type, kind: ArgKind, nested: bool) -> Type:
-         """Analyze signature argument type for *args and **kwargs argument."""
--        t = t.resolve_string_annotation()
-         if isinstance(t, UnboundType) and t.name and "." in t.name and not t.args:
-             components = t.name.split(".")
-             tvar_name = ".".join(components[:-1])
-@@ -1235,8 +1232,6 @@ class TypeAnalyser(SyntheticTypeVisitor[Type], TypeAnalyzerPluginInterface):
-         # make signatures like "foo(x: 20) -> None" legal, we can change
-         # this method so it generates and returns an actual LiteralType
-         # instead.
--        if t.node is not None:
--            return t.node.accept(self)
- 
-         if self.report_invalid_types:
-             if t.base_type_name in ("builtins.int", "builtins.bool"):
-@@ -1499,7 +1494,6 @@ class TypeAnalyser(SyntheticTypeVisitor[Type], TypeAnalyzerPluginInterface):
-         invalid_unpacks: list[Type] = []
-         second_unpack_last = False
-         for i, arg in enumerate(arglist.items):
--            arg = arg.resolve_string_annotation()
-             if isinstance(arg, CallableArgument):
-                 args.append(arg.typ)
-                 names.append(arg.name)
-@@ -1580,6 +1574,18 @@ class TypeAnalyser(SyntheticTypeVisitor[Type], TypeAnalyzerPluginInterface):
-         return UnionType.make_union(output, line=t.line)
- 
-     def analyze_literal_param(self, idx: int, arg: Type, ctx: Context) -> list[Type] | None:
-+        # This UnboundType was originally defined as a string.
-+        if isinstance(arg, UnboundType) and arg.original_str_expr is not None:
-+            assert arg.original_str_fallback is not None
-+            return [
-+                LiteralType(
-+                    value=arg.original_str_expr,
-+                    fallback=self.named_type(arg.original_str_fallback),
-+                    line=arg.line,
-+                    column=arg.column,
-+                )
-+            ]
-+
-         # If arg is an UnboundType that was *not* originally defined as
-         # a string, try expanding it in case it's a type alias or something.
-         if isinstance(arg, UnboundType):
-@@ -2564,8 +2570,7 @@ class FindTypeVarVisitor(SyntheticTypeVisitor[None]):
-         self.process_types(list(t.items.values()))
- 
-     def visit_raw_expression_type(self, t: RawExpressionType) -> None:
--        if t.node is not None:
--            t.node.accept(self)
-+        pass
- 
-     def visit_literal_type(self, t: LiteralType) -> None:
-         pass
-diff --git a/mypy/types.py b/mypy/types.py
-index 3dce98b..7103e53 100644
---- a/mypy/types.py
-+++ b/mypy/types.py
-@@ -271,9 +271,6 @@ class Type(mypy.nodes.Context):
-     def can_be_false_default(self) -> bool:
-         return True
- 
--    def resolve_string_annotation(self) -> Type:
--        return self
--
-     def accept(self, visitor: TypeVisitor[T]) -> T:
-         raise RuntimeError("Not implemented", type(self))
- 
-@@ -906,7 +903,14 @@ class TypeVarTupleType(TypeVarLikeType):
- class UnboundType(ProperType):
-     """Instance type that has not been bound during semantic analysis."""
- 
--    __slots__ = ("name", "args", "optional", "empty_tuple_index")
-+    __slots__ = (
-+        "name",
-+        "args",
-+        "optional",
-+        "empty_tuple_index",
-+        "original_str_expr",
-+        "original_str_fallback",
-+    )
- 
-     def __init__(
-         self,
-@@ -916,6 +920,8 @@ class UnboundType(ProperType):
-         column: int = -1,
-         optional: bool = False,
-         empty_tuple_index: bool = False,
-+        original_str_expr: str | None = None,
-+        original_str_fallback: str | None = None,
-     ) -> None:
-         super().__init__(line, column)
-         if not args:
-@@ -927,6 +933,21 @@ class UnboundType(ProperType):
-         self.optional = optional
-         # Special case for X[()]
-         self.empty_tuple_index = empty_tuple_index
-+        # If this UnboundType was originally defined as a str or bytes, keep track of
-+        # the original contents of that string-like thing. This way, if this UnboundExpr
-+        # ever shows up inside of a LiteralType, we can determine whether that
-+        # Literal[...] is valid or not. E.g. Literal[foo] is most likely invalid
-+        # (unless 'foo' is an alias for another literal or something) and
-+        # Literal["foo"] most likely is.
-+        #
-+        # We keep track of the entire string instead of just using a boolean flag
-+        # so we can distinguish between things like Literal["foo"] vs
-+        # Literal["    foo   "].
-+        #
-+        # We also keep track of what the original base fallback type was supposed to be
-+        # so we don't have to try and recompute it later
-+        self.original_str_expr = original_str_expr
-+        self.original_str_fallback = original_str_fallback
- 
-     def copy_modified(self, args: Bogus[Sequence[Type] | None] = _dummy) -> UnboundType:
-         if args is _dummy:
-@@ -938,19 +959,25 @@ class UnboundType(ProperType):
-             column=self.column,
-             optional=self.optional,
-             empty_tuple_index=self.empty_tuple_index,
-+            original_str_expr=self.original_str_expr,
-+            original_str_fallback=self.original_str_fallback,
-         )
- 
-     def accept(self, visitor: TypeVisitor[T]) -> T:
-         return visitor.visit_unbound_type(self)
- 
-     def __hash__(self) -> int:
--        return hash((self.name, self.optional, tuple(self.args)))
-+        return hash((self.name, self.optional, tuple(self.args), self.original_str_expr))
- 
-     def __eq__(self, other: object) -> bool:
-         if not isinstance(other, UnboundType):
-             return NotImplemented
-         return (
--            self.name == other.name and self.optional == other.optional and self.args == other.args
-+            self.name == other.name
-+            and self.optional == other.optional
-+            and self.args == other.args
-+            and self.original_str_expr == other.original_str_expr
-+            and self.original_str_fallback == other.original_str_fallback
-         )
- 
-     def serialize(self) -> JsonDict:
-@@ -958,12 +985,19 @@ class UnboundType(ProperType):
-             ".class": "UnboundType",
-             "name": self.name,
-             "args": [a.serialize() for a in self.args],
-+            "expr": self.original_str_expr,
-+            "expr_fallback": self.original_str_fallback,
-         }
- 
-     @classmethod
-     def deserialize(cls, data: JsonDict) -> UnboundType:
-         assert data[".class"] == "UnboundType"
--        return UnboundType(data["name"], [deserialize_type(a) for a in data["args"]])
-+        return UnboundType(
-+            data["name"],
-+            [deserialize_type(a) for a in data["args"]],
-+            original_str_expr=data["expr"],
-+            original_str_fallback=data["expr_fallback"],
-+        )
- 
- 
- class CallableArgument(ProperType):
-@@ -2644,7 +2678,7 @@ class RawExpressionType(ProperType):
- 
-     This synthetic type is only used at the beginning stages of semantic analysis
-     and should be completely removing during the process for mapping UnboundTypes to
--    actual types: we turn it into its "node" argument, a LiteralType, or an AnyType.
-+    actual types: we either turn it into a LiteralType or an AnyType.
- 
-     For example, suppose `Foo[1]` is initially represented as the following:
- 
-@@ -2682,7 +2716,7 @@ class RawExpressionType(ProperType):
-         )
-     """
- 
--    __slots__ = ("literal_value", "base_type_name", "note", "node")
-+    __slots__ = ("literal_value", "base_type_name", "note")
- 
-     def __init__(
-         self,
-@@ -2691,13 +2725,11 @@ class RawExpressionType(ProperType):
-         line: int = -1,
-         column: int = -1,
-         note: str | None = None,
--        node: Type | None = None,
-     ) -> None:
-         super().__init__(line, column)
-         self.literal_value = literal_value
-         self.base_type_name = base_type_name
-         self.note = note
--        self.node = node
- 
-     def simple_name(self) -> str:
-         return self.base_type_name.replace("builtins.", "")
-@@ -2709,21 +2741,6 @@ class RawExpressionType(ProperType):
-         ret: T = visitor.visit_raw_expression_type(self)
-         return ret
- 
--    def copy_modified(self, node: Type | None) -> RawExpressionType:
--        return RawExpressionType(
--            literal_value=self.literal_value,
--            base_type_name=self.base_type_name,
--            line=self.line,
--            column=self.column,
--            note=self.note,
--            node=node,
--        )
--
--    def resolve_string_annotation(self) -> Type:
--        if self.node is not None:
--            return self.node.resolve_string_annotation()
--        return self
--
-     def serialize(self) -> JsonDict:
-         assert False, "Synthetic types don't serialize"
- 
-@@ -2735,7 +2752,6 @@ class RawExpressionType(ProperType):
-             return (
-                 self.base_type_name == other.base_type_name
-                 and self.literal_value == other.literal_value
--                and self.node == other.node
-             )
-         else:
-             return NotImplemented
-@@ -3411,8 +3427,6 @@ class TypeStrVisitor(SyntheticTypeVisitor[str]):
-         return f"TypedDict({prefix}{s})"
- 
-     def visit_raw_expression_type(self, t: RawExpressionType) -> str:
--        if t.node is not None:
--            return t.node.accept(self)
-         return repr(t.literal_value)
- 
-     def visit_literal_type(self, t: LiteralType) -> str:
-@@ -3476,9 +3490,6 @@ class TrivialSyntheticTypeTranslator(TypeTranslator, SyntheticTypeVisitor[Type])
-         return t
- 
-     def visit_raw_expression_type(self, t: RawExpressionType) -> Type:
--        if t.node is not None:
--            node = t.node.accept(self)
--            return t.copy_modified(node=node)
-         return t
- 
-     def visit_type_list(self, t: TypeList) -> Type:
-diff --git a/mypy/typetraverser.py b/mypy/typetraverser.py
-index 4d740a8..a28bbf4 100644
---- a/mypy/typetraverser.py
-+++ b/mypy/typetraverser.py
-@@ -130,8 +130,7 @@ class TypeTraverserVisitor(SyntheticTypeVisitor[None]):
-         pass
- 
-     def visit_raw_expression_type(self, t: RawExpressionType) -> None:
--        if t.node is not None:
--            t.node.accept(self)
-+        pass
- 
-     def visit_type_alias_type(self, t: TypeAliasType) -> None:
-         # TODO: sometimes we want to traverse target as well
-diff --git a/mypyc/irbuild/classdef.py b/mypyc/irbuild/classdef.py
-index 2152da0..7e0a842 100644
---- a/mypyc/irbuild/classdef.py
-+++ b/mypyc/irbuild/classdef.py
-@@ -26,7 +26,7 @@ from mypy.nodes import (
-     TypeParam,
-     is_class_var,
- )
--from mypy.types import ENUM_REMOVED_PROPS, Instance, RawExpressionType, get_proper_type
-+from mypy.types import ENUM_REMOVED_PROPS, Instance, UnboundType, get_proper_type
- from mypyc.common import PROPSET_PREFIX
- from mypyc.ir.class_ir import ClassIR, NonExtClassInfo
- from mypyc.ir.func_ir import FuncDecl, FuncSignature
-@@ -640,15 +640,16 @@ def add_non_ext_class_attr_ann(
-     if typ is None:
-         # FIXME: if get_type_info is not provided, don't fall back to stmt.type?
-         ann_type = get_proper_type(stmt.type)
--        if isinstance(stmt.unanalyzed_type, RawExpressionType) and isinstance(
--            stmt.unanalyzed_type.literal_value, str
-+        if (
-+            isinstance(stmt.unanalyzed_type, UnboundType)
-+            and stmt.unanalyzed_type.original_str_expr is not None
-         ):
-             # Annotation is a forward reference, so don't attempt to load the actual
-             # type and load the string instead.
-             #
-             # TODO: is it possible to determine whether a non-string annotation is
-             # actually a forward reference due to the __annotations__ future?
--            typ = builder.load_str(stmt.unanalyzed_type.literal_value)
-+            typ = builder.load_str(stmt.unanalyzed_type.original_str_expr)
-         elif isinstance(ann_type, Instance):
-             typ = load_type(builder, ann_type.type, stmt.line)
-         else:
-diff --git a/test-data/unit/check-final.test b/test-data/unit/check-final.test
-index dadf76a..7631831 100644
---- a/test-data/unit/check-final.test
-+++ b/test-data/unit/check-final.test
-@@ -6,13 +6,11 @@
- [case testFinalDefiningModuleVar]
- from typing import Final
- 
--w: 'Final' = int()
- x: Final = int()
- y: Final[float] = int()
- z: Final[int] = int()
- bad: Final[str] = int()  # E: Incompatible types in assignment (expression has type "int", variable has type "str")
- 
--reveal_type(w)  # N: Revealed type is "builtins.int"
- reveal_type(x)  # N: Revealed type is "builtins.int"
- reveal_type(y)  # N: Revealed type is "builtins.float"
- reveal_type(z)  # N: Revealed type is "builtins.int"
-diff --git a/test-data/unit/check-literal.test b/test-data/unit/check-literal.test
-index 8f8aaf6..2f5fa1b 100644
---- a/test-data/unit/check-literal.test
-+++ b/test-data/unit/check-literal.test
-@@ -12,12 +12,8 @@ reveal_type(g1)  # N: Revealed type is "def (x: Literal['A['])"
- 
- def f2(x: 'A B') -> None: pass  # E: Invalid type comment or annotation
- def g2(x: Literal['A B']) -> None: pass
--def h2(x: 'A|int') -> None: pass  # E: Name "A" is not defined
--def i2(x: Literal['A|B']) -> None: pass
- reveal_type(f2)  # N: Revealed type is "def (x: Any)"
- reveal_type(g2)  # N: Revealed type is "def (x: Literal['A B'])"
--reveal_type(h2)  # N: Revealed type is "def (x: Union[Any, builtins.int])"
--reveal_type(i2)  # N: Revealed type is "def (x: Literal['A|B'])"
- [builtins fixtures/tuple.pyi]
- [out]
- 
-diff --git a/test-data/unit/check-namedtuple.test b/test-data/unit/check-namedtuple.test
-index e9d1567..ade2dde 100644
---- a/test-data/unit/check-namedtuple.test
-+++ b/test-data/unit/check-namedtuple.test
-@@ -824,20 +824,14 @@ class Fraction(Real):
- [builtins fixtures/tuple.pyi]
- 
- [case testForwardReferenceInNamedTuple]
--from typing import List, NamedTuple
-+from typing import NamedTuple
- 
- class A(NamedTuple):
-     b: 'B'
-     x: int
--    y: List['B']
- 
- class B:
-     pass
--
--def f(a: A):
--    reveal_type(a.b)  # N: Revealed type is "__main__.B"
--    reveal_type(a.x)  # N: Revealed type is "builtins.int"
--    reveal_type(a.y)  # N: Revealed type is "builtins.list[__main__.B]"
- [builtins fixtures/tuple.pyi]
- 
- [case testTypeNamedTupleClassmethod]
-diff --git a/test-data/unit/check-parameter-specification.test b/test-data/unit/check-parameter-specification.test
-index e6d8cec..c2afb61 100644
---- a/test-data/unit/check-parameter-specification.test
-+++ b/test-data/unit/check-parameter-specification.test
-@@ -1193,28 +1193,7 @@ def func(callback: Callable[P, str]) -> Callable[P, str]:
-     return inner
- [builtins fixtures/paramspec.pyi]
- 
--[case testParamSpecArgsAndKwargsStringified]
--from typing import Callable
--from typing_extensions import ParamSpec
--
--P1 = ParamSpec("P1")
--
--def func(callback: Callable[P1, str]) -> Callable[P1, str]:
--    def inner(*args: "P1.args", **kwargs: "P1.kwargs") -> str:
--        return "foo"
--    return inner
--
-- at func
--def outer(a: int) -> str:
--    return ""
--
--outer(1)  # OK
--outer("x")  # E: Argument 1 to "outer" has incompatible type "str"; expected "int"
--outer(a=1)  # OK
--outer(b=1)  # E: Unexpected keyword argument "b" for "outer"
--[builtins fixtures/paramspec.pyi]
--
--[case testParamSpecArgsAndKwargsMismatch]
-+[case testParamSpecArgsAndKwargsMissmatch]
- from typing import Callable
- from typing_extensions import ParamSpec
- 
-diff --git a/test-data/unit/check-typeguard.test b/test-data/unit/check-typeguard.test
-index e1b7a86..27b8855 100644
---- a/test-data/unit/check-typeguard.test
-+++ b/test-data/unit/check-typeguard.test
-@@ -9,17 +9,6 @@ def main(a: object) -> None:
-         reveal_type(a)  # N: Revealed type is "builtins.object"
- [builtins fixtures/tuple.pyi]
- 
--[case testTypeGuardStringified]
--from typing_extensions import TypeGuard
--class Point: pass
--def is_point(a: object) -> "TypeGuard[Point]": pass
--def main(a: object) -> None:
--    if is_point(a):
--        reveal_type(a)  # N: Revealed type is "__main__.Point"
--    else:
--        reveal_type(a)  # N: Revealed type is "builtins.object"
--[builtins fixtures/tuple.pyi]
--
- [case testTypeGuardTypeArgsNone]
- from typing_extensions import TypeGuard
- def foo(a: object) -> TypeGuard:  # E: TypeGuard must have exactly one type argument
-diff --git a/test-data/unit/check-typeis.test b/test-data/unit/check-typeis.test
-index 83467d5..6b96845 100644
---- a/test-data/unit/check-typeis.test
-+++ b/test-data/unit/check-typeis.test
-@@ -9,17 +9,6 @@ def main(a: object) -> None:
-         reveal_type(a)  # N: Revealed type is "builtins.object"
- [builtins fixtures/tuple.pyi]
- 
--[case testTypeIsStringified]
--from typing_extensions import TypeIs
--class Point: pass
--def is_point(a: object) -> "TypeIs[Point]": pass
--def main(a: object) -> None:
--    if is_point(a):
--        reveal_type(a)  # N: Revealed type is "__main__.Point"
--    else:
--        reveal_type(a)  # N: Revealed type is "builtins.object"
--[builtins fixtures/tuple.pyi]
--
- [case testTypeIsElif]
- from typing_extensions import TypeIs
- from typing import Union


=====================================
debian/patches/0005-An-alternative-fix-for-a-union-like-literal-string-1.patch deleted
=====================================
@@ -1,119 +0,0 @@
-From: Ivan Levkivskyi <levkivskyi at gmail.com>
-Date: Sun, 11 Aug 2024 22:26:32 +0100
-Subject: An alternative fix for a union-like literal string (#17639)
-
-It is unfortunate to add two extra slots to a common type (and I guess
-this is why it was rejected in the original PR), but all other
-alternatives I tried are hacky and/or dangerous. So, this is a price to
-pay for introducing a new type syntax.
-
----------
-
-Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
----
- mypy/fastparse.py                 |  4 +---
- mypy/typeanal.py                  |  6 +++++-
- mypy/types.py                     | 16 +++++++++++++---
- test-data/unit/check-literal.test |  4 ++++
- 4 files changed, 23 insertions(+), 7 deletions(-)
-
-diff --git a/mypy/fastparse.py b/mypy/fastparse.py
-index 0d93c36..c78a24e 100644
---- a/mypy/fastparse.py
-+++ b/mypy/fastparse.py
-@@ -329,12 +329,10 @@ def parse_type_string(
-     """
-     try:
-         _, node = parse_type_comment(f"({expr_string})", line=line, column=column, errors=None)
--        if isinstance(node, UnboundType) and node.original_str_expr is None:
-+        if isinstance(node, (UnboundType, UnionType)) and node.original_str_expr is None:
-             node.original_str_expr = expr_string
-             node.original_str_fallback = expr_fallback_name
-             return node
--        elif isinstance(node, UnionType):
--            return node
-         else:
-             return RawExpressionType(expr_string, expr_fallback_name, line, column)
-     except (SyntaxError, ValueError):
-diff --git a/mypy/typeanal.py b/mypy/typeanal.py
-index 5613e01..ee6cd87 100644
---- a/mypy/typeanal.py
-+++ b/mypy/typeanal.py
-@@ -1575,7 +1575,11 @@ class TypeAnalyser(SyntheticTypeVisitor[Type], TypeAnalyzerPluginInterface):
- 
-     def analyze_literal_param(self, idx: int, arg: Type, ctx: Context) -> list[Type] | None:
-         # This UnboundType was originally defined as a string.
--        if isinstance(arg, UnboundType) and arg.original_str_expr is not None:
-+        if (
-+            isinstance(arg, ProperType)
-+            and isinstance(arg, (UnboundType, UnionType))
-+            and arg.original_str_expr is not None
-+        ):
-             assert arg.original_str_fallback is not None
-             return [
-                 LiteralType(
-diff --git a/mypy/types.py b/mypy/types.py
-index 7103e53..2881717 100644
---- a/mypy/types.py
-+++ b/mypy/types.py
-@@ -914,7 +914,7 @@ class UnboundType(ProperType):
- 
-     def __init__(
-         self,
--        name: str | None,
-+        name: str,
-         args: Sequence[Type] | None = None,
-         line: int = -1,
-         column: int = -1,
-@@ -926,7 +926,6 @@ class UnboundType(ProperType):
-         super().__init__(line, column)
-         if not args:
-             args = []
--        assert name is not None
-         self.name = name
-         self.args = tuple(args)
-         # Should this type be wrapped in an Optional?
-@@ -2849,7 +2848,13 @@ class LiteralType(ProperType):
- class UnionType(ProperType):
-     """The union type Union[T1, ..., Tn] (at least one type argument)."""
- 
--    __slots__ = ("items", "is_evaluated", "uses_pep604_syntax")
-+    __slots__ = (
-+        "items",
-+        "is_evaluated",
-+        "uses_pep604_syntax",
-+        "original_str_expr",
-+        "original_str_fallback",
-+    )
- 
-     def __init__(
-         self,
-@@ -2868,6 +2873,11 @@ class UnionType(ProperType):
-         self.is_evaluated = is_evaluated
-         # uses_pep604_syntax is True if Union uses OR syntax (X | Y)
-         self.uses_pep604_syntax = uses_pep604_syntax
-+        # The meaning of these two is the same as for UnboundType. A UnionType can be
-+        # return by type parser from a string "A|B", and we need to be able to fall back
-+        # to plain string, when such a string appears inside a Literal[...].
-+        self.original_str_expr: str | None = None
-+        self.original_str_fallback: str | None = None
- 
-     def can_be_true_default(self) -> bool:
-         return any(item.can_be_true for item in self.items)
-diff --git a/test-data/unit/check-literal.test b/test-data/unit/check-literal.test
-index 2f5fa1b..8f8aaf6 100644
---- a/test-data/unit/check-literal.test
-+++ b/test-data/unit/check-literal.test
-@@ -12,8 +12,12 @@ reveal_type(g1)  # N: Revealed type is "def (x: Literal['A['])"
- 
- def f2(x: 'A B') -> None: pass  # E: Invalid type comment or annotation
- def g2(x: Literal['A B']) -> None: pass
-+def h2(x: 'A|int') -> None: pass  # E: Name "A" is not defined
-+def i2(x: Literal['A|B']) -> None: pass
- reveal_type(f2)  # N: Revealed type is "def (x: Any)"
- reveal_type(g2)  # N: Revealed type is "def (x: Literal['A B'])"
-+reveal_type(h2)  # N: Revealed type is "def (x: Union[Any, builtins.int])"
-+reveal_type(i2)  # N: Revealed type is "def (x: Literal['A|B'])"
- [builtins fixtures/tuple.pyi]
- [out]
- 


=====================================
debian/patches/0006-Revert-Fix-RawExpressionType.accept-crash-with-cache.patch deleted
=====================================
@@ -1,47 +0,0 @@
-From: Ivan Levkivskyi <levkivskyi at gmail.com>
-Date: Sun, 4 Aug 2024 12:22:29 +0100
-Subject: Revert "Fix `RawExpressionType.accept` crash with
- `--cache-fine-grained`" (#17637)
-
-Reverts python/mypy#17588
----
- mypy/types.py                       |  2 --
- test-data/unit/check-typeddict.test | 12 ------------
- 2 files changed, 14 deletions(-)
-
-diff --git a/mypy/types.py b/mypy/types.py
-index 2881717..6db6862 100644
---- a/mypy/types.py
-+++ b/mypy/types.py
-@@ -2734,8 +2734,6 @@ class RawExpressionType(ProperType):
-         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
-diff --git a/test-data/unit/check-typeddict.test b/test-data/unit/check-typeddict.test
-index a6a89f1..d35ec8d 100644
---- a/test-data/unit/check-typeddict.test
-+++ b/test-data/unit/check-typeddict.test
-@@ -1442,18 +1442,6 @@ 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
- 


=====================================
debian/patches/series
=====================================
@@ -1,6 +1,3 @@
 hint-typeshed-package
 verbose
 intersphinx
-0004-Revert-Fix-Literal-strings-containing-pipe-character.patch
-0005-An-alternative-fix-for-a-union-like-literal-string-1.patch
-0006-Revert-Fix-RawExpressionType.accept-crash-with-cache.patch


=====================================
mypy.egg-info/PKG-INFO
=====================================
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: mypy
-Version: 1.11.1
+Version: 1.11.2
 Summary: Optional static typing for Python
 Home-page: https://www.mypy-lang.org/
 Author: Jukka Lehtosalo


=====================================
mypy/fastparse.py
=====================================
@@ -329,7 +329,12 @@ def parse_type_string(
     """
     try:
         _, node = parse_type_comment(f"({expr_string})", line=line, column=column, errors=None)
-        return RawExpressionType(expr_string, expr_fallback_name, line, column, node=node)
+        if isinstance(node, (UnboundType, UnionType)) and node.original_str_expr is None:
+            node.original_str_expr = expr_string
+            node.original_str_fallback = expr_fallback_name
+            return node
+        else:
+            return RawExpressionType(expr_string, expr_fallback_name, line, column)
     except (SyntaxError, ValueError):
         # Note: the parser will raise a `ValueError` instead of a SyntaxError if
         # the string happens to contain things like \x00.
@@ -1046,8 +1051,6 @@ class ASTConverter:
             return
         # Indicate that type should be wrapped in an Optional if arg is initialized to None.
         optional = isinstance(initializer, NameExpr) and initializer.name == "None"
-        if isinstance(type, RawExpressionType) and type.node is not None:
-            type = type.node
         if isinstance(type, UnboundType):
             type.optional = optional
 


=====================================
mypy/semanal.py
=====================================
@@ -3437,10 +3437,10 @@ class SemanticAnalyzer(
     def analyze_lvalues(self, s: AssignmentStmt) -> None:
         # We cannot use s.type, because analyze_simple_literal_type() will set it.
         explicit = s.unanalyzed_type is not None
-        final_type = self.unwrap_final_type(s.unanalyzed_type)
-        if final_type is not None:
+        if self.is_final_type(s.unanalyzed_type):
             # We need to exclude bare Final.
-            if not final_type.args:
+            assert isinstance(s.unanalyzed_type, UnboundType)
+            if not s.unanalyzed_type.args:
                 explicit = False
 
         if s.rvalue:
@@ -3506,19 +3506,19 @@ class SemanticAnalyzer(
 
         Returns True if Final[...] was present.
         """
-        final_type = self.unwrap_final_type(s.unanalyzed_type)
-        if final_type is None:
+        if not s.unanalyzed_type or not self.is_final_type(s.unanalyzed_type):
             return False
-        if len(final_type.args) > 1:
-            self.fail("Final[...] takes at most one type argument", final_type)
+        assert isinstance(s.unanalyzed_type, UnboundType)
+        if len(s.unanalyzed_type.args) > 1:
+            self.fail("Final[...] takes at most one type argument", s.unanalyzed_type)
         invalid_bare_final = False
-        if not final_type.args:
+        if not s.unanalyzed_type.args:
             s.type = None
             if isinstance(s.rvalue, TempNode) and s.rvalue.no_rhs:
                 invalid_bare_final = True
                 self.fail("Type in Final[...] can only be omitted if there is an initializer", s)
         else:
-            s.type = final_type.args[0]
+            s.type = s.unanalyzed_type.args[0]
 
         if s.type is not None and self.is_classvar(s.type):
             self.fail("Variable should not be annotated with both ClassVar and Final", s)
@@ -4937,18 +4937,13 @@ class SemanticAnalyzer(
             return False
         return sym.node.fullname == "typing.ClassVar"
 
-    def unwrap_final_type(self, typ: Type | None) -> UnboundType | None:
-        if typ is None:
-            return None
-        typ = typ.resolve_string_annotation()
+    def is_final_type(self, typ: Type | None) -> bool:
         if not isinstance(typ, UnboundType):
-            return None
+            return False
         sym = self.lookup_qualified(typ.name, typ)
         if not sym or not sym.node:
-            return None
-        if sym.node.fullname in FINAL_TYPE_NAMES:
-            return typ
-        return None
+            return False
+        return sym.node.fullname in FINAL_TYPE_NAMES
 
     def fail_invalid_classvar(self, context: Context) -> None:
         self.fail(message_registry.CLASS_VAR_OUTSIDE_OF_CLASS, context)


=====================================
mypy/semanal_typeddict.py
=====================================
@@ -323,7 +323,9 @@ class TypedDictAnalyzer:
                         return None, [], [], set()  # Need to defer
                     types.append(analyzed)
                     if not has_placeholder(analyzed):
-                        stmt.type = analyzed
+                        stmt.type = (
+                            analyzed.item if isinstance(analyzed, RequiredType) else analyzed
+                        )
                 # ...despite possible minor failures that allow further analysis.
                 if stmt.type is None or hasattr(stmt, "new_syntax") and not stmt.new_syntax:
                     self.fail(TPDICT_CLASS_ERROR, stmt)


=====================================
mypy/server/astmerge.py
=====================================
@@ -507,8 +507,7 @@ class TypeReplaceVisitor(SyntheticTypeVisitor[None]):
         typ.fallback.accept(self)
 
     def visit_raw_expression_type(self, t: RawExpressionType) -> None:
-        if t.node is not None:
-            t.node.accept(self)
+        pass
 
     def visit_literal_type(self, typ: LiteralType) -> None:
         typ.fallback.accept(self)


=====================================
mypy/stubutil.py
=====================================
@@ -17,16 +17,7 @@ import mypy.options
 from mypy.modulefinder import ModuleNotFoundReason
 from mypy.moduleinspect import InspectError, ModuleInspect
 from mypy.stubdoc import ArgSig, FunctionSig
-from mypy.types import (
-    AnyType,
-    NoneType,
-    RawExpressionType,
-    Type,
-    TypeList,
-    TypeStrVisitor,
-    UnboundType,
-    UnionType,
-)
+from mypy.types import AnyType, NoneType, Type, TypeList, TypeStrVisitor, UnboundType, UnionType
 
 # Modules that may fail when imported, or that may have side effects (fully qualified).
 NOT_IMPORTABLE_MODULES = ()
@@ -302,11 +293,12 @@ class AnnotationPrinter(TypeStrVisitor):
         The main difference from list_str is the preservation of quotes for string
         arguments
         """
+        types = ["builtins.bytes", "builtins.str"]
         res = []
         for arg in args:
             arg_str = arg.accept(self)
-            if isinstance(arg, RawExpressionType):
-                res.append(repr(arg.literal_value))
+            if isinstance(arg, UnboundType) and arg.original_str_fallback in types:
+                res.append(f"'{arg_str}'")
             else:
                 res.append(arg_str)
         return ", ".join(res)


=====================================
mypy/type_visitor.py
=====================================
@@ -382,8 +382,6 @@ class TypeQuery(SyntheticTypeVisitor[T]):
         return self.query_types(t.items.values())
 
     def visit_raw_expression_type(self, t: RawExpressionType) -> T:
-        if t.node is not None:
-            return t.node.accept(self)
         return self.strategy([])
 
     def visit_literal_type(self, t: LiteralType) -> T:
@@ -524,8 +522,6 @@ class BoolTypeQuery(SyntheticTypeVisitor[bool]):
         return self.query_types(list(t.items.values()))
 
     def visit_raw_expression_type(self, t: RawExpressionType) -> bool:
-        if t.node is not None:
-            return t.node.accept(self)
         return self.default
 
     def visit_literal_type(self, t: LiteralType) -> bool:


=====================================
mypy/typeanal.py
=====================================
@@ -1107,7 +1107,6 @@ class TypeAnalyser(SyntheticTypeVisitor[Type], TypeAnalyzerPluginInterface):
         return ret
 
     def anal_type_guard(self, t: Type) -> Type | None:
-        t = t.resolve_string_annotation()
         if isinstance(t, UnboundType):
             sym = self.lookup_qualified(t.name, t)
             if sym is not None and sym.node is not None:
@@ -1126,7 +1125,6 @@ class TypeAnalyser(SyntheticTypeVisitor[Type], TypeAnalyzerPluginInterface):
         return None
 
     def anal_type_is(self, t: Type) -> Type | None:
-        t = t.resolve_string_annotation()
         if isinstance(t, UnboundType):
             sym = self.lookup_qualified(t.name, t)
             if sym is not None and sym.node is not None:
@@ -1144,7 +1142,6 @@ class TypeAnalyser(SyntheticTypeVisitor[Type], TypeAnalyzerPluginInterface):
 
     def anal_star_arg_type(self, t: Type, kind: ArgKind, nested: bool) -> Type:
         """Analyze signature argument type for *args and **kwargs argument."""
-        t = t.resolve_string_annotation()
         if isinstance(t, UnboundType) and t.name and "." in t.name and not t.args:
             components = t.name.split(".")
             tvar_name = ".".join(components[:-1])
@@ -1235,8 +1232,6 @@ class TypeAnalyser(SyntheticTypeVisitor[Type], TypeAnalyzerPluginInterface):
         # make signatures like "foo(x: 20) -> None" legal, we can change
         # this method so it generates and returns an actual LiteralType
         # instead.
-        if t.node is not None:
-            return t.node.accept(self)
 
         if self.report_invalid_types:
             if t.base_type_name in ("builtins.int", "builtins.bool"):
@@ -1499,7 +1494,6 @@ class TypeAnalyser(SyntheticTypeVisitor[Type], TypeAnalyzerPluginInterface):
         invalid_unpacks: list[Type] = []
         second_unpack_last = False
         for i, arg in enumerate(arglist.items):
-            arg = arg.resolve_string_annotation()
             if isinstance(arg, CallableArgument):
                 args.append(arg.typ)
                 names.append(arg.name)
@@ -1580,6 +1574,22 @@ class TypeAnalyser(SyntheticTypeVisitor[Type], TypeAnalyzerPluginInterface):
         return UnionType.make_union(output, line=t.line)
 
     def analyze_literal_param(self, idx: int, arg: Type, ctx: Context) -> list[Type] | None:
+        # This UnboundType was originally defined as a string.
+        if (
+            isinstance(arg, ProperType)
+            and isinstance(arg, (UnboundType, UnionType))
+            and arg.original_str_expr is not None
+        ):
+            assert arg.original_str_fallback is not None
+            return [
+                LiteralType(
+                    value=arg.original_str_expr,
+                    fallback=self.named_type(arg.original_str_fallback),
+                    line=arg.line,
+                    column=arg.column,
+                )
+            ]
+
         # If arg is an UnboundType that was *not* originally defined as
         # a string, try expanding it in case it's a type alias or something.
         if isinstance(arg, UnboundType):
@@ -2564,8 +2574,7 @@ class FindTypeVarVisitor(SyntheticTypeVisitor[None]):
         self.process_types(list(t.items.values()))
 
     def visit_raw_expression_type(self, t: RawExpressionType) -> None:
-        if t.node is not None:
-            t.node.accept(self)
+        pass
 
     def visit_literal_type(self, t: LiteralType) -> None:
         pass


=====================================
mypy/types.py
=====================================
@@ -271,9 +271,6 @@ class Type(mypy.nodes.Context):
     def can_be_false_default(self) -> bool:
         return True
 
-    def resolve_string_annotation(self) -> Type:
-        return self
-
     def accept(self, visitor: TypeVisitor[T]) -> T:
         raise RuntimeError("Not implemented", type(self))
 
@@ -906,27 +903,50 @@ class TypeVarTupleType(TypeVarLikeType):
 class UnboundType(ProperType):
     """Instance type that has not been bound during semantic analysis."""
 
-    __slots__ = ("name", "args", "optional", "empty_tuple_index")
+    __slots__ = (
+        "name",
+        "args",
+        "optional",
+        "empty_tuple_index",
+        "original_str_expr",
+        "original_str_fallback",
+    )
 
     def __init__(
         self,
-        name: str | None,
+        name: str,
         args: Sequence[Type] | None = None,
         line: int = -1,
         column: int = -1,
         optional: bool = False,
         empty_tuple_index: bool = False,
+        original_str_expr: str | None = None,
+        original_str_fallback: str | None = None,
     ) -> None:
         super().__init__(line, column)
         if not args:
             args = []
-        assert name is not None
         self.name = name
         self.args = tuple(args)
         # Should this type be wrapped in an Optional?
         self.optional = optional
         # Special case for X[()]
         self.empty_tuple_index = empty_tuple_index
+        # If this UnboundType was originally defined as a str or bytes, keep track of
+        # the original contents of that string-like thing. This way, if this UnboundExpr
+        # ever shows up inside of a LiteralType, we can determine whether that
+        # Literal[...] is valid or not. E.g. Literal[foo] is most likely invalid
+        # (unless 'foo' is an alias for another literal or something) and
+        # Literal["foo"] most likely is.
+        #
+        # We keep track of the entire string instead of just using a boolean flag
+        # so we can distinguish between things like Literal["foo"] vs
+        # Literal["    foo   "].
+        #
+        # We also keep track of what the original base fallback type was supposed to be
+        # so we don't have to try and recompute it later
+        self.original_str_expr = original_str_expr
+        self.original_str_fallback = original_str_fallback
 
     def copy_modified(self, args: Bogus[Sequence[Type] | None] = _dummy) -> UnboundType:
         if args is _dummy:
@@ -938,19 +958,25 @@ class UnboundType(ProperType):
             column=self.column,
             optional=self.optional,
             empty_tuple_index=self.empty_tuple_index,
+            original_str_expr=self.original_str_expr,
+            original_str_fallback=self.original_str_fallback,
         )
 
     def accept(self, visitor: TypeVisitor[T]) -> T:
         return visitor.visit_unbound_type(self)
 
     def __hash__(self) -> int:
-        return hash((self.name, self.optional, tuple(self.args)))
+        return hash((self.name, self.optional, tuple(self.args), self.original_str_expr))
 
     def __eq__(self, other: object) -> bool:
         if not isinstance(other, UnboundType):
             return NotImplemented
         return (
-            self.name == other.name and self.optional == other.optional and self.args == other.args
+            self.name == other.name
+            and self.optional == other.optional
+            and self.args == other.args
+            and self.original_str_expr == other.original_str_expr
+            and self.original_str_fallback == other.original_str_fallback
         )
 
     def serialize(self) -> JsonDict:
@@ -958,12 +984,19 @@ class UnboundType(ProperType):
             ".class": "UnboundType",
             "name": self.name,
             "args": [a.serialize() for a in self.args],
+            "expr": self.original_str_expr,
+            "expr_fallback": self.original_str_fallback,
         }
 
     @classmethod
     def deserialize(cls, data: JsonDict) -> UnboundType:
         assert data[".class"] == "UnboundType"
-        return UnboundType(data["name"], [deserialize_type(a) for a in data["args"]])
+        return UnboundType(
+            data["name"],
+            [deserialize_type(a) for a in data["args"]],
+            original_str_expr=data["expr"],
+            original_str_fallback=data["expr_fallback"],
+        )
 
 
 class CallableArgument(ProperType):
@@ -2644,7 +2677,7 @@ class RawExpressionType(ProperType):
 
     This synthetic type is only used at the beginning stages of semantic analysis
     and should be completely removing during the process for mapping UnboundTypes to
-    actual types: we turn it into its "node" argument, a LiteralType, or an AnyType.
+    actual types: we either turn it into a LiteralType or an AnyType.
 
     For example, suppose `Foo[1]` is initially represented as the following:
 
@@ -2682,7 +2715,7 @@ class RawExpressionType(ProperType):
         )
     """
 
-    __slots__ = ("literal_value", "base_type_name", "note", "node")
+    __slots__ = ("literal_value", "base_type_name", "note")
 
     def __init__(
         self,
@@ -2691,39 +2724,20 @@ class RawExpressionType(ProperType):
         line: int = -1,
         column: int = -1,
         note: str | None = None,
-        node: Type | None = None,
     ) -> None:
         super().__init__(line, column)
         self.literal_value = literal_value
         self.base_type_name = base_type_name
         self.note = note
-        self.node = node
 
     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
 
-    def copy_modified(self, node: Type | None) -> RawExpressionType:
-        return RawExpressionType(
-            literal_value=self.literal_value,
-            base_type_name=self.base_type_name,
-            line=self.line,
-            column=self.column,
-            note=self.note,
-            node=node,
-        )
-
-    def resolve_string_annotation(self) -> Type:
-        if self.node is not None:
-            return self.node.resolve_string_annotation()
-        return self
-
     def serialize(self) -> JsonDict:
         assert False, "Synthetic types don't serialize"
 
@@ -2735,7 +2749,6 @@ class RawExpressionType(ProperType):
             return (
                 self.base_type_name == other.base_type_name
                 and self.literal_value == other.literal_value
-                and self.node == other.node
             )
         else:
             return NotImplemented
@@ -2833,7 +2846,13 @@ class LiteralType(ProperType):
 class UnionType(ProperType):
     """The union type Union[T1, ..., Tn] (at least one type argument)."""
 
-    __slots__ = ("items", "is_evaluated", "uses_pep604_syntax")
+    __slots__ = (
+        "items",
+        "is_evaluated",
+        "uses_pep604_syntax",
+        "original_str_expr",
+        "original_str_fallback",
+    )
 
     def __init__(
         self,
@@ -2852,6 +2871,11 @@ class UnionType(ProperType):
         self.is_evaluated = is_evaluated
         # uses_pep604_syntax is True if Union uses OR syntax (X | Y)
         self.uses_pep604_syntax = uses_pep604_syntax
+        # The meaning of these two is the same as for UnboundType. A UnionType can be
+        # return by type parser from a string "A|B", and we need to be able to fall back
+        # to plain string, when such a string appears inside a Literal[...].
+        self.original_str_expr: str | None = None
+        self.original_str_fallback: str | None = None
 
     def can_be_true_default(self) -> bool:
         return any(item.can_be_true for item in self.items)
@@ -3411,8 +3435,6 @@ class TypeStrVisitor(SyntheticTypeVisitor[str]):
         return f"TypedDict({prefix}{s})"
 
     def visit_raw_expression_type(self, t: RawExpressionType) -> str:
-        if t.node is not None:
-            return t.node.accept(self)
         return repr(t.literal_value)
 
     def visit_literal_type(self, t: LiteralType) -> str:
@@ -3476,9 +3498,6 @@ class TrivialSyntheticTypeTranslator(TypeTranslator, SyntheticTypeVisitor[Type])
         return t
 
     def visit_raw_expression_type(self, t: RawExpressionType) -> Type:
-        if t.node is not None:
-            node = t.node.accept(self)
-            return t.copy_modified(node=node)
         return t
 
     def visit_type_list(self, t: TypeList) -> Type:


=====================================
mypy/typetraverser.py
=====================================
@@ -130,8 +130,7 @@ class TypeTraverserVisitor(SyntheticTypeVisitor[None]):
         pass
 
     def visit_raw_expression_type(self, t: RawExpressionType) -> None:
-        if t.node is not None:
-            t.node.accept(self)
+        pass
 
     def visit_type_alias_type(self, t: TypeAliasType) -> None:
         # TODO: sometimes we want to traverse target as well


=====================================
mypy/version.py
=====================================
@@ -8,7 +8,7 @@ from mypy import git
 # - 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.1"
+__version__ = "1.11.2"
 base_version = __version__
 
 mypy_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))


=====================================
mypyc/irbuild/classdef.py
=====================================
@@ -26,7 +26,7 @@ from mypy.nodes import (
     TypeParam,
     is_class_var,
 )
-from mypy.types import ENUM_REMOVED_PROPS, Instance, RawExpressionType, get_proper_type
+from mypy.types import ENUM_REMOVED_PROPS, Instance, UnboundType, get_proper_type
 from mypyc.common import PROPSET_PREFIX
 from mypyc.ir.class_ir import ClassIR, NonExtClassInfo
 from mypyc.ir.func_ir import FuncDecl, FuncSignature
@@ -640,15 +640,16 @@ def add_non_ext_class_attr_ann(
     if typ is None:
         # FIXME: if get_type_info is not provided, don't fall back to stmt.type?
         ann_type = get_proper_type(stmt.type)
-        if isinstance(stmt.unanalyzed_type, RawExpressionType) and isinstance(
-            stmt.unanalyzed_type.literal_value, str
+        if (
+            isinstance(stmt.unanalyzed_type, UnboundType)
+            and stmt.unanalyzed_type.original_str_expr is not None
         ):
             # Annotation is a forward reference, so don't attempt to load the actual
             # type and load the string instead.
             #
             # TODO: is it possible to determine whether a non-string annotation is
             # actually a forward reference due to the __annotations__ future?
-            typ = builder.load_str(stmt.unanalyzed_type.literal_value)
+            typ = builder.load_str(stmt.unanalyzed_type.original_str_expr)
         elif isinstance(ann_type, Instance):
             typ = load_type(builder, ann_type.type, stmt.line)
         else:


=====================================
test-data/unit/check-final.test
=====================================
@@ -6,13 +6,11 @@
 [case testFinalDefiningModuleVar]
 from typing import Final
 
-w: 'Final' = int()
 x: Final = int()
 y: Final[float] = int()
 z: Final[int] = int()
 bad: Final[str] = int()  # E: Incompatible types in assignment (expression has type "int", variable has type "str")
 
-reveal_type(w)  # N: Revealed type is "builtins.int"
 reveal_type(x)  # N: Revealed type is "builtins.int"
 reveal_type(y)  # N: Revealed type is "builtins.float"
 reveal_type(z)  # N: Revealed type is "builtins.int"


=====================================
test-data/unit/check-namedtuple.test
=====================================
@@ -824,20 +824,14 @@ class Fraction(Real):
 [builtins fixtures/tuple.pyi]
 
 [case testForwardReferenceInNamedTuple]
-from typing import List, NamedTuple
+from typing import NamedTuple
 
 class A(NamedTuple):
     b: 'B'
     x: int
-    y: List['B']
 
 class B:
     pass
-
-def f(a: A):
-    reveal_type(a.b)  # N: Revealed type is "__main__.B"
-    reveal_type(a.x)  # N: Revealed type is "builtins.int"
-    reveal_type(a.y)  # N: Revealed type is "builtins.list[__main__.B]"
 [builtins fixtures/tuple.pyi]
 
 [case testTypeNamedTupleClassmethod]


=====================================
test-data/unit/check-parameter-specification.test
=====================================
@@ -1193,28 +1193,7 @@ def func(callback: Callable[P, str]) -> Callable[P, str]:
     return inner
 [builtins fixtures/paramspec.pyi]
 
-[case testParamSpecArgsAndKwargsStringified]
-from typing import Callable
-from typing_extensions import ParamSpec
-
-P1 = ParamSpec("P1")
-
-def func(callback: Callable[P1, str]) -> Callable[P1, str]:
-    def inner(*args: "P1.args", **kwargs: "P1.kwargs") -> str:
-        return "foo"
-    return inner
-
- at func
-def outer(a: int) -> str:
-    return ""
-
-outer(1)  # OK
-outer("x")  # E: Argument 1 to "outer" has incompatible type "str"; expected "int"
-outer(a=1)  # OK
-outer(b=1)  # E: Unexpected keyword argument "b" for "outer"
-[builtins fixtures/paramspec.pyi]
-
-[case testParamSpecArgsAndKwargsMismatch]
+[case testParamSpecArgsAndKwargsMissmatch]
 from typing import Callable
 from typing_extensions import ParamSpec
 


=====================================
test-data/unit/check-typeddict.test
=====================================
@@ -1442,18 +1442,6 @@ 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
 
@@ -2394,6 +2382,14 @@ class ForceDeferredEval: pass
 [builtins fixtures/dict.pyi]
 [typing fixtures/typing-typeddict.pyi]
 
+[case testTypedDictRequiredUnimportedAny]
+# flags: --disallow-any-unimported
+from typing import NotRequired, TypedDict
+from nonexistent import Foo  # type: ignore[import-not-found]
+class Bar(TypedDict):
+    foo: NotRequired[Foo]  # E: Type of variable becomes "Any" due to an unfollowed import
+[typing fixtures/typing-typeddict.pyi]
+
 -- Required[]
 
 [case testDoesRecognizeRequiredInTypedDictWithClass]


=====================================
test-data/unit/check-typeguard.test
=====================================
@@ -9,17 +9,6 @@ def main(a: object) -> None:
         reveal_type(a)  # N: Revealed type is "builtins.object"
 [builtins fixtures/tuple.pyi]
 
-[case testTypeGuardStringified]
-from typing_extensions import TypeGuard
-class Point: pass
-def is_point(a: object) -> "TypeGuard[Point]": pass
-def main(a: object) -> None:
-    if is_point(a):
-        reveal_type(a)  # N: Revealed type is "__main__.Point"
-    else:
-        reveal_type(a)  # N: Revealed type is "builtins.object"
-[builtins fixtures/tuple.pyi]
-
 [case testTypeGuardTypeArgsNone]
 from typing_extensions import TypeGuard
 def foo(a: object) -> TypeGuard:  # E: TypeGuard must have exactly one type argument


=====================================
test-data/unit/check-typeis.test
=====================================
@@ -9,17 +9,6 @@ def main(a: object) -> None:
         reveal_type(a)  # N: Revealed type is "builtins.object"
 [builtins fixtures/tuple.pyi]
 
-[case testTypeIsStringified]
-from typing_extensions import TypeIs
-class Point: pass
-def is_point(a: object) -> "TypeIs[Point]": pass
-def main(a: object) -> None:
-    if is_point(a):
-        reveal_type(a)  # N: Revealed type is "__main__.Point"
-    else:
-        reveal_type(a)  # N: Revealed type is "builtins.object"
-[builtins fixtures/tuple.pyi]
-
 [case testTypeIsElif]
 from typing_extensions import TypeIs
 from typing import Union



View it on GitLab: https://salsa.debian.org/python-team/packages/mypy/-/compare/119cdd810804cc634693444227a341a24bf9fce1...7f49c62dd3db56efe2b29fc5d6262a2d3d0addf1

-- 
View it on GitLab: https://salsa.debian.org/python-team/packages/mypy/-/compare/119cdd810804cc634693444227a341a24bf9fce1...7f49c62dd3db56efe2b29fc5d6262a2d3d0addf1
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20240826/4c52e10b/attachment-0001.htm>


More information about the debian-med-commit mailing list