Skip to content

Commit

Permalink
updates for mypy 1.4
Browse files Browse the repository at this point in the history
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 f79d092)
  • Loading branch information
zzzeek committed Jun 21, 2023
1 parent 8e465ce commit b39af62
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 3 deletions.
5 changes: 5 additions & 0 deletions doc/build/changelog/unreleased_14/mypy14.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.. change::
:tags: bug, ext
:versions: 2.0.17

Fixed issue in mypy plugin for use with mypy 1.4.
5 changes: 2 additions & 3 deletions lib/sqlalchemy/ext/mypy/infer.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
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
Expand Down Expand Up @@ -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,
)
Expand Down
15 changes: 15 additions & 0 deletions lib/sqlalchemy/ext/mypy/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
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
Expand All @@ -23,6 +25,7 @@
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
Expand All @@ -35,6 +38,11 @@
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])

Expand Down Expand Up @@ -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:
Expand Down
19 changes: 19 additions & 0 deletions test/ext/mypy/test_mypy_plugin_py3k.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,9 @@ def test_mypy(self, mypy_runner, path):
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)
Expand All @@ -191,6 +194,22 @@ def test_mypy(self, mypy_runner, path):
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())
)
Expand Down

0 comments on commit b39af62

Please sign in to comment.