]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
updates for mypy 1.4
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 20 Jun 2023 19:24:38 +0000 (15:24 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 21 Jun 2023 15:44:18 +0000 (11:44 -0400)
mypy 1.4 is reporting new style types list[], tuple[], etc.
as well as "x | None" for optional.

they also added one argument for format_type().

This is for 1.4 backport as well

Change-Id: I68084199858e9da901641d6036780437bcf5f2d6

doc/build/changelog/unreleased_14/mypy14.rst [new file with mode: 0644]
lib/sqlalchemy/ext/mypy/infer.py
lib/sqlalchemy/ext/mypy/util.py
test/ext/mypy/test_mypy_plugin_py3k.py

diff --git a/doc/build/changelog/unreleased_14/mypy14.rst b/doc/build/changelog/unreleased_14/mypy14.rst
new file mode 100644 (file)
index 0000000..97c3751
--- /dev/null
@@ -0,0 +1,5 @@
+.. change::
+    :tags: bug, ext
+    :versions: 2.0.17
+
+    Fixed issue in mypy plugin for use with mypy 1.4.
index 33137959359164fe337e1acd11e3531ea54f01f5..e8345d09ae3fb7fc33d3fc544de52b4fc7b67ba5 100644 (file)
@@ -11,7 +11,6 @@ from typing import Optional
 from typing import Sequence
 
 from mypy.maptype import map_instance_to_supertype
-from mypy.messages import format_type
 from mypy.nodes import AssignmentStmt
 from mypy.nodes import CallExpr
 from mypy.nodes import Expression
@@ -489,8 +488,8 @@ def _infer_type_from_left_and_inferred_right(
             api,
             msg.format(
                 node.name,
-                format_type(orig_left_hand_type),
-                format_type(effective_type),
+                util.format_type(orig_left_hand_type, api.options),
+                util.format_type(effective_type, api.options),
             ),
             node,
         )
index c3771dbc5cae9c74288fea6ffe378acdccd472b5..fe4402123633aa2d84b8e0130d326c6eee231e73 100644 (file)
@@ -19,6 +19,8 @@ from typing import Type as TypingType
 from typing import TypeVar
 from typing import Union
 
+from mypy import version
+from mypy.messages import format_type as _mypy_format_type
 from mypy.nodes import CallExpr
 from mypy.nodes import ClassDef
 from mypy.nodes import CLASSDEF_NO_INFO
@@ -33,6 +35,7 @@ from mypy.nodes import Statement
 from mypy.nodes import SymbolTableNode
 from mypy.nodes import TypeAlias
 from mypy.nodes import TypeInfo
+from mypy.options import Options
 from mypy.plugin import ClassDefContext
 from mypy.plugin import DynamicClassDefContext
 from mypy.plugin import SemanticAnalyzerPluginInterface
@@ -47,6 +50,11 @@ from mypy.types import TypeVarType
 from mypy.types import UnboundType
 from mypy.types import UnionType
 
+_vers = tuple(
+    [int(x) for x in version.__version__.split(".") if re.match(r"^\d+$", x)]
+)
+mypy_14 = _vers >= (1, 4)
+
 
 _TArgType = TypeVar("_TArgType", bound=Union[CallExpr, NameExpr])
 
@@ -163,6 +171,13 @@ def get_mapped_attributes(
     return attributes
 
 
+def format_type(typ_: Type, options: Options) -> str:
+    if mypy_14:
+        return _mypy_format_type(typ_, options)  # type: ignore
+    else:
+        return _mypy_format_type(typ_)  # type: ignore
+
+
 def set_mapped_attributes(
     info: TypeInfo, attributes: List[SQLAlchemyAttribute]
 ) -> None:
index 6a04f2730a7af021c98c00bdd85b0a76ad520fbc..4440a16e45115288888bb1c1fba2fa09caa17b38 100644 (file)
@@ -207,6 +207,9 @@ class MypyPluginTest(fixtures.TestBase):
         expected_messages = []
         expected_re = re.compile(r"\s*# EXPECTED(_MYPY)?(_RE)?(_TYPE)?: (.+)")
         py_ver_re = re.compile(r"^#\s*PYTHON_VERSION\s?>=\s?(\d+\.\d+)")
+
+        from sqlalchemy.ext.mypy.util import mypy_14
+
         with open(path) as file_:
             current_assert_messages = []
             for num, line in enumerate(file_, 1):
@@ -229,6 +232,7 @@ class MypyPluginTest(fixtures.TestBase):
                     is_type = bool(m.group(3))
 
                     expected_msg = re.sub(r"# noqa[:]? ?.*", "", m.group(4))
+
                     if is_type:
                         if not is_re:
                             # the goal here is that we can cut-and-paste
@@ -267,6 +271,23 @@ class MypyPluginTest(fixtures.TestBase):
 
                         is_mypy = is_re = True
                         expected_msg = f'Revealed type is "{expected_msg}"'
+
+                    if mypy_14:
+                        # skip first character which could be capitalized
+                        # "List item x not found" type of message
+                        expected_msg = expected_msg[0] + re.sub(
+                            r"\b(List|Tuple|Dict|Set)\b"
+                            if is_type
+                            else r"\b(List|Tuple|Dict|Set|Type)\b",
+                            lambda m: m.group(1).lower(),
+                            expected_msg[1:],
+                        )
+
+                        expected_msg = re.sub(
+                            r"Optional\[(.*?)\]",
+                            lambda m: f"{m.group(1)} | None",
+                            expected_msg,
+                        )
                     current_assert_messages.append(
                         (is_mypy, is_re, expected_msg.strip())
                     )