Skip to content

Commit

Permalink
First cut
Browse files Browse the repository at this point in the history
  • Loading branch information
debonte committed Feb 14, 2022
1 parent bdc0e44 commit 64afca0
Showing 1 changed file with 44 additions and 0 deletions.
44 changes: 44 additions & 0 deletions pep-0681.rst
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ customization of default behaviors:
eq_default: bool = True,
order_default: bool = False,
kw_only_default: bool = False,
transform_descriptor_types: bool = False,
field_descriptors: tuple[type | Callable[..., Any], ...] = (),
) -> Callable[[_T], _T]: ...
Expand All @@ -218,6 +219,10 @@ customization of default behaviors:
assumed to be True or False if it is omitted by the caller. If not
specified, ``kw_only_default`` will default to False (the default
assumption for dataclass).
* ``transform_descriptor_types`` indicates whether, for fields whose
annotated types are descriptors, the corresponding parameter in the
synthesized ``__init__`` method should be the descriptor's setter
parameter type. If False, the descriptor type will be used.

This comment has been minimized.

Copy link
@erictraut

erictraut Feb 15, 2022

This is a good description and a reasonable name. It should also mention the default value, which should be False, since that corresponds to the behavior of dataclass.

* ``field_descriptors`` specifies a static list of supported classes
that describe fields. Some libraries also supply functions to
allocate instances of field descriptors, and those functions may
Expand Down Expand Up @@ -326,6 +331,31 @@ Metaclass example
id: int
name: str
``transform_descriptor_types`` example
``````````````````````````````````````

Because ``transform_descriptor_types`` is set to ``True``, the
``target`` parameter on the synthesized ``__init__`` method will be of
type ``float`` instead of ``Descriptor``.

.. code-block:: python
class Descriptor:

This comment has been minimized.

Copy link
@erictraut

erictraut Feb 15, 2022

A more typical scenario is for the descriptor class to be generic. That's the case with SqlAlchemy, for example. Do you think we should make the example generic as well? I could go either way on this. It adds complexity, and it's good to keep sample code simple. However, it's also good to show a typical use case.

def __get__(self, instance: object, owner: Any) -> int:
...
# The setter and getter can have different types (asymmetric).
# The setter's value type is used for the __init__ parameter.
# The getter's return type is ignored.
def __set__(self, instance: object, value: float):
...
class CustomerModel(
ModelBase,
transform_descriptor_types=True

This comment has been minimized.

Copy link
@erictraut

erictraut Feb 15, 2022

dataclass_transform is always applied as a decorator on the base class, so this would need to be changed to:

@dataclass_transform(transform_descriptor_types=True)
class ModelBase: ...
):
target: Descriptor
Field descriptors
-----------------
Expand Down Expand Up @@ -449,6 +479,7 @@ For example:
"eq_default": True,
"order_default": False,
"kw_only_default": False,
"transform_descriptor_types": False,
"field_descriptors": ()
}
Expand Down Expand Up @@ -556,6 +587,7 @@ following declaration within their type stubs or source files:
eq_default: bool = True,
order_default: bool = False,
kw_only_default: bool = False,
transform_descriptor_types: bool = False,
field_descriptors: tuple[type | Callable[..., Any], ...] = (),
) -> Callable[[_T], _T]:
# If used within a stub file, the following implementation can
Expand Down Expand Up @@ -676,6 +708,18 @@ users of Django would need to explicitly declare the ``id`` field.
This limitation may make it impractical to use the
``dataclass_transform`` mechanism with Django.

Class-wide default values
-------------------------

SQLAlchemy requested that we expose a way to specify that the default
value of all fields in the transformed class is None. It is typical
that all of their fields are optional and None indicates that the
field is not set.

We chose not to support this feature, since it is specific to
SQLAlchemy. Users can manually set ``default=None`` on these fields
instead.

Open Issues
===========

Expand Down

0 comments on commit 64afca0

Please sign in to comment.