[pypy-issue] Issue #2771: Minimal support for __slots__ (pypy/pypy)
Hrvoje Nikšić
issues-reply at bitbucket.org
Sat Mar 3 17:58:27 EST 2018
New issue 2771: Minimal support for __slots__
https://bitbucket.org/pypy/pypy/issues/2771/minimal-support-for-__slots__
Hrvoje Nikšić:
While experimenting with PyPy on our company code base, I found that ignoring `__slots__` is a source of incompatibility with CPython. I understand why `__slots__` declarations are currently ignored - their primary use to save memory is simply unnecessary in PyPy. However, doing so leads to unnecessary behavior difference compared to CPython. Consider a class such as:
```
class Point:
__slots__ = 'x', 'y'
```
Here declaring `__slots__` is not only about memory savings; the intention is for the class to raise an `AttributeError` if someone assigns to `z` by mistake. Also, cclasses without dict are not foreign to PyPy. For example:
```
>>>> object().foo = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'foo'
>>>> [].foo = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute 'foo'
```
To allow creation of such classes from Python, I propose "supporting" `__slots__` as follows:
* a class that has `__slots__` gets flagged with a `NO_WRITE_TO_DICT` flag (unless `__slots__` contains `__dict__`)
* `object.__setattr__` refuses writing to `__dict__` of such classes
* each slot named in `__slots__` gets a class-level property whose `__set__` writes to the dict
* the actual dict is not returned by accessing `__dict__` on the instance.
For example:
```
p = Point()
p.x = 10 # allowed
p.y = 10 # allowed
p.z = 10 # forbidden, raises AttributeError
p.__dict__ # raises AttributeError, the dict is hidden
```
More information about the pypy-issue
mailing list