[pypy-commit] pypy default: Fix issue #1492.
arigo
noreply at buildbot.pypy.org
Fri May 31 10:22:00 CEST 2013
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r64675:d439d104a605
Date: 2013-05-31 10:21 +0200
http://bitbucket.org/pypy/pypy/changeset/d439d104a605/
Log: Fix issue #1492.
Manual revert in socket.py. This re-introduces the change done in
2006 in 9db062bb60e3 (anders, implementing explicit refcounting on
the underlying _socket.socket objects). It reverts a later change
where, I think for goals of being more Python3-like, the refcounter
was moved to the class socket._socketobject. However this later
change is less compatible with CPython 2.x, as shown by eventlet.
diff --git a/lib-python/2.7/socket.py b/lib-python/2.7/socket.py
--- a/lib-python/2.7/socket.py
+++ b/lib-python/2.7/socket.py
@@ -96,6 +96,7 @@
_realsocket = socket
+_type = type
# WSA error codes
if sys.platform.lower().startswith("win"):
@@ -173,12 +174,18 @@
__doc__ = _realsocket.__doc__
+ __slots__ = ["_sock", "__weakref__"]
+
def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None):
if _sock is None:
_sock = _realsocket(family, type, proto)
+ elif _type(_sock) is _realsocket:
+ _sock._reuse()
+ # PyPy note about refcounting: implemented with _reuse()/_drop()
+ # on the class '_socket.socket'. Python 3 did it differently
+ # with a reference counter on this class 'socket._socketobject'
+ # instead, but it is a less compatible change (breaks eventlet).
self._sock = _sock
- self._io_refs = 0
- self._closed = False
def send(self, data, flags=0):
return self._sock.send(data, flags=flags)
@@ -208,7 +215,9 @@
sendto.__doc__ = _realsocket.sendto.__doc__
def close(self):
- # This function should not reference any globals. See issue #808164.
+ s = self._sock
+ if type(s) is _realsocket:
+ s._drop()
self._sock = _closedsocket()
close.__doc__ = _realsocket.close.__doc__
@@ -228,24 +237,7 @@
Return a regular file object corresponding to the socket. The mode
and bufsize arguments are as for the built-in open() function."""
- self._io_refs += 1
- return _fileobject(self, mode, bufsize)
-
- def _decref_socketios(self):
- if self._io_refs > 0:
- self._io_refs -= 1
- if self._closed:
- self.close()
-
- def _real_close(self):
- # This function should not reference any globals. See issue #808164.
- self._sock.close()
-
- def close(self):
- # This function should not reference any globals. See issue #808164.
- self._closed = True
- if self._io_refs <= 0:
- self._real_close()
+ return _fileobject(self._sock, mode, bufsize)
family = property(lambda self: self._sock.family, doc="the socket family")
type = property(lambda self: self._sock.type, doc="the socket type")
@@ -286,6 +278,8 @@
"_close"]
def __init__(self, sock, mode='rb', bufsize=-1, close=False):
+ if type(sock) is _realsocket:
+ sock._reuse()
self._sock = sock
self.mode = mode # Not actually used in this version
if bufsize < 0:
@@ -320,16 +314,11 @@
if self._sock:
self.flush()
finally:
- if self._sock:
- if self._close:
- self._sock.close()
- else:
- try:
- self._sock._decref_socketios()
- except AttributeError:
- pass # bah, someone built a _fileobject manually
- # with some unexpected replacement of the
- # _socketobject class
+ s = self._sock
+ if type(s) is _realsocket:
+ s._drop()
+ if self._close:
+ self._sock.close()
self._sock = None
def __del__(self):
More information about the pypy-commit
mailing list