Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Special handling of descriptor field like in dataclasses #1232

Open
getzze opened this issue Feb 2, 2024 · 5 comments
Open

Special handling of descriptor field like in dataclasses #1232

getzze opened this issue Feb 2, 2024 · 5 comments
Labels
dataclasses dataclass features we're lacking Feature

Comments

@getzze
Copy link

getzze commented Feb 2, 2024

dataclass dataclasses handle descriptor fields differently from other fields, so the descriptor type is not lost when assigning:
https://docs.python.org/3/library/dataclasses.html#descriptor-typed-fields

This does not work in attrs, it's a pity because it could be used as an alternative to converters called with the instance (#1108).
Previous discussion about this was not very conclusive (#881).

# Example from python docs
from dataclasses import dataclass
from attrs import define


class IntConversionDescriptor:
    def __init__(self, *, default):
        self._default = default

    def __set_name__(self, owner, name):
        self._name = "_" + name

    def __get__(self, obj, type):
        if obj is None:
            return self._default

        return getattr(obj, self._name, self._default)

    def __set__(self, obj, value):
        setattr(obj, self._name, int(value))

# dataclass: WORKS AS EXPECTED
@dataclass
class InventoryItem:
    quantity_on_hand: IntConversionDescriptor = IntConversionDescriptor(default=100)

i = InventoryItem()
print(i.quantity_on_hand)   # 100
i.quantity_on_hand = 2.5    # calls __set__ with 2.5
print(i.quantity_on_hand)   # 2


# attrs: DOES NOT WORK
@define
class InventoryItem2:
    quanttity_on_hand: IntConversionDescriptor = IntConversionDescriptor(default=100)

i2 = InventoryItem2()
print(i2.quantity_on_hand)   # <__main__.IntConversionDescriptor object at 0x78c3a12a1250>
i2.quantity_on_hand = 2.5    # set InventoryItem2 attribute to a float, erasing the descriptor
print(i2.quantity_on_hand)   # 2.5
@hynek
Copy link
Member

hynek commented Feb 3, 2024

I was wondering when they added it, because I didn't have it on my radar at all, but it looks like 3.10 – if the docs are to be trusted (3.9 doesn't mention descriptors at all).

Does anyone have a clue how much work it would be to integrate this?

@hynek hynek added the Feature label Feb 3, 2024
@getzze
Copy link
Author

getzze commented Feb 3, 2024 via email

@Tinche
Copy link
Member

Tinche commented Feb 4, 2024

I'm in favor of fixing this on philosophical grounds (I'm bothered by dataclasses doing a thing better than us) ;)

@hynek
Copy link
Member

hynek commented Feb 4, 2024

Yes, it's very irritating.

@getzze
Copy link
Author

getzze commented Feb 4, 2024 via email

@hynek hynek added the dataclasses dataclass features we're lacking label Feb 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dataclasses dataclass features we're lacking Feature
Projects
None yet
Development

No branches or pull requests

3 participants