diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2023-03-11 10:38:44 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2023-03-12 12:07:41 -0400 |
| commit | 3a4705225d2d7ccfdc48c31bd5a4436bc3830c5d (patch) | |
| tree | bc953673ed32cbf0a82f124641f2348dae7f441a /doc/build/orm | |
| parent | 85897db771bd3150d10ebb80cade909c69264ac0 (diff) | |
| download | sqlalchemy-3a4705225d2d7ccfdc48c31bd5a4436bc3830c5d.tar.gz | |
document no-pep681 workarounds
Mypy 1.1.1 has been released which includes a non-compliant pep-681
implementation that fails with SQLAlchemy's :class:`.MappedAsDataclass` and
similar features. In order to work around this issue until Mypy is able to
release a fix, as well as to support other typing tools which may have
non-compliant pep-681 implementations, document a workaround class
for :class:`.MappedAsDataclass`.
Including this class as well as a decorator was considered, but overall
this is an issue with typing tools that they will have to resolve
and I'm not ready to set up for this issue going on long term. There's
also no good solution for the decorator version since you have to
have an ``__init__`` method indicated somewhere.
References: https://github.com/python/mypy/issues/13856
Fixes: #9467
Change-Id: I1be6abea7f7fc72883c14ab2447edad937d0c23f
Diffstat (limited to 'doc/build/orm')
| -rw-r--r-- | doc/build/orm/dataclasses.rst | 55 | ||||
| -rw-r--r-- | doc/build/orm/mapping_api.rst | 1 |
2 files changed, 50 insertions, 6 deletions
diff --git a/doc/build/orm/dataclasses.rst b/doc/build/orm/dataclasses.rst index 254959ab6..34749334f 100644 --- a/doc/build/orm/dataclasses.rst +++ b/doc/build/orm/dataclasses.rst @@ -37,11 +37,56 @@ as having Dataclass-specific behaviors, most notably by taking advantage of :pe as though it were explicitly decorated using the ``@dataclasses.dataclass`` decorator. -.. note:: Support for :pep:`681` in typing tools as of **July 3, 2022** is - limited and is currently known to be supported by Pyright_, but not yet - Mypy_. When :pep:`681` is not supported, typing tools will see the - ``__init__()`` constructor provided by the :class:`_orm.DeclarativeBase` - superclass, if used, else will see the constructor as untyped. +.. note:: Support for :pep:`681` in typing tools as of **March 11, 2023** is + limited and is currently known to be supported by Pyright_, but + **not correctly supported** by Mypy_ version 1.1.1. Mypy 1.1.1 introduced + :pep:`681` support but failed to accommodate for Python descriptors + correctly (see Github issue below). + + In order to resolve errors when using :class:`_orm.MappedAsDataclass` with + Mypy version 1.1.1 or other typing tools that have similar errors, the + following workaround may be used, which uses a plain non-pep681 mixin within + ``TYPE_CHECKING`` to avoid errors:: + + import typing + + if typing.TYPE_CHECKING: + + class MappedAsDataclass: + """Mixin class which works in the same way as + :class:`_orm.MappedAsDataclass`, + but does not include :pep:`681` directives. + + """ + + def __init__(self, *arg: typing.Any, **kw: typing.Any): + pass + + else: + from sqlalchemy.orm import MappedAsDataclass + + Above, the SQLAlchemy :class:`_orm.MappedAsDataclass` mixin is hidden + from typing tools and replaced with a plain mixin that sets up an + ``__init__`` constructor that accommodates any arguments. + + When using the :meth:`_orm.registry.mapped_as_dataclass` method, + similar approaches can be taken using a plain decorator, however classes + would need to also include an explicit ``__init__()`` method on a mixin + like the one indicated above for the workaround to work completely:: + + + def mapped_as_dataclass(registry, cls, **kw): + """Will conceal the pep-681 enabled methods from typing tools""" + + return registry.mapped_as_dataclass(cls, **kw) + + .. seealso:: + + https://github.com/python/mypy/issues/13856 - Mypy issue on github + + https://peps.python.org/pep-0681/#the-dataclass-transform-decorator - background + on how libraries like SQLAlchemy enable :pep:`681` support + Dataclass conversion may be added to any Declarative class either by adding the :class:`_orm.MappedAsDataclass` mixin to a :class:`_orm.DeclarativeBase` class diff --git a/doc/build/orm/mapping_api.rst b/doc/build/orm/mapping_api.rst index 1a33f9566..8260fcb2f 100644 --- a/doc/build/orm/mapping_api.rst +++ b/doc/build/orm/mapping_api.rst @@ -138,7 +138,6 @@ Class Mapping API .. autoclass:: Mapper :members: - .. autoclass:: MappedAsDataclass :members: |
