From 3e3ea70df4a753e9f774f222d3722d2c9bfdbca7 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Tue, 19 Jul 2022 13:03:51 -0400 Subject: [PATCH] fixes for mypy 0.971 things that were passing with 0.961 need adjustment. it seems mypy has become very pedantic about the difference between importing from a module vs. accessing members of that module as instance variables, so adjust the preloaded typing block to be explicitly instance variables, since that's how the accessor works in any case. Change-Id: I746a3c9102530b7cf9b123aec7be6376657c1169 --- lib/sqlalchemy/orm/exc.py | 2 +- lib/sqlalchemy/orm/relationships.py | 2 +- lib/sqlalchemy/orm/strategies.py | 2 +- lib/sqlalchemy/sql/__init__.py | 16 ++--- lib/sqlalchemy/sql/cache_key.py | 2 +- lib/sqlalchemy/util/preloaded.py | 91 ++++++++++++++++++++++------- tox.ini | 3 +- 7 files changed, 83 insertions(+), 35 deletions(-) diff --git a/lib/sqlalchemy/orm/exc.py b/lib/sqlalchemy/orm/exc.py index 57e5fe8c6e..9b32e3a312 100644 --- a/lib/sqlalchemy/orm/exc.py +++ b/lib/sqlalchemy/orm/exc.py @@ -213,7 +213,7 @@ def _default_unmapped(cls: Type[Any]) -> Optional[str]: base = util.preloaded.orm_base try: - mappers = base.manager_of_class(cls).mappers + mappers = base.manager_of_class(cls).mappers # type: ignore except ( UnmappedClassError, TypeError, diff --git a/lib/sqlalchemy/orm/relationships.py b/lib/sqlalchemy/orm/relationships.py index 77a95a195b..669a2047c9 100644 --- a/lib/sqlalchemy/orm/relationships.py +++ b/lib/sqlalchemy/orm/relationships.py @@ -2055,7 +2055,7 @@ class Relationship( if self.uselist is None: self.uselist = self.direction is not MANYTOONE if not self.viewonly: - self._dependency_processor = ( + self._dependency_processor = ( # type: ignore dependency.DependencyProcessor.from_relationship )(self) diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py index db9dcffdc1..2c707439a1 100644 --- a/lib/sqlalchemy/orm/strategies.py +++ b/lib/sqlalchemy/orm/strategies.py @@ -543,7 +543,7 @@ class DeferredColumnLoader(LoaderStrategy): class LoadDeferredColumns: """serializable loader object used by DeferredColumnLoader""" - def __init__(self, key, raiseload=False): + def __init__(self, key: str, raiseload: bool = False): self.key = key self.raiseload = raiseload diff --git a/lib/sqlalchemy/sql/__init__.py b/lib/sqlalchemy/sql/__init__.py index c3ebb45960..5702d6c250 100644 --- a/lib/sqlalchemy/sql/__init__.py +++ b/lib/sqlalchemy/sql/__init__.py @@ -5,6 +5,7 @@ # This module is part of SQLAlchemy and is released under # the MIT License: https://www.opensource.org/licenses/mit-license.php from typing import Any +from typing import TYPE_CHECKING from .base import Executable as Executable from .compiler import COLLECT_CARTESIAN_PRODUCTS as COLLECT_CARTESIAN_PRODUCTS @@ -114,13 +115,14 @@ def __go(lcls: Any) -> None: from . import traversals from . import type_api - base.coercions = elements.coercions = coercions - base.elements = elements - base.type_api = type_api - coercions.elements = elements - coercions.lambdas = lambdas - coercions.schema = schema - coercions.selectable = selectable + if not TYPE_CHECKING: + base.coercions = elements.coercions = coercions + base.elements = elements + base.type_api = type_api + coercions.elements = elements + coercions.lambdas = lambdas + coercions.schema = schema + coercions.selectable = selectable from .annotation import _prepare_annotations from .annotation import Annotated diff --git a/lib/sqlalchemy/sql/cache_key.py b/lib/sqlalchemy/sql/cache_key.py index 5922c2db01..88148285c5 100644 --- a/lib/sqlalchemy/sql/cache_key.py +++ b/lib/sqlalchemy/sql/cache_key.py @@ -272,7 +272,7 @@ class HasCacheKey: elif meth is ANON_NAME: elements = util.preloaded.sql_elements if isinstance(obj, elements._anonymous_label): - obj = obj.apply_map(anon_map) + obj = obj.apply_map(anon_map) # type: ignore result += (attrname, obj) elif meth is CALL_GEN_CACHE_KEY: result += ( diff --git a/lib/sqlalchemy/util/preloaded.py b/lib/sqlalchemy/util/preloaded.py index 67394c9a3a..6332b3c943 100644 --- a/lib/sqlalchemy/util/preloaded.py +++ b/lib/sqlalchemy/util/preloaded.py @@ -13,8 +13,6 @@ runtime. from __future__ import annotations import sys -from types import ModuleType -import typing from typing import Any from typing import Callable from typing import TYPE_CHECKING @@ -24,17 +22,71 @@ _FN = TypeVar("_FN", bound=Callable[..., Any]) if TYPE_CHECKING: - from sqlalchemy.engine import default as engine_default # noqa - from sqlalchemy.orm import clsregistry as orm_clsregistry # noqa - from sqlalchemy.orm import decl_api as orm_decl_api # noqa - from sqlalchemy.orm import properties as orm_properties # noqa - from sqlalchemy.orm import relationships as orm_relationships # noqa - from sqlalchemy.orm import session as orm_session # noqa - from sqlalchemy.orm import state as orm_state # noqa - from sqlalchemy.orm import util as orm_util # noqa - from sqlalchemy.sql import dml as sql_dml # noqa - from sqlalchemy.sql import functions as sql_functions # noqa - from sqlalchemy.sql import util as sql_util # noqa + from sqlalchemy import dialects as _dialects + from sqlalchemy import orm as _orm + from sqlalchemy.engine import cursor as _engine_cursor + from sqlalchemy.engine import default as _engine_default + from sqlalchemy.engine import reflection as _engine_reflection + from sqlalchemy.engine import result as _engine_result + from sqlalchemy.engine import url as _engine_url + from sqlalchemy.orm import base as _orm_base + from sqlalchemy.orm import clsregistry as _orm_clsregistry + from sqlalchemy.orm import decl_api as _orm_decl_api + from sqlalchemy.orm import decl_base as _orm_decl_base + from sqlalchemy.orm import dependency as _orm_dependency + from sqlalchemy.orm import descriptor_props as _orm_descriptor_props + from sqlalchemy.orm import mapper as _orm_mapper + from sqlalchemy.orm import properties as _orm_properties + from sqlalchemy.orm import relationships as _orm_relationships + from sqlalchemy.orm import session as _orm_session + from sqlalchemy.orm import state as _orm_state + from sqlalchemy.orm import strategies as _orm_strategies + from sqlalchemy.orm import strategy_options as _orm_strategy_options + from sqlalchemy.orm import util as _orm_util + from sqlalchemy.sql import default_comparator as _sql_default_comparator + from sqlalchemy.sql import dml as _sql_dml + from sqlalchemy.sql import elements as _sql_elements + from sqlalchemy.sql import functions as _sql_functions + from sqlalchemy.sql import naming as _sql_naming + from sqlalchemy.sql import schema as _sql_schema + from sqlalchemy.sql import selectable as _sql_selectable + from sqlalchemy.sql import sqltypes as _sql_sqltypes + from sqlalchemy.sql import traversals as _sql_traversals + from sqlalchemy.sql import util as _sql_util + + # sigh, appease mypy 0.971 which does not accept imports as instance + # variables of a module + dialects = _dialects + engine_cursor = _engine_cursor + engine_default = _engine_default + engine_reflection = _engine_reflection + engine_result = _engine_result + engine_url = _engine_url + orm_clsregistry = _orm_clsregistry + orm_base = _orm_base + orm = _orm + orm_decl_api = _orm_decl_api + orm_decl_base = _orm_decl_base + orm_descriptor_props = _orm_descriptor_props + orm_dependency = _orm_dependency + orm_mapper = _orm_mapper + orm_properties = _orm_properties + orm_relationships = _orm_relationships + orm_session = _orm_session + orm_strategies = _orm_strategies + orm_strategy_options = _orm_strategy_options + orm_state = _orm_state + orm_util = _orm_util + sql_default_comparator = _sql_default_comparator + sql_dml = _sql_dml + sql_elements = _sql_elements + sql_functions = _sql_functions + sql_naming = _sql_naming + sql_selectable = _sql_selectable + sql_traversals = _sql_traversals + sql_schema = _sql_schema + sql_sqltypes = _sql_sqltypes + sql_util = _sql_util class _ModuleRegistry: @@ -85,17 +137,12 @@ class _ModuleRegistry: __import__(module, globals(), locals()) self.__dict__[key] = globals()[key] = sys.modules[module] - if typing.TYPE_CHECKING: - - def __getattr__(self, key: str) -> ModuleType: - ... - _reg = _ModuleRegistry() preload_module = _reg.preload_module import_prefix = _reg.import_prefix -if TYPE_CHECKING: - - def __getattr__(key: str) -> ModuleType: - ... +# this appears to do absolutely nothing for any version of mypy +# if TYPE_CHECKING: +# def __getattr__(key: str) -> ModuleType: +# ... diff --git a/tox.ini b/tox.ini index d966d9807d..ec51a939c5 100644 --- a/tox.ini +++ b/tox.ini @@ -133,8 +133,7 @@ commands= deps= greenlet != 0.4.17 importlib_metadata; python_version < '3.8' - mypy - # pyright + mypy >= 0.971 commands = mypy ./lib/sqlalchemy # pyright changes too often with not-exactly-correct errors -- 2.47.2