Commit 69a53c64 authored by Jason Madden's avatar Jason Madden

various module cleanups.

clean up socketcommon.
cleanup examples and servers.
cleanup server
cleanup util.
cleanup sslgte279
cleanup greentest.
cleanup corecffi.
cleanup fileobject.
cleanup select.py
cleanup socket2
fix naming.
cleanup socket3
cleanup hub.
cleanup threading.
cleanup lock
cleanup pywsgi.
cleanup _threading
cleanup patched_test_setup.
parent b098197a
......@@ -10,7 +10,7 @@ python-targets:
- 2
- 3
ignore-paths:
- examples/webchat
- examples/webchat/
- doc/
- build
- dist
......@@ -23,6 +23,10 @@ ignore-paths:
# This file has invalid syntax for Python 3, which is how
# landscape.io runs things
- gevent/_util_py2.py
# This is vendored with minimal changes
- gevent/_tblib.py
# likewise
- greentest/six.py
- greentest/getaddrinfo_module.py
ignore-patterns:
# disabled code
......@@ -47,3 +51,5 @@ pyflakes:
# F821: undefined name; caught better by pylint, where it can be
# controlled for the whole file/per-line
- F821
# F401: unused import; same story
- F401
......@@ -42,3 +42,32 @@ max-line-length=160
#notes=FIXME,XXX,TODO
# Disable that, we don't want them in the report (???)
notes=
[VARIABLES]
dummy-variables-rgx=_.*
[TYPECHECK]
# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E1101 when accessed. Python regular
# expressions are accepted.
# gevent: this is helpful for py3/py2 code.
generated-members=exc_clear
# List of classes names for which member attributes should not be checked
# (useful for classes with attributes dynamically set). This supports can work
# with qualified names.
ignored-classes=SSLContext, SSLSocket, greenlet
# List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis. It
# supports qualified module names, as well as Unix pattern matching.
ignored-modules=gevent._corecffi
[DESIGN]
max-attributes=10
[BASIC]
bad-functions=input
......@@ -2,6 +2,7 @@
[1] http://pypi.python.org/pypi/py-sendfile/
"""
# pylint:disable=import-error
from errno import EAGAIN
from sendfile import sendfile as original_sendfile
from gevent.socket import wait_write
......
......@@ -25,7 +25,7 @@ class PortForwarder(StreamServer):
StreamServer.__init__(self, listener, **kwargs)
self.dest = dest
def handle(self, source, address):
def handle(self, source, address): # pylint:disable=method-hidden
log('%s:%s accepted', *address[:2])
try:
dest = create_connection(self.dest)
......
from __future__ import print_function
# pylint:disable=import-error,broad-except,bare-except
import sys
import contextlib
......@@ -146,7 +147,7 @@ class PostgresConnectionPool(DatabaseConnectionPool):
return self.connect(*self.args, **self.kwargs)
if __name__ == '__main__':
def main():
import time
pool = PostgresConnectionPool("dbname=postgres", maxsize=3)
start = time.time()
......@@ -155,3 +156,6 @@ if __name__ == '__main__':
gevent.wait()
delay = time.time() - start
print('Running "select pg_sleep(1);" 4 times with 3 connections. Should take about 2 seconds: %.2fs' % delay)
if __name__ == '__main__':
main()
......@@ -11,7 +11,7 @@ from gevent.server import DatagramServer
class EchoServer(DatagramServer):
def handle(self, data, address):
def handle(self, data, address): # pylint:disable=method-hidden
print('%s: got %r' % (address[0], data))
self.socket.sendto(('Received %s bytes' % len(data)).encode('utf-8'), address)
......
......@@ -4,6 +4,7 @@ from gevent import socket
def application(environ, start_response):
assert environ
start_response('200 OK', [])
return []
......
......@@ -16,6 +16,7 @@ import sys
import re
import traceback
from cgi import escape
try:
import urllib2
from urlparse import urlparse
......@@ -74,13 +75,14 @@ def proxy(path, start_response, proxy_url):
response = ex
print('%s: %s %s' % (path, response.code, response.msg))
headers = [(k, v) for (k, v) in response.headers.items() if k not in drop_headers]
scheme, netloc, path, params, query, fragment = urlparse(path)
scheme, netloc, path, _params, _query, _fragment = urlparse(path)
host = (scheme or 'http') + '://' + netloc
except Exception as ex:
except Exception as ex: # pylint:disable=broad-except
sys.stderr.write('error while reading %s:\n' % path)
traceback.print_exc()
tb = traceback.format_exc()
start_response('502 Bad Gateway', [('Content-Type', 'text/html')])
# pylint:disable=deprecated-method
error_str = escape(str(ex) or ex.__class__.__name__ or 'Error')
error_str = '<h1>%s</h1><h2>%s</h2><pre>%s</pre>' % (error_str, escape(path), escape(tb))
return [_as_bytes(error_str)]
......
......@@ -5,7 +5,7 @@ from __future__ import print_function
from gevent import monkey; monkey.patch_all()
from gevent.pywsgi import WSGIServer
import time
import web
import web # pylint:disable=import-error
urls = ("/", "index",
'/long', 'long_polling')
......
......@@ -44,7 +44,7 @@ else:
# changing the behaviour of the stdlib if we're just imported; OTOH,
# under Python 2.6/2.7, test_urllib2net.py asserts that the class IS
# socket._fileobject (sigh), so we have to work around that.
class _fileobject(_fileobject):
class _fileobject(_fileobject): # pylint:disable=function-redefined
def __enter__(self):
return self
......@@ -74,7 +74,7 @@ else:
class _closedsocket(object):
__slots__ = []
def _dummy(*args, **kwargs):
def _dummy(*args, **kwargs): # pylint:disable=no-method-argument,unused-argument
raise error(EBADF, 'Bad file descriptor')
# All _delegate_methods must also be initialized here.
send = recv = recv_into = sendto = recvfrom = recvfrom_into = _dummy
......@@ -132,6 +132,7 @@ class socket(object):
return '<%s %s>' % (type(self).__name__, self._formatinfo())
def _formatinfo(self):
# pylint:disable=broad-except
try:
fileno = self.fileno()
except Exception as ex:
......@@ -246,7 +247,7 @@ class socket(object):
except timeout:
return EAGAIN
except error as ex:
if type(ex) is error:
if type(ex) is error: # pylint:disable=unidiomatic-typecheck
return ex.args[0]
else:
raise # gaierror is not silented by connect_ex
......@@ -399,7 +400,7 @@ class socket(object):
# example, bench_sendall.py yields ~264MB/s, while using 1MB yields
# ~653MB/s (matching CPython). 1MB is arbitrary and might be better
# chosen, say, to match a page size?
chunk_size = max(self.getsockopt(SOL_SOCKET, SO_SNDBUF), 1024 * 1024)
chunk_size = max(self.getsockopt(SOL_SOCKET, SO_SNDBUF), 1024 * 1024) # pylint:disable=no-member
data_sent = 0
end = None
......@@ -468,7 +469,7 @@ class socket(object):
# delegate the functions that we haven't implemented to the real socket object
_s = "def %s(self, *args): return self._sock.%s(*args)\n\n"
_m = None
for _m in set(_socketmethods) - set(locals()):
exec(_s % (_m, _m,))
del _m, _s
......
......@@ -4,6 +4,8 @@ Python 3 socket module.
"""
# Our import magic sadly makes this warning useless
# pylint: disable=undefined-variable
# pylint: disable=too-many-statements,too-many-branches
# pylint: disable=too-many-public-methods,unused-argument
import io
import os
......@@ -25,7 +27,7 @@ __imports__ = _socketcommon.__imports__
__dns__ = _socketcommon.__dns__
SocketIO = __socket__.SocketIO
SocketIO = __socket__.SocketIO # pylint:disable=no-member
def _get_memory(data):
......@@ -91,7 +93,7 @@ class socket(object):
def type(self):
# See https://github.com/gevent/gevent/pull/399
if self.timeout != 0.0:
return self._sock.type & ~_socket.SOCK_NONBLOCK
return self._sock.type & ~_socket.SOCK_NONBLOCK # pylint:disable=no-member
else:
return self._sock.type
......@@ -106,7 +108,7 @@ class socket(object):
"""Wrap __repr__() to reveal the real class name."""
try:
s = _socket.socket.__repr__(self._sock)
except Exception as ex:
except Exception as ex: # pylint:disable=broad-except
# Observed on Windows Py3.3, printing the repr of a socket
# that just sufferred a ConnectionResetError [WinError 10054]:
# "OverflowError: no printf formatter to display the socket descriptor in decimal"
......@@ -220,7 +222,7 @@ class socket(object):
if reading and writing:
buffer = io.BufferedRWPair(raw, raw, buffering)
elif reading:
buffer = io.BufferedReader(raw, buffering)
buffer = io.BufferedReader(raw, buffering) # pylint:disable=redefined-variable-type
else:
assert writing
buffer = io.BufferedWriter(raw, buffering)
......@@ -295,7 +297,7 @@ class socket(object):
except timeout:
return EAGAIN
except error as ex:
if type(ex) is error:
if type(ex) is error: # pylint:disable=unidiomatic-typecheck
return ex.args[0]
else:
raise # gaierror is not silented by connect_ex
......@@ -426,7 +428,7 @@ class socket(object):
# because it's not cooperative.
def _sendfile_use_sendfile(self, file, offset=0, count=None):
# This is called directly by tests
raise __socket__._GiveupOnSendfile()
raise __socket__._GiveupOnSendfile() # pylint:disable=no-member
def _sendfile_use_send(self, file, offset=0, count=None):
self._check_sendfile_params(file, offset, count)
......@@ -503,6 +505,7 @@ class socket(object):
# get/set_inheritable new in 3.4
if hasattr(os, 'get_inheritable') or hasattr(os, 'get_handle_inheritable'):
# pylint:disable=no-member
if os.name == 'nt':
def get_inheritable(self):
return os.get_handle_inheritable(self.fileno())
......@@ -531,7 +534,7 @@ if sys.version_info[:2] == (3, 4) and sys.version_info[:3] <= (3, 4, 2):
# Therefore, on these old versions, we must preserve it as an enum; while this
# seems like it could lead to non-green behaviour, code on those versions
# cannot possibly be using SocketType as a class anyway.
SocketType = __socket__.SocketType
SocketType = __socket__.SocketType # pylint:disable=no-member
# Fixup __all__; note that we get exec'd multiple times during unit tests
if 'SocketType' in __implements__:
__implements__.remove('SocketType')
......@@ -591,9 +594,9 @@ elif 'socketpair' in __implements__:
# PyPy needs drop and reuse
def _do_reuse_or_drop(socket, methname):
def _do_reuse_or_drop(sock, methname):
try:
method = getattr(socket, methname)
method = getattr(sock, methname)
except (AttributeError, TypeError):
pass
else:
......@@ -660,7 +663,7 @@ class _basefileobject(object):
def __del__(self):
try:
self.close()
except:
except: # pylint:disable=bare-except
# close() may fail if __init__ didn't complete
pass
......@@ -695,7 +698,7 @@ class _basefileobject(object):
self._wbuf.append(data)
self._wbuf_len += len(data)
if (self._wbufsize == 0 or (self._wbufsize == 1 and b'\n' in data) or
(self._wbufsize > 1 and self._wbuf_len >= self._wbufsize)):
(self._wbufsize > 1 and self._wbuf_len >= self._wbufsize)):
self.flush()
def writelines(self, list):
......@@ -704,7 +707,7 @@ class _basefileobject(object):
lines = filter(None, map(str, list))
self._wbuf_len += sum(map(len, lines))
self._wbuf.extend(lines)
if (self._wbufsize <= 1 or self._wbuf_len >= self._wbufsize):
if self._wbufsize <= 1 or self._wbuf_len >= self._wbufsize:
self.flush()
def read(self, size=-1):
......@@ -775,6 +778,7 @@ class _basefileobject(object):
return buf.getvalue()
def readline(self, size=-1):
# pylint:disable=too-many-return-statements
buf = self._rbuf
buf.seek(0, 2) # seek end
if buf.tell() > 0:
......@@ -786,7 +790,7 @@ class _basefileobject(object):
self._rbuf.write(buf.read())
return bline
del bline
if size < 0:
if size < 0: # pylint:disable=too-many-nested-blocks
# Read until \n or EOF, whichever comes first
if self._rbufsize <= 1:
# Speed up unbuffered case
......@@ -931,7 +935,7 @@ else:
def __del__(self):
try:
self.close()
except:
except: # pylint:disable=bare-except
# close() may fail if __init__ didn't complete
pass
......
......@@ -2,60 +2,69 @@
from __future__ import absolute_import
# standard functions and classes that this module re-implements in a gevent-aware way:
_implements = ['create_connection',
'socket',
'SocketType',
'fromfd',
'socketpair']
__dns__ = ['getaddrinfo',
'gethostbyname',
'gethostbyname_ex',
'gethostbyaddr',
'getnameinfo',
'getfqdn']
_implements = [
'create_connection',
'socket',
'SocketType',
'fromfd',
'socketpair',
]
__dns__ = [
'getaddrinfo',
'gethostbyname',
'gethostbyname_ex',
'gethostbyaddr',
'getnameinfo',
'getfqdn',
]
_implements += __dns__
# non-standard functions that this module provides:
__extensions__ = ['cancel_wait',
'wait_read',
'wait_write',
'wait_readwrite']
__extensions__ = [
'cancel_wait',
'wait_read',
'wait_write',
'wait_readwrite',
]
# standard functions and classes that this module re-imports
__imports__ = ['error',
'gaierror',
'herror',
'htonl',
'htons',
'ntohl',
'ntohs',
'inet_aton',
'inet_ntoa',
'inet_pton',
'inet_ntop',
'timeout',
'gethostname',
'getprotobyname',
'getservbyname',
'getservbyport',
'getdefaulttimeout',
'setdefaulttimeout',
# Windows:
'errorTab',
]
__py3_imports__ = [# Python 3
'AddressFamily',
'SocketKind',
'CMSG_LEN',
'CMSG_SPACE',
'dup',
'if_indextoname',
'if_nameindex',
'if_nametoindex',
'sethostname']
__imports__ = [
'error',
'gaierror',
'herror',
'htonl',
'htons',
'ntohl',
'ntohs',
'inet_aton',
'inet_ntoa',
'inet_pton',
'inet_ntop',
'timeout',
'gethostname',
'getprotobyname',
'getservbyname',
'getservbyport',
'getdefaulttimeout',
'setdefaulttimeout',
# Windows:
'errorTab',
]
__py3_imports__ = [
# Python 3
'AddressFamily',
'SocketKind',
'CMSG_LEN',
'CMSG_SPACE',
'dup',
'if_indextoname',
'if_nameindex',
'if_nametoindex',
'sethostname',
]
__imports__.extend(__py3_imports__)
......@@ -66,7 +75,7 @@ from gevent.hub import ConcurrentObjectUseError
from gevent.timeout import Timeout
is_windows = sys.platform == 'win32'
# pylint:disable=no-name-in-module,unused-import
if is_windows:
# no such thing as WSAEPERM or error code 10001 according to winsock.h or MSDN
from errno import WSAEINVAL as EINVAL
......@@ -94,21 +103,21 @@ import _socket
_realsocket = _socket.socket
import socket as __socket__
for name in __imports__[:]:
_name = _value = None
for _name in __imports__[:]:
try:
value = getattr(__socket__, name)
globals()[name] = value
_value = getattr(__socket__, _name)
globals()[_name] = _value
except AttributeError:
__imports__.remove(name)
__imports__.remove(_name)
for name in __socket__.__all__:
value = getattr(__socket__, name)
if isinstance(value, integer_types) or isinstance(value, string_types):
globals()[name] = value
__imports__.append(name)
for _name in __socket__.__all__:
_value = getattr(__socket__, _name)
if isinstance(_value, integer_types) or isinstance(_value, string_types):
globals()[_name] = _value
__imports__.append(_name)
del name, value
del _name, _value
class _NONE(object):
......@@ -117,7 +126,7 @@ class _NONE(object):
return "<default value>"
_NONE = _NONE()
_timeout_error = timeout
_timeout_error = timeout # pylint: disable=undefined-variable
def wait(io, timeout=None, timeout_exc=_NONE):
......@@ -179,6 +188,7 @@ def wait_write(fileno, timeout=None, timeout_exc=_NONE, event=_NONE):
.. seealso:: :func:`cancel_wait`
"""
# pylint:disable=unused-argument
io = get_hub().loop.io(fileno, 2)
return wait(io, timeout, timeout_exc)
......@@ -196,11 +206,12 @@ def wait_readwrite(fileno, timeout=None, timeout_exc=_NONE, event=_NONE):
.. seealso:: :func:`cancel_wait`
"""
# pylint:disable=unused-argument
io = get_hub().loop.io(fileno, 3)
return wait(io, timeout, timeout_exc)
#: The exception raised by default on a call to :func:`cancel_wait`
cancel_wait_ex = error(EBADF, 'File descriptor was closed in another greenlet')
cancel_wait_ex = error(EBADF, 'File descriptor was closed in another greenlet') # pylint: disable=undefined-variable
def cancel_wait(watcher, error=cancel_wait_ex):
......@@ -300,11 +311,12 @@ def getfqdn(name=''):
possibly existing aliases. In case no FQDN is available, hostname
from gethostname() is returned.
"""
# pylint: disable=undefined-variable
name = name.strip()
if not name or name == '0.0.0.0':
name = gethostname()
try:
hostname, aliases, ipaddrs = gethostbyaddr(name)
hostname, aliases, _ = gethostbyaddr(name)
except error:
pass
else:
......
......@@ -10,11 +10,12 @@ This module implements cooperative SSL socket wrappers.
from __future__ import absolute_import
# Our import magic sadly makes this warning useless
# pylint: disable=undefined-variable
# pylint: disable=too-many-instance-attributes,too-many-locals,too-many-statements,too-many-branches
# pylint: disable=arguments-differ,too-many-public-methods
import ssl as __ssl__
_ssl = __ssl__._ssl
_ssl = __ssl__._ssl # pylint:disable=no-member
import errno
from gevent._socket2 import socket
......@@ -23,33 +24,35 @@ from gevent.socket import error as socket_error
from gevent.socket import timeout as _socket_timeout
from gevent.hub import PYPY
__implements__ = ['SSLContext',
'SSLSocket',
'wrap_socket',
'get_server_certificate',
'create_default_context',
'_create_unverified_context',
'_create_default_https_context',
'_create_stdlib_context']
__implements__ = [
'SSLContext',
'SSLSocket',
'wrap_socket',
'get_server_certificate',
'create_default_context',
'_create_unverified_context',
'_create_default_https_context',
'_create_stdlib_context',
]
__imports__ = []
# Import all symbols from Python's ssl.py, except those that we are implementing
# and "private" symbols.
value = None
for name in dir(__ssl__):
if name in __implements__:
_name = _value = None
for _name in dir(__ssl__):
if _name in __implements__:
continue
if name.startswith('__'):
if _name.startswith('__'):
continue
if name == 'socket':
if _name == 'socket':
# SSLSocket *must* subclass gevent.socket.socket; see issue 597
continue
value = getattr(__ssl__, name)
globals()[name] = value
__imports__.append(name)
_value = getattr(__ssl__, _name)
globals()[_name] = _value
__imports__.append(_name)
del name, value
del _name, _value
try:
_delegate_methods
......@@ -58,7 +61,7 @@ except NameError: # PyPy doesn't expose this detail
__all__ = __implements__ + __imports__
orig_SSLContext = __ssl__.SSLContext
orig_SSLContext = __ssl__.SSLContext # pylint: disable=no-member
class SSLContext(orig_SSLContext):
......@@ -99,7 +102,7 @@ def create_default_context(purpose=Purpose.SERVER_AUTH, cafile=None,
if purpose == Purpose.SERVER_AUTH:
# verify certs and host name in client mode
context.verify_mode = CERT_REQUIRED
context.check_hostname = True
context.check_hostname = True # pylint: disable=attribute-defined-outside-init
elif purpose == Purpose.CLIENT_AUTH:
# Prefer the server's ciphers by default so that we get stronger
# encryption
......@@ -122,9 +125,9 @@ def create_default_context(purpose=Purpose.SERVER_AUTH, cafile=None,
return context
def _create_unverified_context(protocol=PROTOCOL_SSLv23, cert_reqs=None,
check_hostname=False, purpose=Purpose.SERVER_AUTH,
certfile=None, keyfile=None,
cafile=None, capath=None, cadata=None):
check_hostname=False, purpose=Purpose.SERVER_AUTH,
certfile=None, keyfile=None,
cafile=None, capath=None, cadata=None):
"""Create a SSLContext object for Python stdlib modules
All Python stdlib modules shall use this function to create SSLContext
......@@ -144,7 +147,7 @@ def _create_unverified_context(protocol=PROTOCOL_SSLv23, cert_reqs=None,
if cert_reqs is not None:
context.verify_mode = cert_reqs
context.check_hostname = check_hostname
context.check_hostname = check_hostname # pylint: disable=attribute-defined-outside-init
if keyfile and not certfile:
raise ValueError("certfile must be specified")
......@@ -184,7 +187,8 @@ class SSLSocket(socket):
suppress_ragged_eofs=True, npn_protocols=None, ciphers=None,
server_hostname=None,
_context=None):
# fileno is ignored
# pylint: disable=unused-argument
if _context:
self._context = _context
else:
......@@ -285,8 +289,8 @@ class SSLSocket(socket):
self._sslobj.context = ctx
def dup(self):
raise NotImplemented("Can't dup() %s instances" %
self.__class__.__name__)
raise NotImplementedError("Can't dup() %s instances" %
self.__class__.__name__)
def _checkClosed(self, msg=None):
# raise an exception here if you wish to check for spurious closes
......@@ -469,8 +473,8 @@ class SSLSocket(socket):
if self._sslobj:
if flags != 0:
raise ValueError(
"non-zero flags not allowed in calls to recv_into() on %s" %
self.__class__)
"non-zero flags not allowed in calls to recv_into() on %s" %
self.__class__)
return self.read(nbytes, buffer)
else:
return socket.recv_into(self, buffer, nbytes, flags)
......@@ -559,7 +563,7 @@ class SSLSocket(socket):
def _real_close(self):
self._sslobj = None
socket._real_close(self)
socket._real_close(self) # pylint: disable=no-member
def do_handshake(self):
"""Perform a TLS/SSL handshake."""
......@@ -623,9 +627,9 @@ class SSLSocket(socket):
newsock, addr = socket.accept(self)
newsock = self.context.wrap_socket(newsock,
do_handshake_on_connect=self.do_handshake_on_connect,
suppress_ragged_eofs=self.suppress_ragged_eofs,
server_side=True)
do_handshake_on_connect=self.do_handshake_on_connect,
suppress_ragged_eofs=self.suppress_ragged_eofs,
server_side=True)
return newsock, addr
def makefile(self, mode='r', bufsize=-1):
......@@ -648,8 +652,8 @@ class SSLSocket(socket):
raise ValueError("Unsupported channel binding type")
if cb_type != "tls-unique":
raise NotImplementedError(
"{0} channel binding type not implemented"
.format(cb_type))
"{0} channel binding type not implemented"
.format(cb_type))
if self._sslobj is None:
return None
return self._sslobj.tls_unique_cb()
......@@ -700,7 +704,7 @@ def get_server_certificate(addr, ssl_version=PROTOCOL_SSLv23, ca_certs=None):
If 'ca_certs' is specified, validate the server cert against it.
If 'ssl_version' is specified, use it in the connection attempt."""
host, port = addr
_, _ = addr
if ca_certs is not None:
cert_reqs = CERT_REQUIRED
else:
......
......@@ -90,6 +90,7 @@ class RLock(object):
class Condition(object):
# pylint:disable=method-hidden
def __init__(self, lock=None):
if lock is None:
......@@ -127,7 +128,7 @@ class Condition(object):
def _release_save(self):
self.__lock.release() # No state to save
def _acquire_restore(self, x):
def _acquire_restore(self, x): # pylint:disable=unused-argument
self.__lock.acquire() # Ignore saved state
def _is_owned(self):
......@@ -234,7 +235,7 @@ class BoundedSemaphore(Semaphore):
self._initial_value = value
def release(self):
if self.Semaphore__value >= self._initial_value:
if self.Semaphore__value >= self._initial_value: # pylint:disable=no-member
raise ValueError("Semaphore released too many times")
return Semaphore.release(self)
......@@ -462,6 +463,7 @@ class Queue:
# Initialize the queue representation
def _init(self, maxsize):
# pylint:disable=unused-argument
self.queue = deque()
def _qsize(self, len=len):
......@@ -489,9 +491,11 @@ class PriorityQueue(Queue):
return len(self.queue)
def _put(self, item, heappush=heapq.heappush):
# pylint:disable=arguments-differ
heappush(self.queue, item)
def _get(self, heappop=heapq.heappop):
# pylint:disable=arguments-differ
return heappop(self.queue)
......
......@@ -32,11 +32,12 @@ except AttributeError:
class _Greenlet_stdreplace(Greenlet):
# A greenlet that replaces sys.std[in/out/err] while running.
_fileobj = None
saved = None
def switch(self, *args, **kw):
if self._fileobj is not None:
self.switch_in()
Greenlet.switch(self, *args, **kw)
Greenlet.switch(self, *args, **kw) # pylint:disable=no-member
def switch_in(self):
self.saved = sys.stdin, sys.stderr, sys.stdout
......@@ -118,7 +119,7 @@ class BackdoorServer(StreamServer):
_locals['__builtins__'] = builtins
return _locals
def handle(self, conn, address):
def handle(self, conn, _address): # pylint: disable=method-hidden
"""
Interact with one remote user.
......
......@@ -66,6 +66,8 @@ class BaseServer(object):
closing of the socket, fixing ResourceWarnings under Python 3 and PyPy.
"""
# pylint: disable=too-many-instance-attributes,bare-except,broad-except
#: the number of seconds to sleep in case there was an error in accept() call
#: for consecutive errors the delay will double until it reaches max_delay
#: when accept() finally succeeds the delay will be reset to min_delay again
......@@ -92,6 +94,10 @@ class BaseServer(object):
self._stop_event.set()
self._watcher = None
self._timer = None
self._handle = None
# XXX: FIXME: Subclasses rely on the presence or absence of the
# `socket` attribute to determine whether we are open/should be opened.
# Instead, have it be None.
self.pool = None
try:
self.set_listener(listener)
......@@ -213,6 +219,8 @@ class BaseServer(object):
break
def full(self):
# copied from self.pool
# pylint: disable=method-hidden
return False
def __repr__(self):
......
......@@ -15,7 +15,7 @@ from gevent.lock import RLock
try: # Py2
import __builtin__ as builtins
_allowed_module_name_types = (basestring,)
_allowed_module_name_types = (basestring,) # pylint:disable=undefined-variable
__target__ = '__builtin__'
except ImportError:
import builtins
......
# pylint: disable=too-many-lines, protected-access, redefined-outer-name
# pylint: disable=too-many-lines, protected-access, redefined-outer-name, not-callable
from __future__ import absolute_import, print_function
import sys
import os
......@@ -6,13 +6,15 @@ import traceback
import signal as signalmodule
__all__ = ['get_version',
'get_header_version',
'supported_backends',
'recommended_backends',
'embeddable_backends',
'time',
'loop']
__all__ = [
'get_version',
'get_header_version',
'supported_backends',
'recommended_backends',
'embeddable_backends',
'time',
'loop',
]
try:
import gevent._corecffi
......@@ -21,10 +23,10 @@ except ImportError:
# Not built yet
import gevent._corecffi_build
gevent._corecffi_build.ffi.compile()
import gevent._corecffi
import gevent._corecffi # pylint: disable=no-member,no-name-in-module,useless-suppression
ffi = gevent._corecffi.ffi
libev = gevent._corecffi.lib
ffi = gevent._corecffi.ffi # pylint:disable=no-member
libev = gevent._corecffi.lib # pylint:disable=no-member
if hasattr(libev, 'vfd_open'):
# Must be on windows
......@@ -107,24 +109,24 @@ def _python_callback(handle, revents):
# to the 'onerror' handler, which
# is not what we want; that can permanently wedge the loop depending
# on which callback was executing
watcher = ffi.from_handle(handle)
args = watcher.args
the_watcher = ffi.from_handle(handle)
args = the_watcher.args
if args is None:
# Legacy behaviour from corecext: convert None into ()
# See test__core_watcher.py
args = _NOARGS
if len(args) > 0 and args[0] == GEVENT_CORE_EVENTS:
args = (revents, ) + args[1:]
watcher.callback(*args)
except:
watcher._exc_info = sys.exc_info()
the_watcher.callback(*args)
except: # pylint:disable=bare-except
the_watcher._exc_info = sys.exc_info()
# Depending on when the exception happened, the watcher
# may or may not have been stopped. We need to make sure its
# memory stays valid so we can stop it at the ev level if needed.
watcher.loop._keepaliveset.add(watcher)
the_watcher.loop._keepaliveset.add(the_watcher)
return -1
else:
if watcher in watcher.loop._keepaliveset:
if the_watcher in the_watcher.loop._keepaliveset:
# It didn't stop itself
return 0
return 1 # It stopped itself
......@@ -146,9 +148,9 @@ def _python_handle_error(handle, revents):
if revents & (libev.EV_READ | libev.EV_WRITE):
try:
watcher.stop()
except:
except: # pylint:disable=bare-except
watcher.loop.handle_error(watcher, *sys.exc_info())
return
return # pylint:disable=lost-exception
libev.python_handle_error = _python_handle_error
......@@ -254,7 +256,7 @@ if sys.version_info[0] >= 3:
basestring = (bytes, str)
integer_types = int,
else:
import __builtin__
import __builtin__ # pylint:disable=import-error
basestring = __builtin__.basestring
integer_types = (int, __builtin__.long)
......@@ -289,9 +291,9 @@ def _check_flags(flags):
flags &= libev.EVBACKEND_MASK
if not flags:
return
if not (flags & libev.EVBACKEND_ALL):
if not flags & libev.EVBACKEND_ALL:
raise ValueError('Invalid value for backend: 0x%x' % flags)
if not (flags & libev.ev_supported_backends()):
if not flags & libev.ev_supported_backends():
as_list = [_str_hex(x) for x in _flags_to_list(flags)]
raise ValueError('Unsupported backend: %s' % '|'.join(as_list))
......@@ -333,6 +335,7 @@ def _loop_callback(*args, **kwargs):
class loop(object):
# pylint:disable=too-many-public-methods
error_handler = None
......@@ -406,7 +409,7 @@ class loop(object):
# work to rethrow the exception is done by the onerror callback
pass
def _run_callbacks(self, evloop, _, revents):
def _run_callbacks(self, _evloop, _, _revents):
count = 1000
libev.ev_timer_stop(self._ptr, self._timer0)
while self._callbacks and count > 0:
......@@ -424,7 +427,7 @@ class loop(object):
try:
callback(*args)
except:
except: # pylint:disable=bare-except
# If we allow an exception to escape this method (while we are running the ev callback),
# then CFFI will print the error and libev will continue executing.
# There are two problems with this. The first is that the code after
......@@ -442,11 +445,11 @@ class loop(object):
# We take a similar approach (but are extra careful about printing)
try:
self.handle_error(cb, *sys.exc_info())
except:
except: # pylint:disable=bare-except
try:
print("Exception while handling another error", file=sys.stderr)
traceback.print_exc()
except:
except: # pylint:disable=bare-except
pass # Nothing we can do here
finally:
# Note, this must be reset here, because cb.args is used as a flag in callback class,
......@@ -493,11 +496,11 @@ class loop(object):
def _handle_syserr(self, message, errno):
try:
errno = os.strerror(errno)
except:
except: # pylint:disable=bare-except
traceback.print_exc()
try:
message = '%s: %s' % (message, errno)
except:
except: # pylint:disable=bare-except
traceback.print_exc()
self.handle_error(None, SystemError, SystemError(message), None)
......@@ -511,7 +514,7 @@ class loop(object):
else:
self._default_handle_error(context, type, value, tb)
def _default_handle_error(self, context, type, value, tb):
def _default_handle_error(self, context, type, value, tb): # pylint:disable=unused-argument
# note: Hub sets its own error handler so this is not used by gevent
# this is here to make core.loop usable without the rest of gevent
traceback.print_exception(type, value, tb)
......@@ -750,7 +753,7 @@ class watcher(object):
@classmethod
def _init_subclasses(cls):
for subclass in cls.__subclasses__():
for subclass in cls.__subclasses__(): # pylint:disable=no-member
watcher_type = subclass._watcher_type
subclass._watcher_struct_pointer_type = ffi.typeof('struct ' + watcher_type + '*')
subclass._watcher_callback = ffi.addressof(libev,
......
......@@ -133,7 +133,7 @@ class FileObjectThread(object):
def close():
try:
fobj.close()
except:
except: # pylint:disable=bare-except
return sys.exc_info()
exc_info = self.threadpool.apply(close)
if exc_info:
......@@ -168,19 +168,21 @@ class FileObjectThread(object):
raise StopIteration
__next__ = next
def _wraps(method):
def x(self, *args, **kwargs):
fobj = self.io
if fobj is None:
raise FileObjectClosed
return self._apply(getattr(fobj, method), args, kwargs)
x.__name__ = method
return x
for method in ('read', 'readinto', 'readline', 'readlines', 'write', 'writelines', 'xreadlines'):
locals()[method] = _wraps(method)
del method
del _wraps
def _wraps(method):
def x(self, *args, **kwargs):
fobj = self.io
if fobj is None:
raise FileObjectClosed
return self._apply(getattr(fobj, method), args, kwargs)
x.__name__ = method
return x
_method = None
for _method in ('read', 'readinto', 'readline', 'readlines', 'write', 'writelines', 'xreadlines'):
setattr(FileObjectThread, _method, _wraps(_method))
del _method
del _wraps
try:
......@@ -203,7 +205,7 @@ class FileObjectBlock(object):
self.io = fobj
def __repr__(self):
return '<%s %r>' % (self.io, )
return '<%s %r>' % (self.__class__.__name__, self.io, )
def __getattr__(self, item):
assert item != '_fobj'
......
# Copyright (c) 2009-2012 Denis Bilenko. See LICENSE for details.
from __future__ import absolute_import
import sys
from greenlet import greenlet
from gevent.hub import GreenletExit
from gevent.hub import InvalidSwitchError
from gevent.hub import PY3
......@@ -8,7 +9,6 @@ from gevent.hub import PYPY
from gevent.hub import Waiter
from gevent.hub import get_hub
from gevent.hub import getcurrent
from gevent.hub import greenlet
from gevent.hub import iwait
from gevent.hub import reraise
from gevent.hub import wait
......@@ -18,9 +18,11 @@ from gevent._tblib import load_traceback
from collections import deque
__all__ = ['Greenlet',
'joinall',
'killall']
__all__ = [
'Greenlet',
'joinall',
'killall',
]
if PYPY:
......
......@@ -3,24 +3,28 @@
Event-loop hub.
"""
from __future__ import absolute_import
# XXX: FIXME: Refactor to make this smaller
# pylint:disable=too-many-lines
from functools import partial as _functools_partial
import os
import sys
import traceback
from greenlet import greenlet, getcurrent, GreenletExit
from greenlet import greenlet as RawGreenlet, getcurrent, GreenletExit
__all__ = ['getcurrent',
'GreenletExit',
'spawn_raw',
'sleep',
'kill',
'signal',
'reinit',
'get_hub',
'Hub',
'Waiter']
__all__ = [
'getcurrent',
'GreenletExit',
'spawn_raw',
'sleep',
'kill',
'signal',
'reinit',
'get_hub',
'Hub',
'Waiter',
]
PY2 = sys.version_info[0] == 2
PY3 = sys.version_info[0] >= 3
......@@ -33,23 +37,23 @@ if PY3:
text_type = str
xrange = range
def reraise(tp, value, tb=None):
def reraise(t, value, tb=None): # pylint:disable=unused-argument
if value.__traceback__ is not tb:
raise value.with_traceback(tb)
raise value
else:
import __builtin__
import __builtin__ # pylint:disable=import-error
string_types = __builtin__.basestring,
text_type = __builtin__.unicode
integer_types = (int, __builtin__.long)
xrange = __builtin__.xrange
from gevent._util_py2 import reraise
from gevent._util_py2 import reraise # pylint:disable=import-error,unused-import,no-name-in-module
if sys.version_info[0] <= 2:
import thread
import thread # pylint:disable=import-error,useless-suppression
else:
import _thread as thread
......@@ -155,10 +159,10 @@ def spawn_raw(function, *args, **kwargs):
# implemented twice in core.ppyx and corecffi.py) so do it with a partial
if kwargs:
function = _functools_partial(function, *args, **kwargs)
g = greenlet(function, hub)
g = RawGreenlet(function, hub)
hub.loop.run_callback(g.switch)
else:
g = greenlet(function, hub)
g = RawGreenlet(function, hub)
hub.loop.run_callback(g.switch, *args)
return g
......@@ -287,13 +291,13 @@ class signal(object):
try:
greenlet = self.greenlet_class(self.handle)
greenlet.switch()
except:
self.hub.handle_error(None, *sys._exc_info())
except: # pylint:disable=bare-except
self.hub.handle_error(None, *sys._exc_info()) # pylint:disable=no-member
def handle(self):
try:
self.handler(*self.args, **self.kwargs)
except:
except: # pylint:disable=bare-except
self.hub.handle_error(None, *sys.exc_info())
......@@ -401,24 +405,31 @@ def set_hub(hub):
def _import(path):
# pylint:disable=too-many-branches
if isinstance(path, list):
if not path:
raise ImportError('Cannot import from empty list: %r' % (path, ))
for item in path[:-1]:
try:
return _import(item)
except ImportError:
pass
return _import(path[-1])
if not isinstance(path, string_types):
return path
if '.' not in path:
raise ImportError("Cannot import %r (required format: [path/][package.]module.class)" % path)
if '/' in path:
package_path, path = path.rsplit('/', 1)
sys.path = [package_path] + sys.path
else:
package_path = None
try:
module, item = path.rsplit('.', 1)
x = __import__(module)
......@@ -455,7 +466,7 @@ _resolvers = {'ares': 'gevent.resolver_ares.Resolver',
_DEFAULT_LOOP_CLASS = 'gevent.core.loop'
class Hub(greenlet):
class Hub(RawGreenlet):
"""A greenlet that runs the event loop.
It is created automatically by :func:`get_hub`.
......@@ -504,7 +515,7 @@ class Hub(greenlet):
threadpool_size = 10
def __init__(self, loop=None, default=None):
greenlet.__init__(self)
RawGreenlet.__init__(self)
if hasattr(loop, 'run'):
if default is not None:
raise TypeError("Unexpected argument: default")
......@@ -531,7 +542,7 @@ class Hub(greenlet):
else:
try:
info = self.loop._format()
except Exception as ex:
except Exception as ex: # pylint:disable=broad-except
info = str(ex) or repr(ex) or 'error'
result = '<%s at 0x%x %s' % (self.__class__.__name__, id(self), info)
if self._resolver is not None:
......@@ -574,7 +585,7 @@ class Hub(greenlet):
cb = None
try:
cb = self.loop.run_callback(current.switch)
except:
except: # pylint:disable=bare-except
traceback.print_exc()
try:
self.parent.throw(type, value)
......@@ -594,7 +605,7 @@ class Hub(greenlet):
if not isinstance(context, str):
try:
context = self.format_context(context)
except:
except: # pylint:disable=bare-except
traceback.print_exc()
context = repr(context)
sys.stderr.write('%s failed with %s\n\n' % (context, getattr(type, '__name__', 'exception'), ))
......@@ -603,7 +614,7 @@ class Hub(greenlet):
switch_out = getattr(getcurrent(), 'switch_out', None)
if switch_out is not None:
switch_out()
return greenlet.switch(self)
return RawGreenlet.switch(self)
def switch_out(self):
raise BlockingSwitchOutError('Impossible to call blocking function in the event loop callback')
......@@ -841,7 +852,7 @@ class Waiter(object):
switch = greenlet.switch
try:
switch(value)
except:
except: # pylint:disable=bare-except
self.hub.handle_error(switch, *sys.exc_info())
def switch_args(self, *args):
......@@ -857,7 +868,7 @@ class Waiter(object):
throw = greenlet.throw
try:
throw(*throw_args)
except:
except: # pylint:disable=bare-except
self.hub.handle_error(throw, *sys.exc_info())
def get(self):
......@@ -906,7 +917,7 @@ class _MultipleWaiter(Waiter):
# here can be impractical (see https://github.com/gevent/gevent/issues/652)
self._values = list()
def switch(self, value):
def switch(self, value): # pylint:disable=signature-differs
self._values.append(value)
Waiter.switch(self, True)
......@@ -966,12 +977,12 @@ def iwait(objects, timeout=None, count=None):
finally:
if timeout is not None:
timer.stop()
for obj in objects:
unlink = getattr(obj, 'unlink', None)
for aobj in objects:
unlink = getattr(aobj, 'unlink', None)
if unlink:
try:
unlink(switch)
except:
except: # pylint:disable=bare-except
traceback.print_exc()
......
......@@ -3,10 +3,15 @@
from __future__ import absolute_import
from gevent.hub import getcurrent, PYPY
from gevent._semaphore import Semaphore, BoundedSemaphore
from gevent._semaphore import Semaphore, BoundedSemaphore # pylint:disable=no-name-in-module,import-error
__all__ = ['Semaphore', 'DummySemaphore', 'BoundedSemaphore', 'RLock']
__all__ = [
'Semaphore',
'DummySemaphore',
'BoundedSemaphore',
'RLock',
]
# On PyPy, we don't compile the Semaphore class with Cython. Under
# Cython, each individual method holds the GIL for its entire
......@@ -17,10 +22,34 @@ __all__ = ['Semaphore', 'DummySemaphore', 'BoundedSemaphore', 'RLock']
# to use locks *other* than the one being traced.)
if PYPY:
# TODO: Need to use monkey.get_original?
from thread import allocate_lock as _allocate_lock
from thread import get_ident as _get_ident
from thread import allocate_lock as _allocate_lock # pylint:disable=import-error,useless-suppression
from thread import get_ident as _get_ident # pylint:disable=import-error,useless-suppression
_sem_lock = _allocate_lock()
def untraceable(f):
# Don't allow re-entry to these functions in a single thread, as can
# happen if a sys.settrace is used
def wrapper(self):
me = _get_ident()
try:
count = self._locking[me]
except KeyError:
count = self._locking[me] = 1
else:
count = self._locking[me] = count + 1
if count:
return
try:
return f(self)
finally:
count = count - 1
if not count:
del self._locking[me]
else:
self._locking[me] = count
return wrapper
class _OwnedLock(object):
def __init__(self):
......@@ -29,30 +58,6 @@ if PYPY:
self._locking = {}
self._count = 0
def untraceable(f):
# Don't allow re-entry to these functions in a single thread, as can
# happen if a sys.settrace is used
def wrapper(self):
me = _get_ident()
try:
count = self._locking[me]
except KeyError:
count = self._locking[me] = 1
else:
count = self._locking[me] = count + 1
if count:
return
try:
return f(self)
finally:
count = count - 1
if not count:
del self._locking[me]
else:
self._locking[me] = count
return wrapper
@untraceable
def acquire(self):
me = _get_ident()
......@@ -75,8 +80,11 @@ if PYPY:
# on exit. acquire and wait can call _do_wait, which must release it on entry
# and re-acquire it for them on exit.
class _around(object):
before = None
after = None
__slots__ = ('before', 'after')
def __init__(self, before, after):
self.before = before
self.after = after
def __enter__(self):
self.before()
......@@ -100,17 +108,15 @@ if PYPY:
def __init__(self, *args, **kwargs):
l = self._lock_lock = _OwnedLock()
self._lock_locked = _around()
self._lock_locked.before = l.acquire
self._lock_locked.after = l.release
self._lock_unlocked = _around()
self._lock_unlocked.before = l.release
self._lock_unlocked.after = l.acquire
self._lock_locked = _around(l.acquire, l.release)
self._lock_unlocked = _around(l.release, l.acquire)
_Sem_init(self, *args, **kwargs)
Semaphore.__init__ = __init__
del _decorate
del untraceable
class DummySemaphore(object):
......@@ -178,6 +184,7 @@ class DummySemaphore(object):
.. versionchanged:: 1.1a1
Always return *true*.
"""
# pylint:disable=unused-argument
return True
def __enter__(self):
......
......@@ -9,6 +9,9 @@ created for each request. The server can be customized to use
different subclasses of :class:`WSGIHandler`.
"""
# FIXME: Can we refactor to make smallor?
# pylint:disable=too-many-lines
import errno
from io import BytesIO
import string
......@@ -106,6 +109,7 @@ class Input(object):
'chunked_input', 'chunk_length', '_chunked_input_error')
def __init__(self, rfile, content_length, socket=None, chunked_input=False):
# pylint:disable=redefined-outer-name
self.rfile = rfile
self.content_length = content_length
self.socket = socket
......@@ -250,6 +254,7 @@ class Input(object):
return int(buf.getvalue(), 16)
def _chunked_read(self, length=None, use_readline=False):
# pylint:disable=too-many-branches
rfile = self.rfile
self._send_100_continue()
......@@ -312,6 +317,7 @@ class Input(object):
return self._do_read(size, use_readline=True)
def readlines(self, hint=None):
# pylint:disable=unused-argument
return list(self)
def __iter__(self):
......@@ -349,7 +355,7 @@ except ImportError:
def typeheader(self):
return self.get('content-type')
def headers_factory(fp, *args):
def headers_factory(fp, *args): # pylint:disable=unused-argument
try:
ret = client.parse_headers(fp, _class=OldMessage)
except client.LineTooLong:
......@@ -373,6 +379,8 @@ class WSGIHandler(object):
itself. The application and environment are obtained from the server.
"""
# pylint:disable=too-many-instance-attributes
protocol_version = 'HTTP/1.1'
if PY3:
# if we do like Py2, then headers_factory unconditionally
......@@ -412,17 +420,17 @@ class WSGIHandler(object):
command = None # str: 'GET'
path = None # str: '/'
def __init__(self, socket, address, server, rfile=None):
def __init__(self, sock, address, server, rfile=None):
# Deprecation: The rfile kwarg was introduced in 1.0a1 as part
# of a refactoring. It was never documented or used. It is
# considered DEPRECATED and may be removed in the future. Its
# use is not supported.
self.socket = socket
self.socket = sock
self.client_address = address
self.server = server
if rfile is None:
self.rfile = socket.makefile('rb', -1)
self.rfile = sock.makefile('rb', -1)
else:
self.rfile = rfile
......@@ -470,10 +478,10 @@ class WSGIHandler(object):
self.__dict__.pop('rfile', None)
def _check_http_version(self):
version = self.request_version
if not version.startswith("HTTP/"):
version_str = self.request_version
if not version_str.startswith("HTTP/"):
return False
version = tuple(int(x) for x in version[5:].split(".")) # "HTTP/"
version = tuple(int(x) for x in version_str[5:].split(".")) # "HTTP/"
if version[1] < 0 or version < (0, 9) or version >= (2, 0):
return False
return True
......@@ -500,6 +508,7 @@ class WSGIHandler(object):
Raise the previously documented :exc:`ValueError` in more cases instead of returning a
false value; this allows subclasses more opportunity to customize behaviour.
"""
# pylint:disable=too-many-branches
self.requestline = raw_requestline.rstrip()
words = self.requestline.split()
if len(words) == 3:
......@@ -539,10 +548,7 @@ class WSGIHandler(object):
if self.request_version == "HTTP/1.1":
conntype = self.headers.get("Connection", "").lower()
if conntype == "close":
self.close_connection = True
else:
self.close_connection = False
self.close_connection = (conntype == 'close')
else:
self.close_connection = True
......@@ -551,17 +557,17 @@ class WSGIHandler(object):
def log_error(self, msg, *args):
try:
message = msg % args
except Exception:
except Exception: # pylint:disable=broad-except
traceback.print_exc()
message = '%r %r' % (msg, args)
try:
message = '%s: %s' % (self.socket, message)
except Exception:
except Exception: # pylint:disable=broad-except
pass
try:
self.server.error_log.write(message + '\n')
except Exception:
except Exception: # pylint:disable=broad-except
traceback.print_exc()
def read_requestline(self):
......@@ -620,8 +626,10 @@ class WSGIHandler(object):
:meth:`_handle_client_error` to allow subclasses to customize. Note that
this is experimental and may change in the future.
"""
# pylint:disable=too-many-return-statements
if self.rfile.closed:
return
try:
self.requestline = self.read_requestline()
# Account for old subclasses that haven't done this
......@@ -645,7 +653,7 @@ class WSGIHandler(object):
# subclasses that return a False value instead.
if not self.read_request(self.requestline):
return ('400', _BAD_REQUEST_RESPONSE)
except Exception as ex:
except Exception as ex: # pylint:disable=broad-except
# Notice we don't use self.handle_error because it reports
# a 500 error to the client, and this is almost certainly
# a client error.
......@@ -748,6 +756,7 @@ class WSGIHandler(object):
and headers during this method. On Python 2, avoid some
extra encodings.
"""
# pylint:disable=too-many-branches
if exc_info:
try:
if self.headers_sent:
......@@ -909,7 +918,7 @@ class WSGIHandler(object):
self.close_connection = True
else:
self.handle_error(*sys.exc_info())
except:
except: # pylint:disable=bare-except
self.handle_error(*sys.exc_info())
finally:
self.time_finish = time.time()
......@@ -1014,11 +1023,12 @@ class WSGIHandler(object):
env[key] = value
if env.get('HTTP_EXPECT') == '100-continue':
socket = self.socket
sock = self.socket
else:
socket = None
sock = None
chunked = env.get('HTTP_TRANSFER_ENCODING', '').lower() == 'chunked'
self.wsgi_input = Input(self.rfile, self.content_length, socket=socket, chunked_input=chunked)
self.wsgi_input = Input(self.rfile, self.content_length, socket=sock, chunked_input=chunked)
env['wsgi.input'] = self.wsgi_input
return env
......@@ -1028,6 +1038,7 @@ class _NoopLog(object):
# to pass the WSGI validator
def write(self, *args, **kwargs):
# pylint:disable=unused-argument
return
def flush(self):
......@@ -1243,11 +1254,12 @@ class WSGIServer(StreamServer):
self.environ.setdefault('SERVER_NAME', '')
self.environ.setdefault('SERVER_PORT', '')
def handle(self, socket, address):
def handle(self, sock, address):
"""
Create an instance of :attr:`handler_class` to handle the request.
This method blocks until the handler returns.
"""
handler = self.handler_class(socket, address, self)
# pylint:disable=method-hidden
handler = self.handler_class(sock, address, self)
handler.handle()
......@@ -51,7 +51,7 @@ class SelectResult(object):
self.event.set()
def select(rlist, wlist, xlist, timeout=None):
def select(rlist, wlist, xlist, timeout=None): # pylint:disable=unused-argument
"""An implementation of :meth:`select.select` that blocks only the current greenlet.
Note: *xlist* is ignored.
......@@ -78,8 +78,8 @@ def select(rlist, wlist, xlist, timeout=None):
result.event.wait(timeout=timeout)
return result.read, result.write, []
finally:
for watcher in watchers:
watcher.stop()
for awatcher in watchers:
awatcher.stop()
if original_poll is not None:
class PollResult(object):
......@@ -127,8 +127,8 @@ if original_poll is not None:
result.event.wait(timeout=timeout)
return list(result.events)
finally:
for fd in self.fds:
self.fds[fd].stop()
for afd in self.fds:
self.fds[afd].stop()
def unregister(self, fd):
self.fds.pop(fd, None)
......@@ -77,6 +77,8 @@ class StreamServer(BaseServer):
def init_socket(self):
if not hasattr(self, 'socket'):
# FIXME: clean up the socket lifetime
# pylint:disable=attribute-defined-outside-init
self.socket = self.get_listener(self.address, self.backlog, self.family)
self.address = self.socket.getsockname()
if self.ssl_args:
......@@ -85,10 +87,10 @@ class StreamServer(BaseServer):
self._handle = self.handle
@classmethod
def get_listener(self, address, backlog=None, family=None):
def get_listener(cls, address, backlog=None, family=None):
if backlog is None:
backlog = self.backlog
return _tcp_listener(address, backlog=backlog, reuse_addr=self.reuse_addr, family=family)
backlog = cls.backlog
return _tcp_listener(address, backlog=backlog, reuse_addr=cls.reuse_addr, family=family)
if PY3:
......@@ -118,8 +120,8 @@ class StreamServer(BaseServer):
client_socket._drop()
return sockobj, address
def do_close(self, socket, *args):
socket.close()
def do_close(self, sock, *args):
sock.close()
def wrap_socket_and_handle(self, client_socket, address):
# used in case of ssl sockets
......@@ -133,12 +135,16 @@ class DatagramServer(BaseServer):
reuse_addr = DEFAULT_REUSE_ADDR
def __init__(self, *args, **kwargs):
# The raw (non-gevent) socket, if possible
self._socket = None
BaseServer.__init__(self, *args, **kwargs)
from gevent.lock import Semaphore
self._writelock = Semaphore()
def init_socket(self):
if not hasattr(self, 'socket'):
# FIXME: clean up the socket lifetime
# pylint:disable=attribute-defined-outside-init
self.socket = self.get_listener(self.address, self.family)
self.address = self.socket.getsockname()
self._socket = self.socket
......@@ -148,8 +154,8 @@ class DatagramServer(BaseServer):
pass
@classmethod
def get_listener(self, address, family=None):
return _udp_socket(address, reuse_addr=self.reuse_addr, family=family)
def get_listener(cls, address, family=None):
return _udp_socket(address, reuse_addr=cls.reuse_addr, family=family)
def do_read(self):
try:
......@@ -186,6 +192,9 @@ def _tcp_listener(address, backlog=50, reuse_addr=None, family=_socket.AF_INET):
def _udp_socket(address, backlog=50, reuse_addr=None, family=_socket.AF_INET):
# backlog argument for compat with tcp_listener
# pylint:disable=unused-argument
# we want gevent.socket.socket here
sock = socket(family=family, type=_socket.SOCK_DGRAM)
if reuse_addr is not None:
......
......@@ -26,6 +26,15 @@ else:
# needs to define these
__implements__ = __dns__ = __all__ = __extensions__ = __imports__ = ()
class error(Exception):
errno = None
def getfqdn(*args):
# pylint:disable=unused-argument
raise NotImplementedError()
for key in _source.__dict__:
if key.startswith('__') and key not in '__implements__ __dns__ __all__ __extensions__ __imports__ __socket__'.split():
continue
......@@ -83,7 +92,7 @@ def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT, source_address=N
# that does not happen with regular sockets though, because _socket.socket.connect() is a built-in.
# this is similar to "getnameinfo loses a reference" failure in test_socket.py
if not PY3:
sys.exc_clear() # pylint:disable=no-member
sys.exc_clear() # pylint:disable=no-member,useless-suppression
if sock is not None:
sock.close()
err = ex
......
......@@ -58,6 +58,9 @@ if PY3 and not sys.platform.startswith('win32'):
__implements__.append("_posixsubprocess")
_posixsubprocess = None
# Some symbols we define that we expect to export;
# useful for static analysis
PIPE = "PIPE should be imported"
# Standard functions and classes that this module re-imports.
__imports__ = [
......
from __future__ import absolute_import
__implements__ = ['local',
'_start_new_thread',
'_allocate_lock',
'Lock',
'_get_ident',
'_sleep',
'_DummyThread']
__implements__ = [
'local',
'_start_new_thread',
'_allocate_lock',
'Lock',
'_get_ident',
'_sleep',
'_DummyThread',
]
import threading as __threading__
......@@ -15,6 +17,15 @@ _DummyThread_ = __threading__._DummyThread
from gevent.local import local
from gevent.thread import start_new_thread as _start_new_thread, allocate_lock as _allocate_lock, get_ident as _get_ident
from gevent.hub import sleep as _sleep, getcurrent, PYPY
# Exports, prevent unused import warnings
local = local
start_new_thread = _start_new_thread
allocate_lock = _allocate_lock
_get_ident = _get_ident
_sleep = _sleep
getcurrent = getcurrent
Lock = _allocate_lock
......@@ -61,7 +72,7 @@ class _DummyThread(_DummyThread_):
_tstate_lock = None
def __init__(self):
#_DummyThread_.__init__(self)
#_DummyThread_.__init__(self) # pylint:disable=super-init-not-called
# It'd be nice to use a pattern like "greenlet-%d", but maybe somebody out
# there is checking thread names...
......@@ -88,12 +99,12 @@ class _DummyThread(_DummyThread_):
# when gevent.threading is imported before monkey patching or not at all
# XXX: This assumes that the import is happening in the "main" greenlet
if _get_ident() not in __threading__._active and len(__threading__._active) == 1:
k, v = next(iter(__threading__._active.items()))
del __threading__._active[k]
v._Thread__ident = _get_ident()
__threading__._active[_get_ident()] = v
del k
del v
_k, _v = next(iter(__threading__._active.items()))
del __threading__._active[_k]
_v._Thread__ident = _get_ident()
__threading__._active[_get_ident()] = _v
del _k
del _v
# Avoid printing an error on shutdown trying to remove the thread entry
# we just replaced if we're not fully monkey patched in
......@@ -101,6 +112,7 @@ if _get_ident() not in __threading__._active and len(__threading__._active) == 1
# defines __delitem__, shutdown hangs. Maybe due to something with the GC?
# XXX: This may be fixed in 2.6.1+
if not PYPY:
# pylint:disable=no-member
_MAIN_THREAD = __threading__._get_ident() if hasattr(__threading__, '_get_ident') else __threading__.get_ident()
class _active(dict):
......
......@@ -20,6 +20,8 @@
# THE SOFTWARE.
# package is named greentest, not test, so it won't be confused with test in stdlib
# pylint:disable=broad-except,unused-argument,no-member,too-many-branches,unused-variable
# pylint:disable=attribute-defined-outside-init,abstract-method
import sys
import types
import unittest
......@@ -83,7 +85,7 @@ if sys.version_info[0] == 2:
PY2 = True
NON_APPLICABLE_SUFFIXES.append('3')
if (sys.version_info[1] < 7
or (sys.version_info[1] == 7 and sys.version_info[2] < 9)):
or (sys.version_info[1] == 7 and sys.version_info[2] < 9)):
# Python 2, < 2.7.9
NON_APPLICABLE_SUFFIXES.append('279')
if sys.platform.startswith('win'):
......@@ -305,7 +307,11 @@ class TestCaseMetaClass(type):
# b) fatal error check
# c) restore the hub's error handler (see expect_one_error)
# d) totalrefcount check
def __new__(meta, classname, bases, classDict):
def __new__(cls, classname, bases, classDict):
# pylint and pep8 fight over what this should be called (mcs or cls).
# pylint gets it right, but we cant scope disable pep8, so we go with
# its convention.
# pylint: disable=bad-mcs-classmethod-argument
timeout = classDict.get('__timeout__', 'NONE')
if timeout == 'NONE':
timeout = getattr(bases[0], '__timeout__', None)
......@@ -327,7 +333,7 @@ class TestCaseMetaClass(type):
if check_totalrefcount:
value = wrap_refcount(value)
classDict[key] = value
return type.__new__(meta, classname, bases, classDict)
return type.__new__(cls, classname, bases, classDict)
class TestCase(TestCaseMetaClass("NewBase", (BaseTestCase,), {})):
......
# pylint:disable=missing-docstring,invalid-name
from __future__ import print_function
import sys
import os
......@@ -46,7 +47,8 @@ test_patched_threading.*
def make_re(tests):
tests = [x.strip().replace('\.', '\\.').replace('*', '.*?') for x in tests.split('\n') if x.strip()]
tests = [x.strip().replace(r'\.', r'\\.').replace('*', '.*?')
for x in tests.split('\n') if x.strip()]
tests = re.compile('^%s$' % '|'.join(tests))
return tests
......@@ -280,7 +282,7 @@ if hasattr(sys, 'pypy_version_info'):
# _execut_child)
]
import cffi
import cffi # pylint:disable=import-error,useless-suppression
if cffi.__version_info__ < (1, 2, 0):
disabled_tests += [
'test_signal.InterProcessSignalTests.test_main',
......
......@@ -7,6 +7,7 @@ import threading
import subprocess
import time
# pylint: disable=broad-except,attribute-defined-outside-init
runtimelog = []
MIN_RUNTIME = 1.0
......
......@@ -2,10 +2,14 @@
# N801: class names should use CapWords
# N802: function names should be lower-case; comes from Windows funcs
# N803: argument name should be lower-case; comes up with using the class name as a keyword-argument
ignore=E702,E265,E402,E731,E266,E261,W503,E129,N801,N802,N803
# N813: camelCase imported as lowercase; socketcommon
# N806: variable in function should be lowercase; but sometimes we want constant-looking names, especially for closures
# N812: lowercase imported as non-lowercase; from greenlet import greenlet as RawGreenlet
ignore=E702,E265,E402,E731,E266,E261,W503,E129,N801,N802,N803,N813,N806,N812
max_line_length=160
exclude=.runtimes,.eggs,.tox,.git,build,2.6,2.7,2.7pypy,3.3,3.5,test_support.py,test_queue.py,patched_tests_setup.py,test_threading_2.py,lock_tests.py,_sslgte279.py,3.4
[flake8]
# F821: undefined name; caught better by pylint, where it can be locally disabled
ignore=F821
# F401: imported but unused; better caught by pylint where it can be locally disabled
ignore=F821,F401
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment