Fix "maximum recursion depth exceeded in GreenSocket.__del__"
Closes #137 Closes #148
This commit is contained in:
@@ -119,6 +119,9 @@ class GreenSocket(object):
|
|||||||
to save syscalls.
|
to save syscalls.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# This placeholder is to prevent __getattr__ from creating an infinite call loop
|
||||||
|
fd = None
|
||||||
|
|
||||||
def __init__(self, family_or_realsock=socket.AF_INET, *args, **kwargs):
|
def __init__(self, family_or_realsock=socket.AF_INET, *args, **kwargs):
|
||||||
should_set_nonblocking = kwargs.pop('set_nonblocking', True)
|
should_set_nonblocking = kwargs.pop('set_nonblocking', True)
|
||||||
if isinstance(family_or_realsock, six.integer_types):
|
if isinstance(family_or_realsock, six.integer_types):
|
||||||
@@ -175,6 +178,8 @@ class GreenSocket(object):
|
|||||||
# If we find such attributes - only attributes having __get__ might be cached.
|
# If we find such attributes - only attributes having __get__ might be cached.
|
||||||
# For now - I do not want to complicate it.
|
# For now - I do not want to complicate it.
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
|
if self.fd is None:
|
||||||
|
raise AttributeError(name)
|
||||||
attr = getattr(self.fd, name)
|
attr = getattr(self.fd, name)
|
||||||
setattr(self, name, attr)
|
setattr(self, name, attr)
|
||||||
return attr
|
return attr
|
||||||
@@ -216,7 +221,10 @@ class GreenSocket(object):
|
|||||||
self._closed = True
|
self._closed = True
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
self.close()
|
# This is in case self.close is not assigned yet (currently the constructor does it)
|
||||||
|
close = getattr(self, 'close', None)
|
||||||
|
if close is not None:
|
||||||
|
close()
|
||||||
|
|
||||||
def connect(self, address):
|
def connect(self, address):
|
||||||
if self.act_non_blocking:
|
if self.act_non_blocking:
|
||||||
|
@@ -9,10 +9,12 @@ import socket as _orig_sock
|
|||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
|
from nose.tools import eq_
|
||||||
|
|
||||||
from eventlet import event, greenio, debug
|
from eventlet import event, greenio, debug
|
||||||
from eventlet.hubs import get_hub
|
from eventlet.hubs import get_hub
|
||||||
from eventlet.green import select, socket, time, ssl
|
from eventlet.green import select, socket, time, ssl
|
||||||
from eventlet.support import get_errno, six
|
from eventlet.support import capture_stderr, get_errno, six
|
||||||
from tests import (
|
from tests import (
|
||||||
LimitedTestCase, main,
|
LimitedTestCase, main,
|
||||||
skip_with_pyevent, skipped, skip_if, skip_on_windows,
|
skip_with_pyevent, skipped, skip_if, skip_on_windows,
|
||||||
@@ -895,5 +897,21 @@ def test_set_nonblocking():
|
|||||||
assert new_flags == (orig_flags | os.O_NONBLOCK)
|
assert new_flags == (orig_flags | os.O_NONBLOCK)
|
||||||
|
|
||||||
|
|
||||||
|
def test_socket_del_fails_gracefully_when_not_fully_initialized():
|
||||||
|
# Regression introduced in da87716714689894f23d0db7b003f26d97031e83, reported in:
|
||||||
|
# * GH #137 https://github.com/eventlet/eventlet/issues/137
|
||||||
|
# * https://bugs.launchpad.net/oslo.messaging/+bug/1369999
|
||||||
|
|
||||||
|
class SocketSubclass(socket.socket):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
with capture_stderr() as err:
|
||||||
|
SocketSubclass()
|
||||||
|
|
||||||
|
assert err.getvalue() == ''
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
Reference in New Issue
Block a user