Skip to content

support __slots__ #1268

@mtshiba

Description

@mtshiba

__slots__ is already handled specially in ty, but should be more fully supported in line with the Python specification.
__slots__ may not be a very commonly used feature, but several major libraries use it (e.g. attrs), and supporting it could improve inference results and error reporting.

ref: https://docs.python.org/3/reference/datamodel.html#slots

Here are the features that should be implemented:

  • Assume that the attributes defined in __slots__ are not unresolved
  • Attempting to read/write/declare an attribute that is not defined in __slots__ will be reported as an error
  • Defining a class variable to set a default value for a name that is defined in __slots__ will be reported as an error
  • Remove __dict__ and __weakref__ from classes that define __slots__
  • An error will be raised if nonempty __slots__ are defined for a class derived from a "variable-length" built-in type such as int, bytes, and tuple
class C:
    __slots__ = ("foo",)

    def __init__(self, foo, bar):
        self.foo = foo
        self.bar = bar  # error

    baz: int  # error (pyright doesn't report this as an error)
    foo: int = 1  # error

class D:
    __slots__ = ("bar",)

d = D()
reveal_type(d.bar)  # revealed: Any or Unknown
reveal_type(d.foo)  # error
d.bar = 1  # ok
# Classes with `__slots__` defined will not have a `__dict__` by default.
d.foo = 1  # error

class E:
    __slots__ = ("foo", "__dict__")

    def __init__(self, foo, bar):
        self.foo = foo
        self.bar = bar  # ok

# `F` has `__dict__` and `__weakref__`.
class F: ...

# Even if a class defines `__slots__`, if the superclass has `__dict__` or `__weakref__`,
# those attributes will be inherited.
class G(F):
    __slots__ = ("foo",)

    def __init__(self, foo, bar):
        self.foo = foo
        self.bar = bar  # ok

# error: nonempty __slots__ not supported for subtype of 'int'
class H(int):
    __slots__ = ("foo",)

related: #111

Metadata

Metadata

Assignees

Labels

runtime semanticsAccurate modeling of how Python's semantics work at runtime

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions