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.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    # 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):
 | 
			
		||||
        should_set_nonblocking = kwargs.pop('set_nonblocking', True)
 | 
			
		||||
        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.
 | 
			
		||||
    # For now - I do not want to complicate it.
 | 
			
		||||
    def __getattr__(self, name):
 | 
			
		||||
        if self.fd is None:
 | 
			
		||||
            raise AttributeError(name)
 | 
			
		||||
        attr = getattr(self.fd, name)
 | 
			
		||||
        setattr(self, name, attr)
 | 
			
		||||
        return attr
 | 
			
		||||
@@ -216,7 +221,10 @@ class GreenSocket(object):
 | 
			
		||||
        self._closed = True
 | 
			
		||||
 | 
			
		||||
    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):
 | 
			
		||||
        if self.act_non_blocking:
 | 
			
		||||
 
 | 
			
		||||
@@ -9,10 +9,12 @@ import socket as _orig_sock
 | 
			
		||||
import sys
 | 
			
		||||
import tempfile
 | 
			
		||||
 | 
			
		||||
from nose.tools import eq_
 | 
			
		||||
 | 
			
		||||
from eventlet import event, greenio, debug
 | 
			
		||||
from eventlet.hubs import get_hub
 | 
			
		||||
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 (
 | 
			
		||||
    LimitedTestCase, main,
 | 
			
		||||
    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)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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__':
 | 
			
		||||
    main()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user