Alternative to __slots__

I would like to have a built-in which creates a slot:

class X:
    a = slot(doc='field a')
    b = slot(doc='field b')

It virtually adds the name to the __slots__ list. No need to pass the field name as argument, it can be set in __set_name__().

The advantage over simple __slots__ is that it can have other options and perform some magic, like control the attribute type or even change the default constructor. It could be an alternative to dataclass.

6 Likes

Sort of related is an idea I’ve been discussing to defer slot creation until the first instance of a class is created. Until that time, __slots__ could be changed. My primary use case is dataclass(slots=True), but it could be more widely used.

4 Likes

That would have to have a way for meta classes to opt out of this. I have some classes where __slots__ has a side effect during class creation and the behaviour you propose would break this.

I would very much enjoy this. I’ve always disliked that __slots__ is a descriptor but we don’t get any of the extra benefits of it like other descriptors. Primarily the docstring

2 Likes

This change or something similar would be really great! I always see the constructs which refer to variables (identifiers) using strings as ugly hack. (another ugly example: T = TypeVar('T'))

How would we add __dict__ and __weakref__? Idea (not sure if possible):

class X:
    a = slot()
    b = slot()
    slot(dict=True, weakref=True)
    # Can the shadowing of __builtins__.dict be problematic here?
    # ...and maybe True could be the default to make slots more accessible?

…but I feel that using annotations would be (syntactically) a much cleaner approach (similar to ClassVar or InitVar in dataclasses). Of course it would need to be compatible with type annotations - for example like this:

class X:
    a: Slot
    b: Slot[int]
    slots(dict=True, weakref=True)

I am not sure if delayed evaluation of annotations would not make it complicated though…

Regarding docstrings I am a strong proponent of the almost forgotten attribute docstrings defined in PEP 257:

class X:
    """Class X"""
    a: Slot
    """field a"""
    b: Slot[int]
    """field b"""

I think they fit very well to the logic of all docstrings. They are supported by many existing tools like Sphinx or VS Code (Pylance) and I use them all the time.

Note: Their better support in Python was sadly rejected by Guido over 20 years ago: PEP 224 but maybe this is another theme to open later :slight_smile:

Edit: I confused the __dir__ and __dict__ attributes, fixed.

1 Like