]> 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:46:09 +0000 (11:46 -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
(cherry picked from commit f79d09221b1ec6cd6bc8d83d6e947db5f75c6d1c)

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 f88a960bd2e1cdaab9185039bec8dd162962f682..f3f44a425046ae3979d32decc441041328a043ab 100644 (file)
@@ -9,7 +9,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
@@ -454,8 +453,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 16b365e1eee970121fbdc31f8934542d2d96eb2a..373fd4bfbc4d7673e79fb65900f6ba5ca60c2166 100644 (file)
@@ -10,6 +10,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 ARG_POS
 from mypy.nodes import CallExpr
 from mypy.nodes import ClassDef
@@ -23,6 +25,7 @@ from mypy.nodes import NameExpr
 from mypy.nodes import Statement
 from mypy.nodes import SymbolTableNode
 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
@@ -35,6 +38,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])
 
@@ -151,6 +159,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 cb04d1c739a901adefaea50043cda5bfdc1162d0..be80043ca88ca30de1b9dd2e460d892c240ae74d 100644 (file)
@@ -172,6 +172,9 @@ class MypyPluginTest(fixtures.TestBase):
         expected_errors = []
         expected_re = re.compile(r"\s*# EXPECTED(_MYPY)?: (.+)")
         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_:
             for num, line in enumerate(file_, 1):
                 m = py_ver_re.match(line)
@@ -191,6 +194,22 @@ class MypyPluginTest(fixtures.TestBase):
                     is_mypy = bool(m.group(1))
                     expected_msg = m.group(2)
                     expected_msg = re.sub(r"# noqa[:]? ?.*", "", m.group(2))
+
+                    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|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,
+                        )
+
                     expected_errors.append(
                         (num, is_mypy, expected_msg.strip())
                     )