Commit d6567bd1 authored by Jason Madden's avatar Jason Madden

try the build using prospector.

parent bdd1a4ec
...@@ -21,8 +21,11 @@ ignore-paths: ...@@ -21,8 +21,11 @@ ignore-paths:
# likewise with scripts # likewise with scripts
- scripts/ - scripts/
# This file has invalid syntax for Python 3, which is how # This file has invalid syntax for Python 3, which is how
# landscape.io runs things # landscape.io runs things...
- gevent/_util_py2.py - gevent/_util_py2.py
# ...and this file has invalid syntax for Python 2, which is how
# travis currently runs things. sigh.
- gevent/_socket3.py
# This is vendored with minimal changes # This is vendored with minimal changes
- gevent/_tblib.py - gevent/_tblib.py
# likewise # likewise
......
...@@ -4,34 +4,46 @@ ...@@ -4,34 +4,46 @@
# can either give multiple identifier separated by comma (,) or put this option # can either give multiple identifier separated by comma (,) or put this option
# multiple time (only on the command line, not in the configuration file where # multiple time (only on the command line, not in the configuration file where
# it should appear only once). # it should appear only once).
# NOTE: comments must go between lines, not at the end; at the end of the line # NOTE: comments must go ABOVE the statement. In Python 2, mixing in
# disables that directive and all following! # comments disables all directives that follow, while in Python 3, putting
# comments at the end of the line does the same thing (though Py3 supports
# mixing)
# invalid-name, ; We get lots of these, especially in scripts. should fix many of them
# protected-access, ; We have many cases of this; legit ones need to be examinid and commented, then this removed
# no-self-use, ; common in superclasses with extension points
# too-few-public-methods, ; Exception and marker classes get tagged with this
# exec-used, ; should tag individual instances with this, there are some but not too many
# global-statement, ; should tag individual instances
# multiple-statements, ; "from gevent import monkey; monkey.patch_all()"
# locally-disabled, ; yes, we know we're doing this. don't replace one warning with another
# cyclic-import, ; most of these are deferred imports
# too-many-arguments, ; these are almost always because that's what the stdlib does
# redefined-builtin, ; likewise: these tend to be keyword arguments like len= in the stdlib
# undefined-all-variable, ; XXX: This crashes with pylint 1.5.4 on Travis (but not locally on Py2/3
# ; or landscape.io on Py3). The file causing the problem is unclear.
# useless-suppression: the only way to avoid repeating it for specific statements everywhere that we
# do Py2/Py3 stuff is to put it here. Sadly this means that we might get better but not realize it.
# see https://github.com/PyCQA/pylint/issues/846
disable=wrong-import-position, disable=wrong-import-position,
wrong-import-order, wrong-import-order,
missing-docstring, missing-docstring,
ungrouped-imports, ungrouped-imports,
# We get lots of these, especially in scripts. should fix many of them invalid-name,
invalid-name, protected-access,
# We have many cases of this; legit ones need to be examinid and commented, then this removed no-self-use,
protected-access, too-few-public-methods,
# common in superclasses with extension points exec-used,
no-self-use, global-statement,
# Exception and marker classes get tagged with this multiple-statements,
too-few-public-methods, locally-disabled,
# should tag individual instances with this, there are some but not too many cyclic-import,
exec-used, too-many-arguments,
# should tag individual instances redefined-builtin,
global-statement, useless-suppression,
# "from gevent import monkey; monkey.patch_all()" # undefined-all-variable
multiple-statements,
# yes, we know we're doing this. don't replace one warning with another
locally-disabled,
# most of these are deferred imports
cyclic-import,
# these are almost always because that's what the stdlib does
too-many-arguments,
# likewise: these tend to be keyword arguments like len= in the stdlib
redefined-builtin,
[FORMAT] [FORMAT]
# duplicated from setup.cfg # duplicated from setup.cfg
......
...@@ -46,13 +46,14 @@ doc: ...@@ -46,13 +46,14 @@ doc:
whitespace: whitespace:
! find . -not -path "*.pem" -not -path "./.eggs/*" -not -path "./greentest/htmlcov/*" -not -path "./greentest/.coverage.*" -not -path "./.tox/*" -not -path "*/__pycache__/*" -not -path "*.so" -not -path "*.pyc" -not -path "./.git/*" -not -path "./build/*" -not -path "./libev/*" -not -path "./gevent/libev/*" -not -path "./gevent.egg-info/*" -not -path "./dist/*" -not -path "./.DS_Store" -not -path "./c-ares/*" -not -path "./gevent/gevent.*.[ch]" -not -path "./gevent/corecext.pyx" -not -path "./doc/_build/*" -not -path "./doc/mytheme/static/*" -type f | xargs egrep -l " $$" ! find . -not -path "*.pem" -not -path "./.eggs/*" -not -path "./greentest/htmlcov/*" -not -path "./greentest/.coverage.*" -not -path "./.tox/*" -not -path "*/__pycache__/*" -not -path "*.so" -not -path "*.pyc" -not -path "./.git/*" -not -path "./build/*" -not -path "./libev/*" -not -path "./gevent/libev/*" -not -path "./gevent.egg-info/*" -not -path "./dist/*" -not -path "./.DS_Store" -not -path "./c-ares/*" -not -path "./gevent/gevent.*.[ch]" -not -path "./gevent/corecext.pyx" -not -path "./doc/_build/*" -not -path "./doc/mytheme/static/*" -type f | xargs egrep -l " $$"
pep8: prospector:
${PYTHON} `which pep8` . which prospector
which pylint
# debugging
# pylint --rcfile=.pylintrc --init-hook="import sys, code; sys.excepthook = lambda exc, exc_type, tb: print(tb.tb_next.tb_next.tb_next.tb_next.tb_next.tb_next.tb_next.tb_next.tb_next.tb_next.tb_frame.f_locals['self'])" gevent greentest/* || true
${PYTHON} scripts/gprospector.py -X
pyflakes: lint: whitespace prospector
${PYTHON} util/pyflakes.py
lint: whitespace pyflakes pep8
test_prelim: test_prelim:
which ${PYTHON} which ${PYTHON}
...@@ -86,7 +87,7 @@ travis_test_linters: ...@@ -86,7 +87,7 @@ travis_test_linters:
coveralls --rcfile=greentest/.coveragerc coveralls --rcfile=greentest/.coveragerc
.PHONY: clean all doc pep8 whitespace pyflakes lint travistest travis .PHONY: clean all doc prospector whitespace lint travistest travis
# Managing runtimes # Managing runtimes
......
...@@ -82,7 +82,7 @@ tests on one version of Python during development, try this:: ...@@ -82,7 +82,7 @@ tests on one version of Python during development, try this::
Before submitting a pull request, it's a good idea to run the tests Before submitting a pull request, it's a good idea to run the tests
across all supported versions of Python, and to check the code quality across all supported versions of Python, and to check the code quality
using pep8 and pyflakes. This is what is done on Travis CI. Locally it using prospector. This is what is done on Travis CI. Locally it
can be done using tox:: can be done using tox::
pip install tox pip install tox
......
...@@ -2,8 +2,7 @@ setuptools ...@@ -2,8 +2,7 @@ setuptools
wheel wheel
cython>=0.23.4 cython>=0.23.4
greenlet>=0.4.9 greenlet>=0.4.9
pep8 prospector[with_pyroma]
pyflakes
coverage>=4.0 coverage>=4.0
coveralls>=1.0 coveralls>=1.0
cffi cffi
......
...@@ -15,9 +15,9 @@ urls = ['http://www.google.com', 'http://www.yandex.ru', 'http://www.python.org' ...@@ -15,9 +15,9 @@ urls = ['http://www.google.com', 'http://www.yandex.ru', 'http://www.python.org'
if sys.version_info[0] == 3: if sys.version_info[0] == 3:
from urllib.request import urlopen from urllib.request import urlopen # pylint:disable=import-error,no-name-in-module
else: else:
from urllib2 import urlopen from urllib2 import urlopen # pylint: disable=import-error
def print_head(url): def print_head(url):
...@@ -25,6 +25,6 @@ def print_head(url): ...@@ -25,6 +25,6 @@ def print_head(url):
data = urlopen(url).read() data = urlopen(url).read()
print('%s: %s bytes: %r' % (url, len(data), data[:50])) print('%s: %s bytes: %r' % (url, len(data), data[:50]))
jobs = [gevent.spawn(print_head, url) for url in urls] jobs = [gevent.spawn(print_head, _url) for _url in urls]
gevent.wait(jobs) gevent.wait(jobs)
...@@ -22,6 +22,7 @@ try: ...@@ -22,6 +22,7 @@ try:
from urlparse import urlparse from urlparse import urlparse
from urllib import unquote from urllib import unquote
except ImportError: except ImportError:
# pylint:disable=import-error,no-name-in-module
from urllib import request as urllib2 from urllib import request as urllib2
from urllib.parse import urlparse from urllib.parse import urlparse
from urllib.parse import unquote from urllib.parse import unquote
...@@ -66,6 +67,7 @@ def application(env, start_response): ...@@ -66,6 +67,7 @@ def application(env, start_response):
def proxy(path, start_response, proxy_url): def proxy(path, start_response, proxy_url):
# pylint:disable=too-many-locals
if '://' not in path: if '://' not in path:
path = 'http://' + path path = 'http://' + path
try: try:
......
...@@ -11,12 +11,12 @@ urls = ("/", "index", ...@@ -11,12 +11,12 @@ urls = ("/", "index",
'/long', 'long_polling') '/long', 'long_polling')
class index: class index(object):
def GET(self): def GET(self):
return '<html>Hello, world!<br><a href="/long">/long</a></html>' return '<html>Hello, world!<br><a href="/long">/long</a></html>'
class long_polling: class long_polling(object):
# Since gevent's WSGIServer executes each incoming connection in a separate greenlet # Since gevent's WSGIServer executes each incoming connection in a separate greenlet
# long running requests such as this one don't block one another; # long running requests such as this one don't block one another;
# and thanks to "monkey.patch_all()" statement at the top, thread-local storage used by web.ctx # and thanks to "monkey.patch_all()" statement at the top, thread-local storage used by web.ctx
......
...@@ -28,7 +28,7 @@ class GreenFileDescriptorIO(RawIOBase): ...@@ -28,7 +28,7 @@ class GreenFileDescriptorIO(RawIOBase):
_write_event = None _write_event = None
def __init__(self, fileno, mode='r', closefd=True): def __init__(self, fileno, mode='r', closefd=True):
RawIOBase.__init__(self) RawIOBase.__init__(self) # Python 2: pylint:disable=no-member,non-parent-init-called
self._closed = False self._closed = False
self._closefd = closefd self._closefd = closefd
self._fileno = fileno self._fileno = fileno
......
...@@ -66,7 +66,7 @@ class SSLContext(orig_SSLContext): ...@@ -66,7 +66,7 @@ class SSLContext(orig_SSLContext):
check_hostname = False check_hostname = False
class _contextawaresock(socket._gevent_sock_class): class _contextawaresock(socket._gevent_sock_class): # Python 2: pylint:disable=slots-on-old-class
# We have to pass the raw stdlib socket to SSLContext.wrap_socket. # We have to pass the raw stdlib socket to SSLContext.wrap_socket.
# That method in turn can pass that object on to things like SNI callbacks. # That method in turn can pass that object on to things like SNI callbacks.
# It wouldn't have access to any of the attributes on the SSLSocket, like # It wouldn't have access to any of the attributes on the SSLSocket, like
......
...@@ -5,10 +5,11 @@ or not). ...@@ -5,10 +5,11 @@ or not).
This module is missing 'Thread' class, but includes 'Queue'. This module is missing 'Thread' class, but includes 'Queue'.
""" """
from __future__ import absolute_import
try: try:
from Queue import Full, Empty from Queue import Full, Empty
except ImportError: except ImportError:
from queue import Full, Empty from queue import Full, Empty # pylint:disable=import-error
from collections import deque from collections import deque
import heapq import heapq
from time import time as _time, sleep as _sleep from time import time as _time, sleep as _sleep
...@@ -280,7 +281,7 @@ class Event(object): ...@@ -280,7 +281,7 @@ class Event(object):
self.__cond.release() self.__cond.release()
class Queue: class Queue: # pylint:disable=old-style-class
"""Create a queue object with a given maximum size. """Create a queue object with a given maximum size.
If maxsize is <= 0, the queue size is infinite. If maxsize is <= 0, the queue size is infinite.
......
...@@ -9,7 +9,7 @@ with other elements of the process. ...@@ -9,7 +9,7 @@ with other elements of the process.
.. seealso:: :class:`code.InteractiveConsole` .. seealso:: :class:`code.InteractiveConsole`
""" """
from __future__ import print_function from __future__ import print_function, absolute_import
import sys import sys
from code import InteractiveConsole from code import InteractiveConsole
...@@ -114,7 +114,7 @@ class BackdoorServer(StreamServer): ...@@ -114,7 +114,7 @@ class BackdoorServer(StreamServer):
import __builtin__ import __builtin__
_locals["__builtins__"] = __builtin__ _locals["__builtins__"] = __builtin__
except ImportError: except ImportError:
import builtins import builtins # pylint:disable=import-error
_locals["builtins"] = builtins _locals["builtins"] = builtins
_locals['__builtins__'] = builtins _locals['__builtins__'] = builtins
return _locals return _locals
......
...@@ -18,7 +18,7 @@ try: # Py2 ...@@ -18,7 +18,7 @@ try: # Py2
_allowed_module_name_types = (basestring,) # pylint:disable=undefined-variable _allowed_module_name_types = (basestring,) # pylint:disable=undefined-variable
__target__ = '__builtin__' __target__ = '__builtin__'
except ImportError: except ImportError:
import builtins import builtins # pylint: disable=import-error
_allowed_module_name_types = (str,) _allowed_module_name_types = (str,)
__target__ = 'builtins' __target__ = 'builtins'
......
...@@ -257,7 +257,7 @@ if sys.version_info[0] >= 3: ...@@ -257,7 +257,7 @@ if sys.version_info[0] >= 3:
integer_types = int, integer_types = int,
else: else:
import __builtin__ # pylint:disable=import-error import __builtin__ # pylint:disable=import-error
basestring = __builtin__.basestring basestring = __builtin__.basestring,
integer_types = (int, __builtin__.long) integer_types = (int, __builtin__.long)
......
...@@ -93,7 +93,7 @@ class FileObjectThread(object): ...@@ -93,7 +93,7 @@ class FileObjectThread(object):
if self.lock is True: if self.lock is True:
self.lock = Semaphore() self.lock = Semaphore()
elif not self.lock: elif not self.lock:
self.lock = DummySemaphore() self.lock = DummySemaphore() # pylint:disable=redefined-variable-type
if not hasattr(self.lock, '__enter__'): if not hasattr(self.lock, '__enter__'):
raise TypeError('Expected a Semaphore or boolean, got %r' % type(self.lock)) raise TypeError('Expected a Semaphore or boolean, got %r' % type(self.lock))
if isinstance(fobj, integer_types): if isinstance(fobj, integer_types):
......
...@@ -47,15 +47,15 @@ else: ...@@ -47,15 +47,15 @@ else:
string_types = __builtin__.basestring, string_types = __builtin__.basestring,
text_type = __builtin__.unicode text_type = __builtin__.unicode
integer_types = (int, __builtin__.long) integer_types = (int, __builtin__.long)
xrange = __builtin__.xrange xrange = __builtin__.xrange # python 2: pylint:disable=redefined-variable-type
from gevent._util_py2 import reraise # pylint:disable=import-error,unused-import,no-name-in-module from gevent._util_py2 import reraise # pylint:disable=import-error,unused-import,no-name-in-module
if sys.version_info[0] <= 2: if sys.version_info[0] <= 2:
import thread # pylint:disable=import-error,useless-suppression import thread # pylint:disable=import-error
else: else:
import _thread as thread import _thread as thread # python 2 pylint:disable=import-error
# These must be the "real" native thread versions, # These must be the "real" native thread versions,
# not monkey-patched. # not monkey-patched.
......
...@@ -81,7 +81,7 @@ if sys.version_info[0] >= 3: ...@@ -81,7 +81,7 @@ if sys.version_info[0] >= 3:
PY3 = True PY3 = True
else: else:
import __builtin__ # pylint:disable=import-error import __builtin__ # pylint:disable=import-error
string_types = __builtin__.basestring string_types = __builtin__.basestring,
PY3 = False PY3 = False
WIN = sys.platform.startswith("win") WIN = sys.platform.startswith("win")
...@@ -244,7 +244,7 @@ def _patch_existing_locks(threading): ...@@ -244,7 +244,7 @@ def _patch_existing_locks(threading):
class _ModuleLock(object): class _ModuleLock(object):
pass pass
else: else:
_ModuleLock = importlib._bootstrap._ModuleLock _ModuleLock = importlib._bootstrap._ModuleLock # python 2 pylint: disable=no-member
# It might be possible to walk up all the existing stack frames to find # It might be possible to walk up all the existing stack frames to find
# locked objects...at least if they use `with`. To be sure, we look at every object # locked objects...at least if they use `with`. To be sure, we look at every object
# Since we're supposed to be done very early in the process, there shouldn't be # Since we're supposed to be done very early in the process, there shouldn't be
......
...@@ -76,9 +76,11 @@ class IMapUnordered(Greenlet): ...@@ -76,9 +76,11 @@ class IMapUnordered(Greenlet):
# redundant, and that lets us avoid having to use self.link() instead # redundant, and that lets us avoid having to use self.link() instead
# of self.rawlink() to avoid having blocking methods called in the # of self.rawlink() to avoid having blocking methods called in the
# hub greenlet. # hub greenlet.
self._result_semaphore = Semaphore(maxsize) factory = Semaphore
else: else:
self._result_semaphore = DummySemaphore() factory = DummySemaphore
self._result_semaphore = factory(maxsize)
self.count = 0 self.count = 0
self.finished = False self.finished = False
# If the queue size is unbounded, then we want to call all # If the queue size is unbounded, then we want to call all
...@@ -666,9 +668,10 @@ class Pool(Group): ...@@ -666,9 +668,10 @@ class Pool(Group):
if greenlet_class is not None: if greenlet_class is not None:
self.greenlet_class = greenlet_class self.greenlet_class = greenlet_class
if size is None: if size is None:
self._semaphore = DummySemaphore() factory = DummySemaphore
else: else:
self._semaphore = Semaphore(size) factory = Semaphore
self._semaphore = factory(size)
def wait_available(self, timeout=None): def wait_available(self, timeout=None):
""" """
......
...@@ -23,7 +23,7 @@ from datetime import datetime ...@@ -23,7 +23,7 @@ from datetime import datetime
try: try:
from urllib import unquote from urllib import unquote
except ImportError: except ImportError:
from urllib.parse import unquote from urllib.parse import unquote # python 2 pylint:disable=import-error,no-name-in-module
from gevent import socket from gevent import socket
import gevent import gevent
...@@ -336,11 +336,11 @@ try: ...@@ -336,11 +336,11 @@ try:
headers_factory = mimetools.Message headers_factory = mimetools.Message
except ImportError: except ImportError:
# adapt Python 3 HTTP headers to old API # adapt Python 3 HTTP headers to old API
from http import client from http import client # pylint:disable=import-error
class OldMessage(client.HTTPMessage): class OldMessage(client.HTTPMessage):
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super(client.HTTPMessage, self).__init__(**kwargs) # pylint:disable=bad-super-call
self.status = '' self.status = ''
def getheader(self, name, default=None): def getheader(self, name, default=None):
...@@ -1247,7 +1247,7 @@ class WSGIServer(StreamServer): ...@@ -1247,7 +1247,7 @@ class WSGIServer(StreamServer):
except socket.error: except socket.error:
name = str(address[0]) name = str(address[0])
if PY3 and not isinstance(name, str): if PY3 and not isinstance(name, str):
name = name.decode('ascii') name = name.decode('ascii') # python 2 pylint:disable=redefined-variable-type
self.environ['SERVER_NAME'] = name self.environ['SERVER_NAME'] = name
self.environ.setdefault('SERVER_PORT', str(address[1])) self.environ.setdefault('SERVER_PORT', str(address[1]))
else: else:
......
...@@ -30,7 +30,7 @@ import collections ...@@ -30,7 +30,7 @@ import collections
if sys.version_info[0] == 2: if sys.version_info[0] == 2:
import Queue as __queue__ import Queue as __queue__
else: else:
import queue as __queue__ import queue as __queue__ # python 2: pylint:disable=import-error
Full = __queue__.Full Full = __queue__.Full
Empty = __queue__.Empty Empty = __queue__.Empty
......
...@@ -122,7 +122,7 @@ if original_poll is not None: ...@@ -122,7 +122,7 @@ if original_poll is not None:
try: try:
for fd in self.fds: for fd in self.fds:
self.fds[fd].start(result.add_event, get_fileno(fd), pass_events=True) self.fds[fd].start(result.add_event, get_fileno(fd), pass_events=True)
if timeout is not None and -1 < timeout: if timeout is not None and timeout > -1:
timeout /= 1000.0 timeout /= 1000.0
result.event.wait(timeout=timeout) result.event.wait(timeout=timeout)
return list(result.events) return list(result.events)
......
...@@ -98,7 +98,7 @@ class StreamServer(BaseServer): ...@@ -98,7 +98,7 @@ class StreamServer(BaseServer):
sock = self.socket sock = self.socket
try: try:
fd, address = sock._accept() fd, address = sock._accept()
except BlockingIOError: except BlockingIOError: # python 2: pylint: disable=undefined-variable
if not sock.timeout: if not sock.timeout:
return return
raise raise
......
...@@ -18,7 +18,7 @@ from gevent.hub import PY3 ...@@ -18,7 +18,7 @@ from gevent.hub import PY3
if PY3: if PY3:
from gevent import _socket3 as _source from gevent import _socket3 as _source # python 2: pylint:disable=no-name-in-module
else: else:
from gevent import _socket2 as _source from gevent import _socket2 as _source
......
...@@ -19,9 +19,9 @@ __implements__ = ['allocate_lock', ...@@ -19,9 +19,9 @@ __implements__ = ['allocate_lock',
__imports__ = ['error'] __imports__ = ['error']
if sys.version_info[0] <= 2: if sys.version_info[0] <= 2:
import thread as __thread__ # pylint:disable=import-error,useless-suppression import thread as __thread__ # pylint:disable=import-error
else: else:
import _thread as __thread__ import _thread as __thread__ # pylint:disable=import-error
__target__ = '_thread' __target__ = '_thread'
__imports__ += ['RLock', __imports__ += ['RLock',
'TIMEOUT_MAX', 'TIMEOUT_MAX',
...@@ -57,7 +57,7 @@ class LockType(BoundedSemaphore): ...@@ -57,7 +57,7 @@ class LockType(BoundedSemaphore):
_OVER_RELEASE_ERROR = __thread__.error _OVER_RELEASE_ERROR = __thread__.error
if PY3: if PY3:
_TIMEOUT_MAX = __thread__.TIMEOUT_MAX _TIMEOUT_MAX = __thread__.TIMEOUT_MAX # python 2: pylint:disable=no-member
def acquire(self, blocking=True, timeout=-1): def acquire(self, blocking=True, timeout=-1):
# Transform the default -1 argument into the None that our # Transform the default -1 argument into the None that our
......
...@@ -50,6 +50,7 @@ class _ErrorFormatter(object): ...@@ -50,6 +50,7 @@ class _ErrorFormatter(object):
self.formatMessage = FormatMessage self.formatMessage = FormatMessage
self.errorTab = errorTab self.errorTab = errorTab
@classmethod
def fromEnvironment(cls): def fromEnvironment(cls):
""" """
Get as many of the platform-specific error translation objects as Get as many of the platform-specific error translation objects as
...@@ -68,7 +69,6 @@ class _ErrorFormatter(object): ...@@ -68,7 +69,6 @@ class _ErrorFormatter(object):
except ImportError: except ImportError:
errorTab = None errorTab = None
return cls(WinError, FormatMessage, errorTab) return cls(WinError, FormatMessage, errorTab)
fromEnvironment = classmethod(fromEnvironment)
def formatError(self, errorcode): def formatError(self, errorcode):
""" """
......
from __future__ import print_function
import re
import sys
from prospector.run import main
def _excepthook(e, t, tb):
while tb is not None:
frame = tb.tb_frame
print(frame.f_code, frame.f_code.co_name)
for n in ('self', 'node', 'elt'):
if n in frame.f_locals:
print(n, frame.f_locals[n])
print('---')
tb = tb.tb_next
sys.excepthook = _excepthook
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())
...@@ -27,8 +27,7 @@ basepython = ...@@ -27,8 +27,7 @@ basepython =
python2.7 python2.7
deps = deps =
{[testenv]deps} {[testenv]deps}
pep8 prospector
pyflakes
commands = commands =
make lint make lint
......
#!/usr/bin/env python
from __future__ import print_function
import sys
import re
import subprocess
import glob
IGNORED = r"""
examples/webchat/urls.py:1: 'from django.conf.urls.defaults import *' used; unable to detect undefined names
gevent/_?ssl[23]?.py:\d+: undefined name
gevent/__init__.py:\d+: redefinition of unused 'signal' from line
gevent/__init__.py:\d+: redefinition of unused 'socket' from line
gevent/__init__.py:\d+:.*imported but unused
gevent/_socket[23].py:\d+: undefined name
gevent/_socketcommon.py:\d+: .*imported but unused
gevent/_socketcommon.py:\d+: undefined name
gevent/_sslgte279.py:.*
gevent/core.py:\d+: 'from gevent.corecext import *' used; unable to detect undefined names
gevent/core.py:\d+: 'from gevent.corecffi import *' used; unable to detect undefined names
gevent/coros.py:\d+: '__all__' imported but unused
gevent/coros.py:\d+: 'from gevent.lock import *' used; unable to detect undefined names
gevent/hub.py:\d+: 'reraise' imported but unused
gevent/os.py:\d+: redefinition of unused 'fork' from line
gevent/socket.py:\d+: undefined name
gevent/subprocess.py:\d+: undefined name
gevent/thread.py:\d+: '_local' imported but unused
gevent/threading.py:\d+: '\w+' imported but unused
gevent/wsgi.py:1: 'from gevent.pywsgi import *' used; unable to detect undefined names
greentest/test__queue.py:\d+: undefined name 'GenericGetTestCase'
greentest/test__server_pywsgi.py:
"""
# Travis runs this on Python 2, but this is only defined
# and used, in Python 3
IGNORED += r"""
gevent/server.py:\d+: undefined name 'BlockingIOError'
"""
IGNORED = IGNORED.strip().replace(' *', ' \\*').split('\n')
def is_ignored(line):
for pattern in IGNORED:
if re.match(pattern, line):
return True
def pyflakes(args):
popen = subprocess.Popen('%s `which pyflakes` %s' % (sys.executable, args),
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
output, errors = popen.communicate()
if errors:
sys.stderr.write(errors.decode())
if popen.poll() != 1:
sys.stderr.write(output + '\n')
sys.exit('pyflakes returned %r' % popen.poll())
if errors:
sys.exit(1)
assert output
output = output.decode('utf-8')
output = output.strip().split('\n')
failed = False
for line in output:
line = line.strip()
if not is_ignored(line):
print('E %s' % line)
failed = True
#else:
# print('I %s' % line)
if failed:
sys.exit(1)
pyflakes('examples/ greentest/*.py util/ *.py')
if sys.version_info[0] == 3:
ignored_files = ['gevent/_util_py2.py', 'gevent/_socket2.py', 'gevent/_fileobject2.py',
'gevent/builtins.py']
else:
ignored_files = ['gevent/_socket3.py', 'gevent/_fileobject3.py']
ignored_files.append('gevent/wsgi.py')
py = set(glob.glob('gevent/*.py')) - set(ignored_files)
pyflakes(' '.join(py))
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