CherryPy compatibility with PyPy 2
From a travis build error in #554, it appears we're no longer compatible with PyPy 2. cherrypy.wsgiserver2 uses socket internals that no longer behave as expected, at least not in PyPy 2.5:
$ coverage run --source=cherrymusicserver,cmbootstrap,audiotranscode $(command -v nosetests)
.....[16/May/2015:11:27:04] ENGINE Error in HTTPServer.tick
Traceback (most recent call last):
File "/home/travis/virtualenv/pypy-2.5.0/site-packages/cherrypy/wsgiserver/wsgiserver2.py", line 1968, in start
self.tick()
File "/home/travis/virtualenv/pypy-2.5.0/site-packages/cherrypy/wsgiserver/wsgiserver2.py", line 2059, in tick
conn = self.ConnectionClass(self, s, makefile)
File "/home/travis/virtualenv/pypy-2.5.0/site-packages/cherrypy/wsgiserver/wsgiserver2.py", line 1327, in __init__
self.rfile = makefile(sock, "rb", self.rbufsize)
File "/home/travis/virtualenv/pypy-2.5.0/site-packages/cherrypy/wsgiserver/wsgiserver2.py", line 1004, in __init__
socket._fileobject.__init__(self, *args, **kwargs)
File "/opt/python/pypy-2.5.0/lib-python/2.7/socket.py", line 300, in __init__
sock._reuse()
AttributeError: '_socketobject' object has no attribute '_reuse'
Also, on my box:
$ pypy --version
Python 2.7.9 (9c4588d731b7, Mar 26 2015, 11:07:33)
[PyPy 2.5.1 with GCC 4.9.2 20150304 (prerelease)]
$ pypy cherrymusic
[150516-14:31] Starting server on port 8080 ...
[150516-14:31] ERROR : [16/May/2015:14:31:42] ENGINE Error in 'start' listener <bound method Server.start of <cherrypy._cpserver.Server object at 0x00007ffb95b6a020>>
Traceback (most recent call last):
File "/home/til/projects/cherrymusic/server.cherrymusic/cherrypy/process/wspbus.py", line 197, in publish
output.append(listener(*args, **kwargs))
File "/home/til/projects/cherrymusic/server.cherrymusic/cherrypy/_cpserver.py", line 150, in start
self.httpserver, self.bind_addr = self.httpserver_from_self()
File "/home/til/projects/cherrymusic/server.cherrymusic/cherrypy/_cpserver.py", line 140, in httpserver_from_self
from cherrypy import _cpwsgi_server
File "/home/til/projects/cherrymusic/server.cherrymusic/cherrypy/_cpwsgi_server.py", line 7, in <module>
from cherrypy import wsgiserver
File "/home/til/projects/cherrymusic/server.cherrymusic/cherrypy/wsgiserver/__init__.py", line 11, in <module>
from wsgiserver2 import *
File "/home/til/projects/cherrymusic/server.cherrymusic/cherrypy/wsgiserver/wsgiserver2.py", line 97, in <module>
_fileobject_uses_str_type = isinstance(socket._fileobject(None)._rbuf, basestring)
File "/opt/pypy/lib-python/2.7/socket.py", line 300, in __init__
sock._reuse()
AttributeError: 'NoneType' object has no attribute '_reuse'
This is ultimately a bug with CherryPy, which is supposed to be compatible with PyPy.
Just as a note, fresh pypy install with 2.4 from the site and cherrypy 3.8.0 works for me
hmm, the test is running using cherrypy 3.8.0 as well, but does fail. Maybe the testsuite touches code that is otherwise not executed or only fails for some small subsystem, so it's not notable when using CM...
See the test output here: https://travis-ci.org/devsnd/cherrymusic/jobs/89947935
Note that cherrypy is used in Google App Engine's development server, would be great to see this fixed so the dev server can be run by PyPy. This is the error I see with PyPy 6.0:
C:\Program Files (x86)\Google\Cloud SDK\google-cloud-sdk\platform\google_appengine\lib\cherrypy\cherrypy\wsgiserver\wsgiserver2.py:97: RefCountingWarning: 'NoneType' object has no _reuse/_drop methods
{{
You make use (or a library you are using makes use) of the internal
classes '_socketobject' and '_fileobject' in socket.py, initializing
them with custom objects. On PyPy, these custom objects need two
extra methods, _reuse() and _drop(), that maintain an explicit
reference counter. When _drop() has been called as many times as
_reuse(), then the object should be freed.
Without these methods, you get the warning here. This is to
prevent the following situation: if your (or the library's) code
relies on reference counting for prompt closing, then on PyPy, the
__del__ method will be called later than on CPython. You can
easily end up in a situation where you open and close a lot of
(high-level) '_socketobject' or '_fileobject', but the (low-level)
custom objects will accumulate before their __del__ are called.
You quickly risk running out of file descriptors, for example.
}}
_fileobject_uses_str_type = isinstance(socket._fileobject(None)._rbuf, basestring)
Traceback (most recent call last):
File "C:\Program Files (x86)\Google\Cloud SDK\google-cloud-sdk\platform\google_appengine\_python_runtime.py", line 96, in <module>
_run_file(__file__, globals())
File "C:\Program Files (x86)\Google\Cloud SDK\google-cloud-sdk\platform\google_appengine\_python_runtime.py", line 90, in _run_file
execfile(_PATHS.script_file(script_name), globals_)
File "C:\Program Files (x86)\Google\Cloud SDK\google-cloud-sdk\platform\google_appengine\google\appengine\tools\devappserver2\python\runtime\runtime.py", line 199, in <module>
main()
File "C:\Program Files (x86)\Google\Cloud SDK\google-cloud-sdk\platform\google_appengine\google\appengine\tools\devappserver2\python\runtime\runtime.py", line 150, in main
os.remove(child_in_path)
WindowsError: [Error 32] The process cannot access the file because it is being used by another process: c:\users\mes65\appdata\local\temp\tmps177l_