pypy / pypy

PyPy is a very fast and compliant implementation of the Python language.
https://pypy.org
Other
993 stars 59 forks source link

TypeError: __weakref__ slot disallowed: we already got one #2681

Open gitlab-importer opened 7 years ago

gitlab-importer commented 7 years ago

In Heptapod by bitbucket_importer on Oct 13, 2017, 16:13

Created originally on Bitbucket by tkadm30 (soppy bear)

#!python
Traceback (most recent call last):
  File "/usr/local/pypy/pypy2-v5.9.0-linux32/lib-python/2.7/wsgiref/handlers.py", line 85, in run
    self.result = application(self.environ, self.start_response)
  File "/usr/local/pypy/pypy2-v5.9.0-linux32/lib-python/2.7/wsgiref/validate.py", line 176, in lint_app
    iterator = application(environ, start_response_wrapper)
  File "/home/erob/src/django-hotsauce-oauthclient/lib/wsgi_oauth2/middleware.py", line 292, in __call__
    return self.application(environ, start_response)
  File "lib/notmm/controllers/wsgi.pyx", line 136, in notmm.controllers.wsgi.BaseController.__call__
TypeError: __weakref__ slot disallowed: we already got one
gitlab-importer commented 7 years ago

In Heptapod by bitbucket_importer on Oct 13, 2017, 16:43

Created originally on Bitbucket by jamadden (Jason Madden)

I can produce the same error in both CPython and PyPy. It happens when a super class already defines __weakref__ and a subclass attempts to do the same:

PyPy

$ pypy
Python 2.7.13 (c925e7381036, Jun 05 2017, 20:53:58)
[PyPy 5.8.0 with GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> class Foo(object):
...   __slots__ = ('__weakref__',)
...
>>> class Bar(Foo):
...   __slots__ = ('__weakref__',)
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __weakref__ slot disallowed: we already got one

CPython:

$ python2.7
Python 2.7.14 (default, Sep 27 2017, 12:15:00)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.37)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> class Foo(object):
...    __slots__ = ("__weakref__",)
...
>>> class Bar(Foo):
...   __slots__ = ('__weakref__',)
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Error when calling the metaclass bases
    __weakref__ slot disallowed: either we already got one, or __itemsize__ != 0

I'm assuming you don't see this under CPython?

Historically I've seen things like this happen when code assumes that all string literals are identical (s = '__weakref__'; s2 = '__weakref__'; assert s is s2), but that can be (or used to be, at least) different under PyPy.

gitlab-importer commented 7 years ago

In Heptapod by @arigo on Oct 14, 2017, 05:02

The issue has something to do with cpyext, according to previous information.

tkadm30: please provide step-by-step instruction about how to reproduce the bug. Just having the traceback is useless for us. Please tell which packages to install ("pip install ...") and what program to run.

gitlab-importer commented 7 years ago

In Heptapod by bitbucket_importer on Oct 14, 2017, 09:27

Created originally on Bitbucket by tkadm30 (soppy bear)

This was a bug in libschevo and libdurus. Theses libraries are bundled in the django-hotsauce distribution. In specific, i found several classes (in persistent.py) defining :

#!python
...
__slots__ = ['__weakref__']

I changed them to __slots__ = [] and it solved the issue.

See: https://bitbucket.org/tkadm30/django-hotsauce/commits/9206398ebe5df6084fd959ae004a3bb09296b80b