as though it were explicitly decorated using the ``@dataclasses.dataclass``
decorator.
-.. 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)
+.. note:: Support for :pep:`681` in typing tools as of **April 4, 2023** is
+ limited and is currently known to be supported by Pyright_ as well
+ as Mypy_ as of **version 1.2**. Note that Mypy 1.1.1 introduced
+ :pep:`681` support but did not correctly accommodate Python descriptors
+ which will lead to errors when using SQLAlhcemy's ORM mapping scheme.
.. 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
--- /dev/null
+from __future__ import annotations
+
+from typing import Optional
+
+from sqlalchemy.orm import DeclarativeBase
+from sqlalchemy.orm import Mapped
+from sqlalchemy.orm import mapped_column
+from sqlalchemy.orm import MappedAsDataclass
+
+
+class Base(MappedAsDataclass, DeclarativeBase):
+ pass
+
+
+class A(Base):
+ __tablename__ = "a"
+
+ id: Mapped[int] = mapped_column(primary_key=True, init=False)
+ data: Mapped[str]
+ x: Mapped[Optional[int]] = mapped_column(default=None)
+ y: Mapped[Optional[int]] = mapped_column(kw_only=True)
+
+
+a1 = A(data="some data", y=5)
+
+# EXPECTED_TYPE: str
+reveal_type(a1.data)
+
+# EXPECTED_RE_TYPE: .*Union\[builtins.int, None\]
+reveal_type(a1.y)
+
+a1.data = "some other data"