[Python-Dev] descriptor set_name and dataclasses (original) (raw)

Eric V. Smith eric at trueblade.com
Mon Mar 26 10:40:10 EDT 2018


https://bugs.python.org/issue33141 points out an interesting issue with dataclasses and descriptors.

Given this code:

from dataclasses import *

class D: """A descriptor class that knows its name.""" def set_name(self, owner, name): self.name = name def get(self, instance, owner): if instance is not None: return 1 return self

@dataclass class C: d: int = field(default=D(), init=False)

C.d.name is not set, because d.set_name is never called. However, in this case:

class X: d: int = D()

X.d.name is set to 'd' when d.set_name is called during type.new.

The problem of course, is that in the dataclass case, when class C is initialized, and before the decorator is called, C.d is set to a Field() object, not to D(). It's only when the dataclass decorator is run that I change C.d from a Field to the value of D(). That means that the call to d.set_name(C, 'd') is skipped. See https://www.python.org/dev/peps/pep-0487/#implementation-details for details on how type.new works.

The only workaround I can think of is to emulate the part of PEP 487 where set_name is called. I can do this from within the @dataclass decorator when I'm initializing C.d. I'm not sure how great this solution is, since it's moving the call from class creation time to class decorator time. I think in 99+% of cases this would be fine, but you could likely write code that depends on side effects of being called during type.new.

Unless anyone has strong objections, I'm going to make the call to set_name in the @datacalss decorator. Since this is such a niche use case, I don't feel strongly that it needs to be in today's beta release, but if possible I'll get it in. I already have the patch written. And if it does get in but the consensus is that it's a bad idea, we can back it out.

Eric



More information about the Python-Dev mailing list