]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commit
Adjust for mypy incremental behaviors
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 26 Mar 2021 23:45:29 +0000 (19:45 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 5 Apr 2021 23:23:52 +0000 (19:23 -0400)
commit606096ae01c71298da4d3fda3f62c730d9985105
tree8e745f10d60683edbf1da49a557bebc9994fb7ba
parent4e0f90424afe03547c21ec3b6365755bb5288075
Adjust for mypy incremental behaviors

Applied a series of refactorings and fixes to accommodate for Mypy
"incremental" mode across multiple files, which previously was not taken
into account. In this mode the Mypy plugin has to accommodate Python
datatypes expressed in other files coming in with less information than
they have on a direct run.

Additionally, a new decorator :func:`_orm.declarative_mixin` is added,
which is necessary for the Mypy plugin to be able to definifitely identify
a Declarative mixin class that is otherwise not used inside a particular
Python file.

discussion:

With incremental / deserialized mypy runs, it appears
that when we look at a base class that comes from another file,
cls.info is set to a special undefined node
that matches CLASSDEF_NO_INFO, and we otherwise can't
touch it without crashing.  Additionally, sometimes cls.defs.body
is present but empty.

However, it appears that both of these cases can be sidestepped,
first by doing a lookup() for the type name where we
get a SymbolTableNode that then has the TypeInfo we wanted
when we tried touching cls.info, and then however we got the
TypeInfo, if cls.defs.body is empty we can just look in the
names to get at the symbols for that class; we just can't
access AssignmentStmts, but that's fine because we just
need the information for classes we aren't actually type checking.

This work also revealed there's no easy way to detect a mixin
class so we just create a new decorator to mark that.  will make
code look better in any case.

Fixes: #6147
Change-Id: Ia8fac8acfeec931d8f280491cffc5c6cb4a1204e
20 files changed:
doc/build/changelog/unreleased_14/6147.rst [new file with mode: 0644]
doc/build/orm/declarative_mixins.rst
doc/build/orm/extensions/mypy.rst
doc/build/orm/mapping_api.rst
lib/sqlalchemy/ext/mypy/apply.py [new file with mode: 0644]
lib/sqlalchemy/ext/mypy/decl_class.py
lib/sqlalchemy/ext/mypy/infer.py [new file with mode: 0644]
lib/sqlalchemy/ext/mypy/names.py
lib/sqlalchemy/ext/mypy/plugin.py
lib/sqlalchemy/ext/mypy/util.py
lib/sqlalchemy/orm/__init__.py
lib/sqlalchemy/orm/decl_api.py
test/ext/mypy/files/mixin_three.py [new file with mode: 0644]
test/ext/mypy/incremental/ticket_6147/__init__.py [new file with mode: 0644]
test/ext/mypy/incremental/ticket_6147/base.py [new file with mode: 0644]
test/ext/mypy/incremental/ticket_6147/one.py [new file with mode: 0644]
test/ext/mypy/incremental/ticket_6147/patch1.testpatch [new file with mode: 0644]
test/ext/mypy/incremental/ticket_6147/patch2.testpatch [new file with mode: 0644]
test/ext/mypy/test_mypy_plugin_py3k.py
test/orm/declarative/test_mixin.py