diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-01-09 11:49:02 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-01-24 15:14:01 -0500 |
| commit | ff1ab665cb1694b85085680d1a02c7c11fa2a6d4 (patch) | |
| tree | bb8414b44946d9cb96361d7dcd4a4541d8254672 /lib/sqlalchemy/orm/decl_api.py | |
| parent | aba3ab247da4628e4e7baf993702e2efaccbc547 (diff) | |
| download | sqlalchemy-ff1ab665cb1694b85085680d1a02c7c11fa2a6d4.tar.gz | |
mypy: sqlalchemy.util
Starting to set up practices and conventions to
get the library typed.
Key goals for typing are:
1. whole library can pass mypy without any strict
turned on.
2. we can incrementally turn on some strict flags on a per-package/
module basis, as here we turn on more strictness for sqlalchemy.util, exc,
and log
3. mypy ORM plugin tests work fully without sqlalchemy2-stubs
installed
4. public facing methods all have return types, major parameter
signatures filled in also
5. Foundational elements like util etc. are typed enough so that
we can use them in fully typed internals higher up the stack.
Conventions set up here:
1. we can use lots of config in setup.cfg to limit where mypy
is throwing errors and how detailed it should be in different
packages / modules. We can use this to push up gerrits
that will pass tests fully without everything being typed.
2. a new tox target pep484 is added. this links to a new jenkins
pep484 job that works across all projects (alembic, dogpile, etc.)
We've worked around some mypy bugs that will likely
be around for awhile, and also set up some core practices
for how to deal with certain things such as public_factory
modules (mypy won't accept a module from a callable at all,
so need to use simple type checking conditionals).
References: #6810
Change-Id: I80be58029896a29fd9f491aa3215422a8b705e12
Diffstat (limited to 'lib/sqlalchemy/orm/decl_api.py')
| -rw-r--r-- | lib/sqlalchemy/orm/decl_api.py | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/lib/sqlalchemy/orm/decl_api.py b/lib/sqlalchemy/orm/decl_api.py index 29a9c9edf..59fabb9b6 100644 --- a/lib/sqlalchemy/orm/decl_api.py +++ b/lib/sqlalchemy/orm/decl_api.py @@ -42,6 +42,9 @@ from ..sql.selectable import FromClause from ..util import hybridmethod from ..util import hybridproperty +if typing.TYPE_CHECKING: + from .state import InstanceState # noqa + _T = TypeVar("_T", bound=Any) @@ -64,7 +67,9 @@ def has_inherited_table(cls): return False -class DeclarativeAttributeIntercept(type): +class DeclarativeAttributeIntercept( + type, inspection.Inspectable["Mapper[Any]"] +): """Metaclass that may be used in conjunction with the :class:`_orm.DeclarativeBase` class to support addition of class attributes dynamically. @@ -78,7 +83,7 @@ class DeclarativeAttributeIntercept(type): _del_attribute(cls, key) -class DeclarativeMeta(type): +class DeclarativeMeta(type, inspection.Inspectable["Mapper[Any]"]): def __init__(cls, classname, bases, dict_, **kw): # early-consume registry from the initial declarative base, # assign privately to not conflict with subclass attributes named @@ -421,7 +426,7 @@ def _setup_declarative_base(cls): cls.metadata = cls.registry.metadata -class DeclarativeBaseNoMeta: +class DeclarativeBaseNoMeta(inspection.Inspectable["Mapper"]): """Same as :class:`_orm.DeclarativeBase`, but does not use a metaclass to intercept new attributes. @@ -451,7 +456,10 @@ class DeclarativeBaseNoMeta: cls._sa_registry.map_declaratively(cls) -class DeclarativeBase(metaclass=DeclarativeAttributeIntercept): +class DeclarativeBase( + inspection.Inspectable["InstanceState"], + metaclass=DeclarativeAttributeIntercept, +): """Base class used for declarative class definitions. The :class:`_orm.DeclarativeBase` allows for the creation of new |
