On Fri, Sep 27, 2019 at 6:41 PM Ricky Teachey <ricky@teachey.org> wrote:
Here's an idea I was toying with in thinking about the problem this evening.

Currently, python complains if you try to add a class member that will conflict with a slot:

>>> class C:
...  __slots__="x"
...  x=1
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 'x' in __slots__ conflicts with class variable


What if the slots machinery were changed so that there was a warning propagated instead, and the conflicting member value(s) were saved in some appropriate place in the class namespace? Maybe something like __slot_conflicts__, or something like that.

>>> class C:
...  __slots__="x"
...  x=1
...
>>> C.__slot_conflicts__["x"]
1

This would give the decorator the opportunity to find the stuff that was put in those fields, and sort out the class definition in an expected way.

But it would silently do nothing if there was no class decorator to look at it.

However if we did `__slots__ = "__auto__"` then we might finagle it so that the initializers could be preserved:

class C:
    __slots__ = "__auto__"  # or MRAB's suggested __slots__ = ...
   x: float = 0.0
   y: float = 0.0

I'm not sure what to do with unannotated initializers -- I worry that it's a slippery slope, since we don't want methods to be accidentally slotified. But decorated methods may have a variety of types (e.g. class methods, static methods, properties) and user-defined decorators could do other things.

So I'd rather keep the rule for auto-slots simple: if there's an annotation (and it's not `ClassVar[something]`) then it's a slot, otherwise it's a class variable that can't be shadowed by an instance variable.

--
--Guido van Rossum (python.org/~guido)