gh-91860: Add typing.dataclass_transform (PEP 681) (#91861)

Copied from typing-extensions (python/typing#1054, python/typing#1120).

Documentation is intentionally omitted, so we can focus on getting the
runtime part in before the feature freeze.
This commit is contained in:
Jelle Zijlstra 2022-04-25 20:30:25 -07:00 committed by GitHub
parent d174ebe91e
commit 5397b5afc1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 167 additions and 0 deletions

View file

@ -123,6 +123,7 @@ __all__ = [
'assert_never',
'cast',
'clear_overloads',
'dataclass_transform',
'final',
'get_args',
'get_origin',
@ -3271,3 +3272,81 @@ def reveal_type(obj: T, /) -> T:
"""
print(f"Runtime type is {type(obj).__name__!r}", file=sys.stderr)
return obj
def dataclass_transform(
*,
eq_default: bool = True,
order_default: bool = False,
kw_only_default: bool = False,
field_specifiers: tuple[type[Any] | Callable[..., Any], ...] = (),
**kwargs: Any,
) -> Callable[[T], T]:
"""Decorator that marks a function, class, or metaclass as providing
dataclass-like behavior.
Example usage with a decorator function:
_T = TypeVar("_T")
@dataclass_transform()
def create_model(cls: type[_T]) -> type[_T]:
...
return cls
@create_model
class CustomerModel:
id: int
name: str
On a base class:
@dataclass_transform()
class ModelBase: ...
class CustomerModel(ModelBase):
id: int
name: str
On a metaclass:
@dataclass_transform()
class ModelMeta(type): ...
class ModelBase(metaclass=ModelMeta): ...
class CustomerModel(ModelBase):
id: int
name: str
Each of the ``CustomerModel`` classes defined in this example will now
behave similarly to a dataclass created with the ``@dataclasses.dataclass``
decorator. For example, the type checker will synthesize an ``__init__``
method.
The arguments to this decorator can be used to customize this behavior:
- ``eq_default`` indicates whether the ``eq`` parameter is assumed to be
True or False if it is omitted by the caller.
- ``order_default`` indicates whether the ``order`` parameter is
assumed to be True or False if it is omitted by the caller.
- ``kw_only_default`` indicates whether the ``kw_only`` parameter is
assumed to be True or False if it is omitted by the caller.
- ``field_specifiers`` specifies a static list of supported classes
or functions that describe fields, similar to ``dataclasses.field()``.
At runtime, this decorator records its arguments in the
``__dataclass_transform__`` attribute on the decorated object.
It has no other runtime effect.
See PEP 681 for more details.
"""
def decorator(cls_or_fn):
cls_or_fn.__dataclass_transform__ = {
"eq_default": eq_default,
"order_default": order_default,
"kw_only_default": kw_only_default,
"field_specifiers": field_specifiers,
"kwargs": kwargs,
}
return cls_or_fn
return decorator