Index: Lib/test/test_support.py =================================================================== --- Lib/test/test_support.py (révision 80568) +++ Lib/test/test_support.py (copie de travail) @@ -724,41 +724,36 @@ sys.path[:] = self.original_value -class TransientResource(object): - - """Raise ResourceDenied if an exception is raised while the context manager - is in effect that matches the specified exception and attributes.""" - - def __init__(self, exc, **kwargs): - self.exc = exc - self.attrs = kwargs - - def __enter__(self): - return self - - def __exit__(self, type_=None, value=None, traceback=None): - """If type_ is a subclass of self.exc and value has attributes matching - self.attrs, raise ResourceDenied. Otherwise let the exception - propagate (if any).""" - if type_ is not None and issubclass(self.exc, type_): - for attr, attr_value in self.attrs.iteritems(): - if not hasattr(value, attr): - break - if getattr(value, attr) != attr_value: - break - else: - raise ResourceDenied("an optional resource is not available") - - @contextlib.contextmanager -def transient_internet(): +def transient_internet(timeout=60.0): """Return a context manager that raises ResourceDenied when various issues with the Internet connection manifest themselves as exceptions.""" - time_out = TransientResource(IOError, errno=errno.ETIMEDOUT) - socket_peer_reset = TransientResource(socket.error, errno=errno.ECONNRESET) - ioerror_peer_reset = TransientResource(IOError, errno=errno.ECONNRESET) - with time_out, socket_peer_reset, ioerror_peer_reset: + denied = ResourceDenied("an optional resource is not available") + def check_socket_error(err): + if isinstance(err, socket.timeout): + raise denied + if err.errno in (errno.ETIMEDOUT, errno.ECONNRESET): + raise denied + + old_timeout = socket.getdefaulttimeout() + try: + socket.setdefaulttimeout(timeout) yield + except socket.error as err: + check_socket_error(err) + raise + except IOError as err: + if err.errno in (errno.ETIMEDOUT, errno.ECONNRESET): + raise denied + # urllib replaces socket.error by IOerror: + # + # except socket.error, msg: + # raise IOError, ('socket error', msg), sys.exc_info()[2] + if 2 <= len(err.args) and isinstance(err.args[1], socket.error): + check_socket_error(err.args[1]) + raise + finally: + socket.setdefaulttimeout(old_timeout) @contextlib.contextmanager