Skip to main content

Enforces usage of '__slots__' for python classes

Project description

Enforces usage of __slots__ for python classes and provides pickling capabilities.

Examples

When defining a Slotted class with no __slots__ declaration, it assumes it has empty slots, which is equivalent of declaring __slots__ = ().

>>> from slotted import Slotted
>>> class Foo(Slotted):
...     pass  # implicit declaration of __slots__ = ()
...
>>> foo = Foo()
>>> foo.bar = 1
Traceback (most recent call last):
AttributeError: 'Foo' object has no attribute 'bar'

Slotted classes have pickling support:

>>> from slotted import Slotted
>>> from pickle import dumps, loads
>>> class Foo(Slotted):
...     __slots__ = ("bar", "foobar")
...
>>> foo = Foo()
>>> foo.bar = 1
>>> foo.foobar = 2
>>> another_foo = loads(dumps(foo))
>>> print(another_foo.bar, another_foo.foobar)
(1, 2)

Slotted classes can be mixed with regular classes as long as they and all of their bases implement __slots__.

>>> from slotted import Slotted
>>> class Bar(object):
...     __slots__ = ("bar",)
>>> class Foo(Bar, Slotted):
...     __slots__ = ("foo",)
...
>>> foo = Foo()

If any non-Slotted class anywhere in the chain does not implement __slots__, a TypeError exception is raised.

>>> from slotted import Slotted
>>> class Bar(object):
...     pass
>>> class Foo(Bar, Slotted):
...     __slots__ = ("foo",)
...
TypeError: base 'Bar' does not enforce '__slots__'

Slotted behavior can also be achieved by using the SlottedMeta metaclass.

>>> from slotted import SlottedMeta
>>> from six import add_metaclass
>>> @add_metaclass(SlottedMeta)
... class Foo(object):
...     pass  # implicit declaration of __slots__ = ()
...
>>> foo = Foo()
>>> foo.bar = 1
Traceback (most recent call last):
AttributeError: 'Foo' object has no attribute 'bar'

In Python 3, Slotted can be mixed with collections.abc classes without any issues. However, those classes do not define slots in Python 2. In order to work around that limitation, you can utilize automatically converted SlottedABC classes like so:

>>> from collections import Mapping
>>> from slotted import SlottedMapping
>>> issubclass(SlottedMapping, Mapping)
True
>>> class FooMapping(SlottedMapping):
...     __slots__ = ("_d",)
...     def __init__(self):
...         self._d = {"a": 1, "b": 2}
...     def __getitem__(self, item):
...         return self._d[item]
...     def __iter__(self):
...         for key in self._d:
...             yield key
...     def __len__(self):
...         return len(self._d)
...
>>> m = FooMapping()
>>> isinstance(m, Mapping)
True
>>> print(m["a"])
1
>>> m.bar = "foo"
Traceback (most recent call last):
AttributeError: 'FooMapping' object has no attribute 'bar'

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for slotted, version 0.0.3
Filename, size File type Python version Upload date Hashes
Filename, size slotted-0.0.3.tar.gz (4.7 kB) File type Source Python version None Upload date Hashes View

Supported by

Pingdom Pingdom Monitoring Google Google Object Storage and Download Analytics Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page