Commit bdd1a4ec authored by Jason Madden's avatar Jason Madden

Make sure Channel is actually iterable in py3. Pointed out by pylint. cleanup queue.

cleanup threadpool.
various small cleanups.
cleanup _fileobjectposix.
parent 913b18bc
...@@ -27,6 +27,8 @@ ignore-paths: ...@@ -27,6 +27,8 @@ ignore-paths:
- gevent/_tblib.py - gevent/_tblib.py
# likewise # likewise
- greentest/six.py - greentest/six.py
# sadly, this one is complicated
- setup.py
- greentest/getaddrinfo_module.py - greentest/getaddrinfo_module.py
ignore-patterns: ignore-patterns:
# disabled code # disabled code
...@@ -55,3 +57,5 @@ pyflakes: ...@@ -55,3 +57,5 @@ pyflakes:
- F401 - F401
# F811: redefined function; same story # F811: redefined function; same story
- F811 - F811
# F403: wildcard import; same story
- F403
...@@ -58,7 +58,9 @@ generated-members=exc_clear ...@@ -58,7 +58,9 @@ generated-members=exc_clear
# List of classes names for which member attributes should not be checked # List of classes names for which member attributes should not be checked
# (useful for classes with attributes dynamically set). This supports can work # (useful for classes with attributes dynamically set). This supports can work
# with qualified names. # with qualified names.
ignored-classes=SSLContext, SSLSocket, greenlet # greenlet, Greenlet, parent, dead: all attempts to fix issues in greenlet.py
# only seen on the service, e.g., self.parent.loop: class parent has no loop
ignored-classes=SSLContext, SSLSocket, greenlet, Greenlet, parent, dead
# List of module names for which member attributes should not be checked # List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime # (useful for modules/projects where namespaces are manipulated during runtime
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
- Remove module ``gevent.coros`` which was replaced by ``gevent.lock`` - Remove module ``gevent.coros`` which was replaced by ``gevent.lock``
and has been deprecated since 1.0b2. and has been deprecated since 1.0b2.
- The ``ref`` parameter to :func:`gevent.os.fork_and_watch` was being ignored. - The ``ref`` parameter to :func:`gevent.os.fork_and_watch` was being ignored.
- Python 3: :class:`gevent.queue.Channel` is now correctly iterable, instead of
raising a :exc:`TypeError`.
1.1.0 (Mar 5, 2016) 1.1.0 (Mar 5, 2016)
=================== ===================
......
...@@ -44,7 +44,7 @@ __all__ = ['get_hub', ...@@ -44,7 +44,7 @@ __all__ = ['get_hub',
import sys import sys
if sys.platform == 'win32': if sys.platform == 'win32':
# trigger WSAStartup call # trigger WSAStartup call
import socket # pylint:disable=unused-import import socket # pylint:disable=unused-import,useless-suppression
del socket del socket
from gevent.hub import get_hub, iwait, wait, PYPY from gevent.hub import get_hub, iwait, wait, PYPY
......
...@@ -24,6 +24,9 @@ class GreenFileDescriptorIO(RawIOBase): ...@@ -24,6 +24,9 @@ class GreenFileDescriptorIO(RawIOBase):
# the type's tp_dealloc slot; prior to Python 3, the object doesn't # the type's tp_dealloc slot; prior to Python 3, the object doesn't
# appear to have a __del__ method, even though it functionally does) # appear to have a __del__ method, even though it functionally does)
_read_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)
self._closed = False self._closed = False
...@@ -33,15 +36,14 @@ class GreenFileDescriptorIO(RawIOBase): ...@@ -33,15 +36,14 @@ class GreenFileDescriptorIO(RawIOBase):
self._readable = 'r' in mode self._readable = 'r' in mode
self._writable = 'w' in mode self._writable = 'w' in mode
self.hub = get_hub() self.hub = get_hub()
io = self.hub.loop.io
io_watcher = self.hub.loop.io
if self._readable: if self._readable:
self._read_event = io(fileno, 1) self._read_event = io_watcher(fileno, 1)
else:
self._read_event = None
if self._writable: if self._writable:
self._write_event = io(fileno, 2) self._write_event = io_watcher(fileno, 2)
else:
self._write_event = None
self._seekable = None self._seekable = None
def readable(self): def readable(self):
...@@ -231,10 +233,12 @@ class FileObjectPosix(object): ...@@ -231,10 +233,12 @@ class FileObjectPosix(object):
bufsize = 1 bufsize = 1
if mode == 'r': if mode == 'r':
self.io = BufferedReader(self.fileio, bufsize) IOFamily = BufferedReader
else: else:
assert mode == 'w' assert mode == 'w'
self.io = BufferedWriter(self.fileio, bufsize) IOFamily = BufferedWriter
self.io = IOFamily(self.fileio, bufsize)
#else: # QQQ: not used, not reachable #else: # QQQ: not used, not reachable
# #
# self.io = BufferedRandom(self.fileio, bufsize) # self.io = BufferedRandom(self.fileio, bufsize)
......
...@@ -99,7 +99,7 @@ class Semaphore(object): ...@@ -99,7 +99,7 @@ class Semaphore(object):
return return
try: try:
link(self) # Must use Cython >= 0.23.4 on PyPy else this leaks memory link(self) # Must use Cython >= 0.23.4 on PyPy else this leaks memory
except: except: # pylint:disable=bare-except
getcurrent().handle_error((link, self), *sys.exc_info()) getcurrent().handle_error((link, self), *sys.exc_info())
if self._dirty: if self._dirty:
# We mutated self._links so we need to start over # We mutated self._links so we need to start over
......
...@@ -298,7 +298,7 @@ class SSLSocket(socket): ...@@ -298,7 +298,7 @@ class SSLSocket(socket):
# 3.5+ # 3.5+
def selected_alpn_protocol(self): def selected_alpn_protocol(self):
self._checkClosed() self._checkClosed()
if not self._sslobj or not _ssl.HAS_ALPN: if not self._sslobj or not _ssl.HAS_ALPN: # pylint:disable=no-member
return None return None
else: else:
return self._sslobj.selected_alpn_protocol() return self._sslobj.selected_alpn_protocol()
......
...@@ -376,7 +376,7 @@ class SSLSocket(socket): ...@@ -376,7 +376,7 @@ class SSLSocket(socket):
# 2.7.10+ # 2.7.10+
def selected_alpn_protocol(self): def selected_alpn_protocol(self):
self._checkClosed() self._checkClosed()
if not self._sslobj or not _ssl.HAS_ALPN: if not self._sslobj or not _ssl.HAS_ALPN: # pylint:disable=no-member
return None return None
else: else:
return self._sslobj.selected_alpn_protocol() return self._sslobj.selected_alpn_protocol()
......
...@@ -407,12 +407,12 @@ def patch_socket(dns=True, aggressive=True): ...@@ -407,12 +407,12 @@ def patch_socket(dns=True, aggressive=True):
# However, because gevent.socket.socket.connect is a Python function, the exception raised by it causes # However, because gevent.socket.socket.connect is a Python function, the exception raised by it causes
# _socket object to be referenced by the frame, thus causing the next invocation of bind(source_address) to fail. # _socket object to be referenced by the frame, thus causing the next invocation of bind(source_address) to fail.
if dns: if dns:
items = socket.__implements__ items = socket.__implements__ # pylint:disable=no-member
else: else:
items = set(socket.__implements__) - set(socket.__dns__) items = set(socket.__implements__) - set(socket.__dns__) # pylint:disable=no-member
patch_module('socket', items=items) patch_module('socket', items=items)
if aggressive: if aggressive:
if 'ssl' not in socket.__implements__: if 'ssl' not in socket.__implements__: # pylint:disable=no-member
remove_item(socket, 'ssl') remove_item(socket, 'ssl')
...@@ -423,7 +423,7 @@ def patch_dns(): ...@@ -423,7 +423,7 @@ def patch_dns():
by that method if requested. by that method if requested.
""" """
from gevent import socket from gevent import socket
patch_module('socket', items=socket.__dns__) patch_module('socket', items=socket.__dns__) # pylint:disable=no-member
def patch_ssl(): def patch_ssl():
......
...@@ -105,6 +105,8 @@ class Queue(object): ...@@ -105,6 +105,8 @@ class Queue(object):
return type(self)(self.maxsize, self.queue) return type(self)(self.maxsize, self.queue)
def _init(self, maxsize, items=None): def _init(self, maxsize, items=None):
# FIXME: Why is maxsize unused or even passed?
# pylint:disable=unused-argument
if items: if items:
self.queue = collections.deque(items) self.queue = collections.deque(items)
else: else:
...@@ -321,7 +323,7 @@ class Queue(object): ...@@ -321,7 +323,7 @@ class Queue(object):
try: try:
putter = self.putters.popleft() putter = self.putters.popleft()
self._put(putter.item) self._put(putter.item)
except: except: # pylint:disable=bare-except
putter.throw(*sys.exc_info()) putter.throw(*sys.exc_info())
else: else:
putter.switch(putter) putter.switch(putter)
...@@ -378,9 +380,11 @@ class PriorityQueue(Queue): ...@@ -378,9 +380,11 @@ class PriorityQueue(Queue):
self.queue = [] self.queue = []
def _put(self, item, heappush=heapq.heappush): def _put(self, item, heappush=heapq.heappush):
# pylint:disable=arguments-differ
heappush(self.queue, item) heappush(self.queue, item)
def _get(self, heappop=heapq.heappop): def _get(self, heappop=heapq.heappop):
# pylint:disable=arguments-differ
return heappop(self.queue) return heappop(self.queue)
...@@ -593,3 +597,5 @@ class Channel(object): ...@@ -593,3 +597,5 @@ class Channel(object):
if result is StopIteration: if result is StopIteration:
raise result raise result
return result return result
__next__ = next # py3
...@@ -189,6 +189,7 @@ class ThreadPool(GroupMappingMixin): ...@@ -189,6 +189,7 @@ class ThreadPool(GroupMappingMixin):
self._size -= 1 self._size -= 1
def _worker(self): def _worker(self):
# pylint:disable=too-many-branches
need_decrease = True need_decrease = True
try: try:
while True: while True:
...@@ -205,7 +206,7 @@ class ThreadPool(GroupMappingMixin): ...@@ -205,7 +206,7 @@ class ThreadPool(GroupMappingMixin):
func, args, kwargs, thread_result = task func, args, kwargs, thread_result = task
try: try:
value = func(*args, **kwargs) value = func(*args, **kwargs)
except: except: # pylint:disable=bare-except
exc_info = getattr(sys, 'exc_info', None) exc_info = getattr(sys, 'exc_info', None)
if exc_info is None: if exc_info is None:
return return
...@@ -219,7 +220,7 @@ class ThreadPool(GroupMappingMixin): ...@@ -219,7 +220,7 @@ class ThreadPool(GroupMappingMixin):
del func, args, kwargs, thread_result, task del func, args, kwargs, thread_result, task
finally: finally:
if sys is None: if sys is None:
return return # pylint:disable=lost-exception
task_queue.task_done() task_queue.task_done()
finally: finally:
if need_decrease: if need_decrease:
...@@ -230,6 +231,7 @@ class ThreadPool(GroupMappingMixin): ...@@ -230,6 +231,7 @@ class ThreadPool(GroupMappingMixin):
.. deprecated:: 1.1a2 .. deprecated:: 1.1a2
Identical to :meth:`apply`; the ``expected_errors`` argument is ignored. Identical to :meth:`apply`; the ``expected_errors`` argument is ignored.
""" """
# pylint:disable=unused-argument
# Deprecated but never documented. In the past, before # Deprecated but never documented. In the past, before
# self.apply() allowed all errors to be raised to the caller, # self.apply() allowed all errors to be raised to the caller,
# expected_errors allowed a caller to specify a set of errors # expected_errors allowed a caller to specify a set of errors
......
...@@ -29,6 +29,7 @@ class _FakeTimer(object): ...@@ -29,6 +29,7 @@ class _FakeTimer(object):
active = False active = False
def start(self, *args, **kwargs): def start(self, *args, **kwargs):
# pylint:disable=unused-argument
raise AssertionError("non-expiring timer cannot be started") raise AssertionError("non-expiring timer cannot be started")
def stop(self): def stop(self):
......
...@@ -9,7 +9,7 @@ pipelining, and not supporting SSL. ...@@ -9,7 +9,7 @@ pipelining, and not supporting SSL.
Use :mod:`gevent.pywsgi` Use :mod:`gevent.pywsgi`
""" """
from gevent.pywsgi import * from gevent.pywsgi import * # pylint:disable=wildcard-import
import gevent.pywsgi as _pywsgi import gevent.pywsgi as _pywsgi
__all__ = _pywsgi.__all__ __all__ = _pywsgi.__all__
del _pywsgi del _pywsgi
...@@ -49,8 +49,7 @@ test_patched_threading.* ...@@ -49,8 +49,7 @@ test_patched_threading.*
def make_re(tests): def make_re(tests):
tests = [x.strip().replace(r'\.', r'\\.').replace('*', '.*?') tests = [x.strip().replace(r'\.', r'\\.').replace('*', '.*?')
for x in tests.split('\n') if x.strip()] for x in tests.split('\n') if x.strip()]
tests = re.compile('^%s$' % '|'.join(tests)) return re.compile('^%s$' % '|'.join(tests))
return tests
no_switch_tests = make_re(no_switch_tests) no_switch_tests = make_re(no_switch_tests)
...@@ -68,6 +67,9 @@ def get_switch_expected(fullname): ...@@ -68,6 +67,9 @@ def get_switch_expected(fullname):
>>> get_switch_expected("test_patched_httplib.BasicTest.test_bad_status_repr") >>> get_switch_expected("test_patched_httplib.BasicTest.test_bad_status_repr")
False False
""" """
# certain pylint versions mistype the globals as
# str, not re.
# pylint:disable=no-member
if ignore_switch_tests.match(fullname) is not None: if ignore_switch_tests.match(fullname) is not None:
return None return None
if no_switch_tests.match(fullname) is not None: if no_switch_tests.match(fullname) is not None:
......
...@@ -254,6 +254,12 @@ class TestChannel(TestCase): ...@@ -254,6 +254,12 @@ class TestChannel(TestCase):
channel.task_done() channel.task_done()
assert channel.unfinished_tasks == 0, channel.unfinished_tasks assert channel.unfinished_tasks == 0, channel.unfinished_tasks
def test_iterable(self):
channel = queue.Channel()
gevent.spawn(channel.put, StopIteration)
r = list(channel)
self.assertEqual(r, [])
class TestNoWait(TestCase): class TestNoWait(TestCase):
......
...@@ -5,7 +5,8 @@ ...@@ -5,7 +5,8 @@
# N813: camelCase imported as lowercase; socketcommon # N813: camelCase imported as lowercase; socketcommon
# N806: variable in function should be lowercase; but sometimes we want constant-looking names, especially for closures # 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 # 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 # N805: first arg should be self; fails on metaclasses and classmethods; pylint does a better job
ignore=E702,E265,E402,E731,E266,E261,W503,E129,N801,N802,N803,N813,N806,N812,N805
max_line_length=160 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 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
......
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