]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
document no-pep681 workarounds
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 11 Mar 2023 15:38:44 +0000 (10:38 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 12 Mar 2023 16:07:41 +0000 (12:07 -0400)
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

doc/build/orm/dataclasses.rst
doc/build/orm/mapping_api.rst

index 254959ab6c67efd3f1e1dc7faf5700b8ed75bb62..34749334fe64a9c808156d16a35bd5e85061851e 100644 (file)
@@ -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
index 1a33f956689b2e4bd7a547eaafc5eccf124e558a..8260fcb2f967855b0835063276d3cb5c0f6c4d67 100644 (file)
@@ -138,7 +138,6 @@ Class Mapping API
 .. autoclass:: Mapper
    :members:
 
-
 .. autoclass:: MappedAsDataclass
     :members: