[Python-Dev] Issues with PEP 526 Variable Notation at the class level

Raymond Hettinger raymond.hettinger at gmail.com
Fri Dec 8 13:28:53 EST 2017



> On Dec 7, 2017, at 12:47 PM, Eric V. Smith <eric at trueblade.com> wrote:
> 
> On 12/7/17 3:27 PM, Raymond Hettinger wrote:
> ...
> 
>> I'm looking for guidance or workarounds for two issues that have arisen.
>> 
>> First, the use of default values seems to completely preclude the use of __slots__.  For example, this raises a ValueError:
>> 
>>    class A:
>>        __slots__ = ['x', 'y']
>>        x: int = 10
>>        y: int = 20
> 
> Hmm, I wasn't aware of that. I'm not sure I understand why that's an error. Maybe it could be fixed?

The way __slots__ works is that the type() metaclass automatically assigns member-objects to the class variables 'x' and 'y'.  Member objects are descriptors that do the actual lookup.

So, I don't think the language limitation can be "fixed".  Essentially, we're wanting to use the class variables 'x' and 'y' to hold both member objects and a default value.

> This doesn't help the general case (your class A), but it does at least solve it for dataclasses. Whether it should be actually included, and what the interface would look like, can be (and I'm sure will be!) argued.
> 
> The reason I didn't include it (as @dataclass(slots=True)) is because it has to return a new class, and the rest of the dataclass features just modifies the given class in place. I wanted to maintain that conceptual simplicity. But this might be a reason to abandon that. For what it's worth, attrs does have an @attr.s(slots=True) that returns a new class with __slots__ set.

I recommend that you follow the path taken by attrs and return a new class.   Otherwise, we're leaving users with a devil's choice.  You can have default values or you can have slots, but you can't have both.

The slots are pretty important.  With slots, a three attribute instance is only 64 bytes.  Without slots, it is 296 bytes.

> 
>> The second issue is that the different annotations give different signatures than would produced for manually written classes.  It is unclear what the best practice is for where to put the annotations and their associated docstrings.
> 
> I don't have any suggestions here.

I'm hoping the typing experts will chime in here.  The question is straight-forward.  Where should we look for the signature and docstring for constructing instances?  Should they be attached to the class, to __init__(), or to __new__() when it used.

It would be nice to have an official position on that before, it gets set in stone through arbitrary choices made by pycharm, pydoc, mypy, typing.NamedTuple, and dataclasses.dataclass.


Raymond






More information about the Python-Dev mailing list