Open
Description
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