[pypy-commit] pypy default: issue #1568
arigo
noreply at buildbot.pypy.org
Tue Aug 6 10:56:40 CEST 2013
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r65954:867a673cccfb
Date: 2013-08-06 10:56 +0200
http://bitbucket.org/pypy/pypy/changeset/867a673cccfb/
Log: issue #1568
Trying to change socket.py to explicitly crash if some other lib
messes around with internal implementation details --- more
specifically, if they build a _socketobject() or _fileobject() with
a custom object. The goal is to require these libraries to provide
the correct fix by adding _reuse() and _drop() methods on their
custom objects.
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
@@ -179,12 +179,21 @@
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:
+ else:
+ # 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.
+
+ # Note that a few libraries (like eventlet) poke at the
+ # private implementation of socket.py, passing custom
+ # objects to _socketobject(). These libraries need the
+ # following fix for use on PyPy: the custom objects need
+ # methods _reuse() and _drop() that maintains an explicit
+ # reference counter, starting at 0. When it drops back to
+ # zero, close() must be called.
_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
def send(self, data, flags=0):
@@ -216,9 +225,8 @@
def close(self):
s = self._sock
- if type(s) is _realsocket:
- s._drop()
self._sock = _closedsocket()
+ s._drop()
close.__doc__ = _realsocket.close.__doc__
def accept(self):
@@ -280,8 +288,14 @@
"_close"]
def __init__(self, sock, mode='rb', bufsize=-1, close=False):
- if type(sock) is _realsocket:
- sock._reuse()
+ # Note that a few libraries (like eventlet) poke at the
+ # private implementation of socket.py, passing custom
+ # objects to _fileobject(). These libraries need the
+ # following fix for use on PyPy: the custom objects need
+ # methods _reuse() and _drop() that maintains an explicit
+ # reference counter, starting at 0. When it drops back to
+ # zero, close() must be called.
+ sock._reuse()
self._sock = sock
self.mode = mode # Not actually used in this version
if bufsize < 0:
@@ -317,11 +331,10 @@
self.flush()
finally:
s = self._sock
- if type(s) is _realsocket:
- s._drop()
if self._close:
self._sock.close()
self._sock = None
+ s._drop()
def __del__(self):
try:
More information about the pypy-commit
mailing list