This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author Thomas701
Recipients Michael Robellard, Thomas701, UnHumbleBen, eric.smith, iivanyuk, juanpa.arrivillaga
Date 2021-10-21.22:12:24
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1634854344.36.0.582975596464.issue39247@roundup.psfhosted.org>
In-reply-to
Content
Agreed on everything but that last part, which I'm not sure I understand:
> If we allow descriptor to accept an iterable as well you could have multiple descriptors just like normal.
Could you give an example of what you mean with a regular class?

I've had a bit more time to think about this and I think one possible solution would be to mix the idea of a "descriptor" argument to the field constructor and the idea of not applying regular defaults at __init__ time.


Basically, at dataclass construction time (when the @dataclass decorator inspects and enhances the class), apply regular defaults at the class level unless the field has a descriptor argument, then apply that instead at the class level. At __init__ time, apply default_factories only unless the field has a descriptor argument, then do apply the regular default value.

If the implementation changed in these two ways, we'd have code like this work exactly as expected:

from dataclasses import dataclass, field


@dataclass
class Foo:
    _bar: int = field(init=False)
    
    @property
    def bar(self):
        return self._bar

    @bar.setter
    def bar(self, value):
        self._bar = value
    
    # field is required,
    # uses descriptor bar for get/set
    bar: int = field(descriptor=bar)

    # field is optional,
    # default of 5 is set at __init__ time
    # using the descriptor bar for get/set,
    bar: int = field(descriptor=bar, default=5)

    # field is optional,
    # default value is the descriptor instance,
    # it is set using regular attribute setter
    bar: int = field(default=bar)

Not only does this allow for descriptor to be used with dataclasses, it also fixes the use case of trying to have a descriptor instance as a default value because the descriptor wouldn't be used to get/set itself.

Although I should say, at this point, I'm clearly seeing this with blinders on to solve this particular problem... It's probable this solution breaks something somewhere that I'm not seeing. Fresh eyes appreciated :)
History
Date User Action Args
2021-10-21 22:12:24Thomas701setrecipients: + Thomas701, eric.smith, Michael Robellard, juanpa.arrivillaga, iivanyuk, UnHumbleBen
2021-10-21 22:12:24Thomas701setmessageid: <1634854344.36.0.582975596464.issue39247@roundup.psfhosted.org>
2021-10-21 22:12:24Thomas701linkissue39247 messages
2021-10-21 22:12:24Thomas701create