Commit ebfc9c3f authored by Denis Bilenko's avatar Denis Bilenko

reorganize the package; rename timeout to Timeout; Hub's recovering from errors

- all the functions from __init__.py were moved to gevent/greenlet.py; __init__ imports only some of them back
- gevent.timeout is now known as gevent.Timeout
- Hub now tries to recover after dispatch() failures (seen only(?) on epoll even though event_reinit() was called as necessary)
  This helps to pass test_socketserver.py all the time, not occasionally like before
- wsgi_test.py: move ssl tests to a separate class
- libevent version checking is gone as its done by gevent.core now

--HG--
rename : gevent/__init__.py => gevent/greenlet.py
parent f93c5023
import sys
import os
import traceback
from gevent import core
try:
from py.magic import greenlet
Greenlet = greenlet
except ImportError:
import greenlet
Greenlet = greenlet.greenlet
getcurrent = greenlet.getcurrent
GreenletExit = greenlet.GreenletExit
version_info = (0, 9, 1) version_info = (0, 9, 1)
__version__ = '0.9.1' __version__ = '0.9.1'
__all__ = ['Greenlet', __all__ = ['getcurrent',
'getcurrent',
'GreenletExit',
'MAIN',
'TimeoutError', 'TimeoutError',
'Timeout',
'spawn', 'spawn',
'spawn_later', 'spawn_later',
'kill', 'kill',
'get_hub',
'sleep', 'sleep',
'wait_reader', 'signal',
'wait_writer', 'with_timeout',
'timeout', 'fork']
'with_timeout']
libevent_version = core.get_version()
libevent_headers_version = core.get_header_version()
if libevent_headers_version is not None and libevent_version != libevent_headers_version:
import warnings
msg = "version mismatch: system libevent version is %r but this gevent is compiled against %r" % (libevent_version, libevent_headers_version)
warnings.warn(msg, UserWarning, stacklevel=2)
_threadlocal = None
MAIN = greenlet.getcurrent()
def timer(*args, **kwargs):
return core.timer(*args, **kwargs)
class TimeoutError(Exception):
"""Exception raised if an asynchronous operation times out"""
def spawn(function, *args, **kwargs):
"""Create a new greenlet that will run `function(*args)'.
The current greenlet won't be unscheduled. Keyword arguments aren't
supported (limitation of greenlet), use spawn() to work around that.
"""
g = Greenlet(lambda : function(*args, **kwargs))
g.parent = get_hub().greenlet
timer(0, g.switch)
return g
def spawn_later(seconds, function, *args, **kwargs):
"""Create a new greenlet that will run `function(*args)'.
The current greenlet won't be unscheduled. Keyword arguments aren't
supported (limitation of greenlet), use spawn() to work around that.
"""
g = Greenlet(lambda : function(*args, **kwargs))
g.parent = get_hub().greenlet
timer(seconds, g.switch)
return g
def kill(g, *throw_args):
timer(0, g.throw, *throw_args)
if getcurrent() is not get_hub().greenlet:
sleep(0)
def get_hub():
global _threadlocal
try:
hub = _threadlocal.hub
except AttributeError:
# do not import anything that can be monkey-patched at top level
import threading
_threadlocal = threading.local()
hub = _threadlocal.hub = Hub()
return hub
def sleep(seconds=0):
"""Yield control to another eligible coroutine until at least *seconds* have
elapsed.
*seconds* may be specified as an integer, or a float if fractional seconds
are desired. Calling sleep with *seconds* of 0 is the canonical way of
expressing a cooperative yield. For example, if one is looping over a
large list performing an expensive calculation without calling any socket
methods, it's a good idea to call ``sleep(0)`` occasionally; otherwise
nothing else will run.
"""
hub = get_hub()
assert hub.greenlet is not greenlet.getcurrent(), 'do not call blocking functions from the mainloop'
t = timer(seconds, greenlet.getcurrent().switch)
try:
hub.switch()
finally:
t.cancel()
class Hub(object):
def __init__(self):
self.greenlet = Greenlet(self.run)
self.keyboard_interrupt_signal = None
def switch(self):
cur = getcurrent()
assert cur is not self.greenlet, 'Cannot switch to MAINLOOP from MAINLOOP'
switch_out = getattr(cur, 'switch_out', None)
if switch_out is not None:
try:
switch_out()
except:
traceback.print_exception(*sys.exc_info())
if self.greenlet.dead:
self.greenlet = Greenlet(self.run)
return self.greenlet.switch()
def run(self, *args, **kwargs):
if self.keyboard_interrupt_signal is None:
self.keyboard_interrupt_signal = signal(2, MAIN.throw, KeyboardInterrupt)
while True:
result = core.dispatch()
if result>0:
return 'Hub.run() has finished because there are no events registered'
elif result<0:
return 'Hub.run() has finished because there was an error'
return result
def signal(signalnum, handler, *args, **kwargs):
def deliver_exception_to_MAIN():
try:
handler(*args, **kwargs)
except:
MAIN.throw(*sys.exc_info())
return core.signal(signalnum, deliver_exception_to_MAIN)
def _wait_helper(ev, fd, evtype):
current, timeout_exc = ev.arg
if evtype & core.EV_TIMEOUT:
current.throw(timeout_exc)
else:
current.switch(ev)
def wait_reader(fileno, timeout=-1, timeout_exc=TimeoutError):
evt = core.read(fileno, _wait_helper, timeout, (getcurrent(), timeout_exc))
try:
returned_ev = get_hub().switch()
assert evt is returned_ev, (evt, returned_ev)
finally:
evt.cancel()
def wait_writer(fileno, timeout=-1, timeout_exc=TimeoutError):
evt = core.write(fileno, _wait_helper, timeout, (getcurrent(), timeout_exc))
try:
returned_ev = get_hub().switch()
assert evt is returned_ev, (evt, returned_ev)
finally:
evt.cancel()
class _SilentException:
pass
class timeout(object):
"""Schedule an exception to raise in the current greenlet (TimeoutError by default).
Raise an exception in the block after timeout.
with timeout(seconds[, exc]):
... code block ...
Assuming code block is yielding (i.e. gives up control to the hub),
an exception provided in `exc' argument will be raised
(TimeoutError if `exc' is omitted).
When exc is None, code block is interrupted silently.
"""
def __init__(self, seconds, exception=TimeoutError):
if exception is None:
exception = _SilentException()
self.exception = exception
if seconds is None:
self.timeout = None
else:
self.timeout = timer(seconds, getcurrent().throw, exception)
def cancel(self):
if self.timeout is not None:
self.timeout.cancel()
def __repr__(self):
if self.timeout is not None:
return repr(self.timeout)
else:
return '<fake timeout>'
def __enter__(self):
return self
def __exit__(self, typ, value, tb):
self.cancel()
if typ is _SilentException and value is self.exception:
return True
def with_timeout(seconds, func, *args, **kwds):
"""Wrap a call to some (yielding) function with a timeout; if the called
function fails to return before the timeout, cancel it and return a flag
value.
seconds
(int or float) seconds before timeout occurs
func
the callable to execute with a timeout; must be one of the functions
that implicitly or explicitly yields
\*args, \*\*kwds
(positional, keyword) arguments to pass to *func*
timeout_value=
value to return if timeout occurs (default raise ``TimeoutError``)
**Returns**:
Value returned by *func* if *func* returns before *seconds*, else
*timeout_value* if provided, else raise ``TimeoutError``
**Raises**:
Any exception raised by *func*, and ``TimeoutError`` if *func* times out
and no ``timeout_value`` has been provided.
**Example**::
data = with_timeout(30, httpc.get, 'http://www.google.com/', timeout_value="")
Here *data* is either the result of the ``get()`` call, or the empty string if # add here Queue, Event, Pipe?, Socket?
it took too long to return. Any exception raised by the ``get()`` call is
passed through to the caller.
"""
# Recognize a specific keyword argument, while also allowing pass-through
# of any other keyword arguments accepted by func. Use pop() so we don't
# pass timeout_value through to func().
has_timeout_value = "timeout_value" in kwds
timeout_value = kwds.pop("timeout_value", None)
error = TimeoutError()
timer = timeout(seconds, error)
try:
try:
return func(*args, **kwds)
except TimeoutError, ex:
if ex is error and has_timeout_value:
return timeout_value
raise
finally:
timer.cancel()
_original_fork = os.fork from gevent.greenlet import *
def fork():
result = _original_fork()
core.reinit()
return result
...@@ -26,7 +26,8 @@ import socket ...@@ -26,7 +26,8 @@ import socket
import sys import sys
from code import InteractiveConsole from code import InteractiveConsole
import gevent from gevent.greenlet import Greenlet
from gevent import core
try: try:
sys.ps1 sys.ps1
...@@ -38,7 +39,7 @@ except AttributeError: ...@@ -38,7 +39,7 @@ except AttributeError:
sys.ps2 = '... ' sys.ps2 = '... '
class SocketConsole(gevent.Greenlet): class SocketConsole(Greenlet):
def __init__(self, desc, hostport, locals): def __init__(self, desc, hostport, locals):
self.hostport = hostport self.hostport = hostport
self.locals = locals self.locals = locals
...@@ -57,7 +58,7 @@ class SocketConsole(gevent.Greenlet): ...@@ -57,7 +58,7 @@ class SocketConsole(gevent.Greenlet):
self.old[key] = getattr(desc, key) self.old[key] = getattr(desc, key)
setattr(desc, key, value) setattr(desc, key, value)
gevent.Greenlet.__init__(self) Greenlet.__init__(self)
def run(self): def run(self):
try: try:
...@@ -70,7 +71,7 @@ class SocketConsole(gevent.Greenlet): ...@@ -70,7 +71,7 @@ class SocketConsole(gevent.Greenlet):
def switch(self, *args, **kw): def switch(self, *args, **kw):
self.saved = sys.stdin, sys.stderr, sys.stdout self.saved = sys.stdin, sys.stderr, sys.stdout
sys.stdin = sys.stdout = sys.stderr = self.desc sys.stdin = sys.stdout = sys.stderr = self.desc
gevent.Greenlet.switch(self, *args, **kw) Greenlet.switch(self, *args, **kw)
def switch_out(self): def switch_out(self):
sys.stdin, sys.stderr, sys.stdout = self.saved sys.stdin, sys.stderr, sys.stdout = self.saved
...@@ -100,7 +101,7 @@ def backdoor_server(server, locals=None): ...@@ -100,7 +101,7 @@ def backdoor_server(server, locals=None):
fl = conn.makeGreenFile("rw") fl = conn.makeGreenFile("rw")
fl.newlines = '\n' fl.newlines = '\n'
greenlet = SocketConsole(fl, (host, port), locals) greenlet = SocketConsole(fl, (host, port), locals)
gevent.timer(0, greenlet.switch) core.timer(0, greenlet.switch)
except socket.error, e: except socket.error, e:
# Broken pipe means it was shutdown # Broken pipe means it was shutdown
if e[0] != 32: if e[0] != 32:
...@@ -118,7 +119,7 @@ def backdoor((conn, addr), locals=None): ...@@ -118,7 +119,7 @@ def backdoor((conn, addr), locals=None):
fl = conn.makeGreenFile("rw") fl = conn.makeGreenFile("rw")
fl.newlines = '\n' fl.newlines = '\n'
greenlet = SocketConsole(fl, (host, port), locals) greenlet = SocketConsole(fl, (host, port), locals)
gevent.timer(0, greenlet.switch) core.timer(0, greenlet.switch)
if __name__ == '__main__': if __name__ == '__main__':
......
...@@ -25,8 +25,8 @@ import collections ...@@ -25,8 +25,8 @@ import collections
import time import time
import traceback import traceback
import gevent from gevent.core import timer
from gevent import get_hub, spawn, getcurrent, sleep from gevent.greenlet import get_hub, spawn, getcurrent, sleep
class Cancelled(RuntimeError): class Cancelled(RuntimeError):
...@@ -187,7 +187,7 @@ class event(object): ...@@ -187,7 +187,7 @@ class event(object):
exc = (exc, ) exc = (exc, )
self._exc = exc self._exc = exc
if self._waiters: if self._waiters:
gevent.timer(0, self._do_send, self._result, self._exc, self._waiters.copy()) timer(0, self._do_send, self._result, self._exc, self._waiters.copy())
def _do_send(self, result, exc, waiters): def _do_send(self, result, exc, waiters):
while waiters: while waiters:
...@@ -249,7 +249,7 @@ class Semaphore(object): ...@@ -249,7 +249,7 @@ class Semaphore(object):
# `blocking' parameter is for consistency with BoundedSemaphore and is ignored # `blocking' parameter is for consistency with BoundedSemaphore and is ignored
self.counter += 1 self.counter += 1
if self._waiters: if self._waiters:
gevent.timer(0, self._do_acquire) timer(0, self._do_acquire)
return True return True
def _do_acquire(self): def _do_acquire(self):
...@@ -373,7 +373,7 @@ class Queue(object): ...@@ -373,7 +373,7 @@ class Queue(object):
exc = (exc, ) exc = (exc, )
self.items.append((result, exc)) self.items.append((result, exc))
if self._waiters and self._timer is None: if self._waiters and self._timer is None:
self._timer = gevent.timer(0, self._do_send) self._timer = timer(0, self._do_send)
def send_exception(self, *args): def send_exception(self, *args):
# the arguments are the same as for greenlet.throw # the arguments are the same as for greenlet.throw
...@@ -442,7 +442,7 @@ class Channel(object): ...@@ -442,7 +442,7 @@ class Channel(object):
if getcurrent() is get_hub().greenlet: if getcurrent() is get_hub().greenlet:
self.items.append((result, exc)) self.items.append((result, exc))
if self._waiters and self._timer is None: if self._waiters and self._timer is None:
self._timer = gevent.timer(0, self._do_switch) self._timer = timer(0, self._do_switch)
else: else:
if self._waiters and self._senders: if self._waiters and self._senders:
sleep(0) sleep(0)
...@@ -450,7 +450,7 @@ class Channel(object): ...@@ -450,7 +450,7 @@ class Channel(object):
# note that send() does not work well with timeouts. if your timeout fires # note that send() does not work well with timeouts. if your timeout fires
# after this point, the item will remain in the queue # after this point, the item will remain in the queue
if self._waiters and self._timer is None: if self._waiters and self._timer is None:
self._timer = gevent.timer(0, self._do_switch) self._timer = timer(0, self._do_switch)
if len(self.items) > self.max_size: if len(self.items) > self.max_size:
self._senders.add(getcurrent()) self._senders.add(getcurrent())
try: try:
...@@ -487,14 +487,14 @@ class Channel(object): ...@@ -487,14 +487,14 @@ class Channel(object):
if self.items: if self.items:
result, exc = self.items.popleft() result, exc = self.items.popleft()
if len(self.items) <= self.max_size and self._timer is None: if len(self.items) <= self.max_size and self._timer is None:
self._timer = gevent.timer(0, self._do_switch) self._timer = timer(0, self._do_switch)
if exc is None: if exc is None:
return result return result
else: else:
getcurrent().throw(*exc) getcurrent().throw(*exc)
else: else:
if self._senders and self._timer is None: if self._senders and self._timer is None:
self._timer = gevent.timer(0, self._do_switch) self._timer = timer(0, self._do_switch)
self._waiters.add(getcurrent()) self._waiters.add(getcurrent())
try: try:
result, exc = get_hub().switch() result, exc = get_hub().switch()
......
import sys
import os
import traceback
from gevent import core
__all__ = ['getcurrent',
'TimeoutError',
'Timeout',
'spawn',
'spawn_later',
'kill',
'killall',
'sleep',
'signal',
'with_timeout',
'fork']
try:
from py.magic import greenlet
Greenlet = greenlet
except ImportError:
greenlet = __import__('greenlet')
Greenlet = greenlet.greenlet
getcurrent = greenlet.getcurrent
GreenletExit = greenlet.GreenletExit
MAIN = greenlet.getcurrent()
_threadlocal = None
class TimeoutError(Exception):
"""Exception raised if an asynchronous operation times out"""
def spawn(function, *args, **kwargs):
g = Greenlet(lambda : function(*args, **kwargs))
g.parent = get_hub().greenlet
core.timer(0, g.switch)
return g
def spawn_later(seconds, function, *args, **kwargs):
g = Greenlet(lambda : function(*args, **kwargs))
g.parent = get_hub().greenlet
core.timer(seconds, g.switch)
return g
def kill(g, *throw_args):
core.timer(0, g.throw, *throw_args)
if get_hub().greenlet is not getcurrent():
sleep()
def killall(greenlets, *throw_args):
for g in greenlets:
if not g.dead:
core.timer(0, g.throw, *throw_args)
if get_hub().greenlet is not getcurrent():
sleep()
def sleep(seconds=0):
"""Yield control to another eligible coroutine until at least *seconds* have
elapsed.
*seconds* may be specified as an integer, or a float if fractional seconds
are desired. Calling sleep with *seconds* of 0 is the canonical way of
expressing a cooperative yield. For example, if one is looping over a
large list performing an expensive calculation without calling any socket
methods, it's a good idea to call ``sleep(0)`` occasionally; otherwise
nothing else will run.
"""
hub = get_hub()
assert hub.greenlet is not greenlet.getcurrent(), 'do not call blocking functions from the mainloop'
t = core.timer(seconds, greenlet.getcurrent().switch)
try:
hub.switch()
finally:
t.cancel()
def signal(signalnum, handler, *args, **kwargs):
def deliver_exception_to_MAIN():
try:
handler(*args, **kwargs)
except:
MAIN.throw(*sys.exc_info())
return core.signal(signalnum, deliver_exception_to_MAIN)
def get_hub():
global _threadlocal
try:
hub = _threadlocal.hub
except AttributeError:
# do not import anything that can be monkey-patched at top level
import threading
# XXX use _local directly from _thread or from _threadlocal
_threadlocal = threading.local()
hub = _threadlocal.hub = Hub()
return hub
class Hub(object):
def __init__(self):
self.greenlet = Greenlet(self.run)
self.keyboard_interrupt_signal = None
def switch(self):
cur = getcurrent()
assert cur is not self.greenlet, 'Cannot switch to MAINLOOP from MAINLOOP'
switch_out = getattr(cur, 'switch_out', None)
if switch_out is not None:
try:
switch_out()
except:
traceback.print_exception(*sys.exc_info())
if self.greenlet.dead:
self.greenlet = Greenlet(self.run)
return self.greenlet.switch()
def run(self):
if self.keyboard_interrupt_signal is None:
self.keyboard_interrupt_signal = signal(2, MAIN.throw, KeyboardInterrupt)
loop_count = 0
while True:
try:
result = core.dispatch()
except IOError, ex:
loop_count += 1
if loop_count > 100:
raise
sys.stderr.write('Restarting gevent.core.dispatch() after an error [%s]: %s\n' % (loop_count, ex))
continue
if result>0:
return 'Hub.run() has finished because there are no events registered'
elif result<0:
return 'Hub.run() has finished because there was an error'
return result
def _wait_helper(ev, fd, evtype):
current, timeout_exc = ev.arg
if evtype & core.EV_TIMEOUT:
current.throw(timeout_exc)
else:
current.switch(ev)
def wait_reader(fileno, timeout=-1, timeout_exc=TimeoutError):
evt = core.read(fileno, _wait_helper, timeout, (getcurrent(), timeout_exc))
try:
returned_ev = get_hub().switch()
assert evt is returned_ev, (evt, returned_ev)
finally:
evt.cancel()
def wait_writer(fileno, timeout=-1, timeout_exc=TimeoutError):
evt = core.write(fileno, _wait_helper, timeout, (getcurrent(), timeout_exc))
try:
returned_ev = get_hub().switch()
assert evt is returned_ev, (evt, returned_ev)
finally:
evt.cancel()
class _SilentException:
pass
class Timeout(object):
"""Schedule an exception to raise in the current greenlet (TimeoutError by default).
Raise an exception in the block after timeout.
with Timeout(seconds[, exc]):
... code block ...
Assuming code block is yielding (i.e. gives up control to the hub),
an exception provided in `exc' argument will be raised
(TimeoutError if `exc' is omitted).
When exc is None, code block is interrupted silently.
"""
def __init__(self, seconds, exception=TimeoutError):
if exception is None:
exception = _SilentException()
self.exception = exception
if seconds is None:
self.timeout = None
else:
self.timeout = core.timer(seconds, getcurrent().throw, exception)
def cancel(self):
if self.timeout is not None:
self.timeout.cancel()
def __repr__(self):
if self.timeout is not None:
return repr(self.timeout)
else:
return '<fake timeout>'
def __enter__(self):
return self
def __exit__(self, typ, value, tb):
self.cancel()
if typ is _SilentException and value is self.exception:
return True
# use this? less prone to errors (what if func has timeout_value argument or func is with_timeout itself?)
# def with_timeout(seconds, func[, args[, kwds[, timeout_value]]]):
# see what other similar standard library functions accept as params (start_new_thread, start new process)
def with_timeout(seconds, func, *args, **kwds):
"""Wrap a call to some (yielding) function with a timeout; if the called
function fails to return before the timeout, cancel it and return a flag
value.
seconds
(int or float) seconds before timeout occurs
func
the callable to execute with a timeout; must be one of the functions
that implicitly or explicitly yields
\*args, \*\*kwds
(positional, keyword) arguments to pass to *func*
timeout_value=
value to return if timeout occurs (default raise ``TimeoutError``)
**Returns**:
Value returned by *func* if *func* returns before *seconds*, else
*timeout_value* if provided, else raise ``TimeoutError``
**Raises**:
Any exception raised by *func*, and ``TimeoutError`` if *func* times out
and no ``timeout_value`` has been provided.
**Example**::
data = with_timeout(30, httpc.get, 'http://www.google.com/', timeout_value="")
Here *data* is either the result of the ``get()`` call, or the empty string if
it took too long to return. Any exception raised by the ``get()`` call is
passed through to the caller.
"""
# Recognize a specific keyword argument, while also allowing pass-through
# of any other keyword arguments accepted by func. Use pop() so we don't
# pass timeout_value through to func().
has_timeout_value = "timeout_value" in kwds
timeout_value = kwds.pop("timeout_value", None)
error = TimeoutError()
timeout = Timeout(seconds, error)
try:
try:
return func(*args, **kwds)
except TimeoutError, ex:
if ex is error and has_timeout_value:
return timeout_value
raise
finally:
timeout.cancel()
_original_fork = os.fork
def fork():
result = _original_fork()
core.reinit()
return result
import sys import sys
def patch_os(): def patch_os():
from gevent import fork from gevent.greenlet import fork
import os import os
os.fork = fork os.fork = fork
def patch_time(): def patch_time():
from gevent import sleep from gevent.greenlet import sleep
_time = __import__('time') _time = __import__('time')
_time.sleep = sleep _time.sleep = sleep
......
...@@ -67,7 +67,7 @@ fails then there's no way to complete the task so the parent must fail as well; ...@@ -67,7 +67,7 @@ fails then there's no way to complete the task so the parent must fail as well;
>>> p = spawn(demofunc, 1, 0) >>> p = spawn(demofunc, 1, 0)
>>> _ = p.link_exception() >>> _ = p.link_exception()
>>> try: >>> try:
... gevent.sleep(1) ... greenlet.sleep(1)
... except LinkedFailed: ... except LinkedFailed:
... print 'LinkedFailed' ... print 'LinkedFailed'
LinkedFailed LinkedFailed
...@@ -76,8 +76,7 @@ One application of linking is `waitall' function: link to a bunch of coroutines ...@@ -76,8 +76,7 @@ One application of linking is `waitall' function: link to a bunch of coroutines
and wait for all them to complete. Such function is provided by this module. and wait for all them to complete. Such function is provided by this module.
""" """
import sys import sys
import gevent from gevent import coros, greenlet, core
from gevent import coros
__all__ = ['LinkedExited', __all__ = ['LinkedExited',
'LinkedFailed', 'LinkedFailed',
...@@ -124,12 +123,12 @@ class LinkedKilled(LinkedFailed): ...@@ -124,12 +123,12 @@ class LinkedKilled(LinkedFailed):
msg = """%r was killed with %s""" msg = """%r was killed with %s"""
def getLinkedFailed(name, typ, value=None, tb=None): def getLinkedFailed(name, typ, value=None, tb=None):
if issubclass(typ, gevent.GreenletExit): if issubclass(typ, greenlet.GreenletExit):
return LinkedKilled(name, typ, value, tb) return LinkedKilled(name, typ, value, tb)
return LinkedFailed(name, typ, value, tb) return LinkedFailed(name, typ, value, tb)
class ProcExit(gevent.GreenletExit): class ProcExit(greenlet.GreenletExit):
"""Raised when this proc is killed.""" """Raised when this proc is killed."""
...@@ -210,17 +209,12 @@ class decorate_send(object): ...@@ -210,17 +209,12 @@ class decorate_send(object):
self._event.send((self._tag, value)) self._event.send((self._tag, value))
def killall(procs, *throw_args, **kwargs): def killall(procs, *throw_args):
if not throw_args: if not throw_args:
throw_args = (ProcExit, ) throw_args = (ProcExit, )
wait = kwargs.pop('wait', False)
if kwargs:
raise TypeError('Invalid keyword argument for proc.killall(): %s' % ', '.join(kwargs.keys()))
for g in procs: for g in procs:
if not g.dead: if not g.dead:
gevent.timer(0, g.throw, *throw_args) core.timer(0, g.throw, *throw_args)
if wait and gevent.getcurrent() is not gevent.get_hub().greenlet:
gevent.sleep(0)
class NotUsed(object): class NotUsed(object):
...@@ -238,9 +232,9 @@ def spawn_greenlet(function, *args): ...@@ -238,9 +232,9 @@ def spawn_greenlet(function, *args):
The current greenlet won't be unscheduled. Keyword arguments aren't The current greenlet won't be unscheduled. Keyword arguments aren't
supported (limitation of greenlet), use spawn() to work around that. supported (limitation of greenlet), use spawn() to work around that.
""" """
g = gevent.Greenlet(function) g = greenlet.Greenlet(function)
g.parent = gevent.get_hub().greenlet g.parent = greenlet.get_hub().greenlet
gevent.timer(0, g.switch, *args) core.timer(0, g.switch, *args)
return g return g
...@@ -339,10 +333,10 @@ class Source(object): ...@@ -339,10 +333,10 @@ class Source(object):
if self.ready() and self._exc is not None: if self.ready() and self._exc is not None:
return return
if listener is None: if listener is None:
listener = gevent.getcurrent() listener = greenlet.getcurrent()
if link is None: if link is None:
link = self.getLink(listener) link = self.getLink(listener)
if self.ready() and listener is gevent.getcurrent(): if self.ready() and listener is greenlet.getcurrent():
link(self) link(self)
else: else:
self._value_links[listener] = link self._value_links[listener] = link
...@@ -354,10 +348,10 @@ class Source(object): ...@@ -354,10 +348,10 @@ class Source(object):
if self.value is not _NOT_USED and self._exc is None: if self.value is not _NOT_USED and self._exc is None:
return return
if listener is None: if listener is None:
listener = gevent.getcurrent() listener = greenlet.getcurrent()
if link is None: if link is None:
link = self.getLink(listener) link = self.getLink(listener)
if self.ready() and listener is gevent.getcurrent(): if self.ready() and listener is greenlet.getcurrent():
link(self) link(self)
else: else:
self._exception_links[listener] = link self._exception_links[listener] = link
...@@ -367,10 +361,10 @@ class Source(object): ...@@ -367,10 +361,10 @@ class Source(object):
def link(self, listener=None, link=None): def link(self, listener=None, link=None):
if listener is None: if listener is None:
listener = gevent.getcurrent() listener = greenlet.getcurrent()
if link is None: if link is None:
link = self.getLink(listener) link = self.getLink(listener)
if self.ready() and listener is gevent.getcurrent(): if self.ready() and listener is greenlet.getcurrent():
if self._exc is None: if self._exc is None:
link(self) link(self)
else: else:
...@@ -387,7 +381,7 @@ class Source(object): ...@@ -387,7 +381,7 @@ class Source(object):
def unlink(self, listener=None): def unlink(self, listener=None):
if listener is None: if listener is None:
listener = gevent.getcurrent() listener = greenlet.getcurrent()
self._value_links.pop(listener, None) self._value_links.pop(listener, None)
self._exception_links.pop(listener, None) self._exception_links.pop(listener, None)
...@@ -409,7 +403,7 @@ class Source(object): ...@@ -409,7 +403,7 @@ class Source(object):
self._start_send() self._start_send()
def _start_send(self): def _start_send(self):
gevent.timer(0, self._do_send, self._value_links.items(), self._value_links) core.timer(0, self._do_send, self._value_links.items(), self._value_links)
def send_exception(self, *throw_args): def send_exception(self, *throw_args):
assert not self.ready(), "%s has been fired already" % self assert not self.ready(), "%s has been fired already" % self
...@@ -418,7 +412,7 @@ class Source(object): ...@@ -418,7 +412,7 @@ class Source(object):
self._start_send_exception() self._start_send_exception()
def _start_send_exception(self): def _start_send_exception(self):
gevent.timer(0, self._do_send, self._exception_links.items(), self._exception_links) core.timer(0, self._do_send, self._exception_links.items(), self._exception_links)
def _do_send(self, links, consult): def _do_send(self, links, consult):
while links: while links:
...@@ -430,7 +424,7 @@ class Source(object): ...@@ -430,7 +424,7 @@ class Source(object):
finally: finally:
consult.pop(listener, None) consult.pop(listener, None)
except: except:
gevent.timer(0, self._do_send, links, consult) core.timer(0, self._do_send, links, consult)
raise raise
def wait(self, timeout=None, *throw_args): def wait(self, timeout=None, *throw_args):
...@@ -446,16 +440,16 @@ class Source(object): ...@@ -446,16 +440,16 @@ class Source(object):
if self._exc is None: if self._exc is None:
return self.value return self.value
else: else:
gevent.getcurrent().throw(*self._exc) greenlet.getcurrent().throw(*self._exc)
if timeout is not None: if timeout is not None:
timer = gevent.timeout(timeout, *throw_args) timer = greenlet.Timeout(timeout, *throw_args)
timer.__enter__() timer.__enter__()
if timeout==0: if timeout==0:
if timer.__exit__(None, None, None): if timer.__exit__(None, None, None):
return return
else: else:
try: try:
gevent.getcurrent().throw(timer.exception) greenlet.getcurrent().throw(timer.exception)
except: except:
if not timer.__exit__(*sys.exc_info()): if not timer.__exit__(*sys.exc_info()):
raise raise
...@@ -487,15 +481,15 @@ class Waiter(object): ...@@ -487,15 +481,15 @@ class Waiter(object):
"""Wake up the greenlet that is calling wait() currently (if there is one). """Wake up the greenlet that is calling wait() currently (if there is one).
Can only be called from get_hub().greenlet. Can only be called from get_hub().greenlet.
""" """
assert gevent.getcurrent() is gevent.get_hub().greenlet assert greenlet.getcurrent() is greenlet.get_hub().greenlet
if self.greenlet is not None: if self.greenlet is not None:
self.greenlet.switch(value) self.greenlet.switch(value)
def send_exception(self, *throw_args): def send_exception(self, *throw_args):
"""Make greenlet calling wait() wake up (if there is a wait()). """Make greenlet calling wait() wake up (if there is a wait()).
Can only be called from gevent.get_hub().greenlet. Can only be called from greenlet.get_hub().greenlet.
""" """
assert gevent.getcurrent() is gevent.get_hub().greenlet assert greenlet.getcurrent() is greenlet.get_hub().greenlet
if self.greenlet is not None: if self.greenlet is not None:
self.greenlet.throw(*throw_args) self.greenlet.throw(*throw_args)
...@@ -504,11 +498,11 @@ class Waiter(object): ...@@ -504,11 +498,11 @@ class Waiter(object):
into send() or raise exception passed into send_exception(). into send() or raise exception passed into send_exception().
""" """
assert self.greenlet is None assert self.greenlet is None
current = gevent.getcurrent() current = greenlet.getcurrent()
assert current is not gevent.get_hub().greenlet assert current is not greenlet.get_hub().greenlet
self.greenlet = current self.greenlet = current
try: try:
return gevent.get_hub().switch() return greenlet.get_hub().switch()
finally: finally:
self.greenlet = None self.greenlet = None
...@@ -598,9 +592,9 @@ class Proc(Source): ...@@ -598,9 +592,9 @@ class Proc(Source):
if not self.dead: if not self.dead:
if not throw_args: if not throw_args:
throw_args = (ProcExit, ) throw_args = (ProcExit, )
gevent.timer(0, self.greenlet.throw, *throw_args) core.timer(0, self.greenlet.throw, *throw_args)
if gevent.getcurrent() is not gevent.get_hub().greenlet: if greenlet.getcurrent() is not greenlet.get_hub().greenlet:
gevent.sleep(0) greenlet.sleep(0)
# QQQ maybe Proc should not inherit from Source (because its send() and send_exception() # QQQ maybe Proc should not inherit from Source (because its send() and send_exception()
# QQQ methods are for internal use only) # QQQ methods are for internal use only)
...@@ -693,7 +687,7 @@ class RunningProcSet(object): ...@@ -693,7 +687,7 @@ class RunningProcSet(object):
return len(self.procs) return len(self.procs)
def __contains__(self, item): def __contains__(self, item):
if isinstance(item, gevent.Greenlet): if isinstance(item, greenlet.Greenlet):
# special case for "getcurrent() in running_proc_set" to work # special case for "getcurrent() in running_proc_set" to work
for x in self.procs: for x in self.procs:
if x.greenlet == item: if x.greenlet == item:
...@@ -748,7 +742,7 @@ class Pool(object): ...@@ -748,7 +742,7 @@ class Pool(object):
""" """
# if reentering an empty pool, don't try to wait on a coroutine freeing # if reentering an empty pool, don't try to wait on a coroutine freeing
# itself -- instead, just execute in the current coroutine # itself -- instead, just execute in the current coroutine
if self.sem.locked() and gevent.getcurrent() in self.procs: if self.sem.locked() and greenlet.getcurrent() in self.procs:
p = spawn(func, *args, **kwargs) p = spawn(func, *args, **kwargs)
try: try:
p.wait() p.wait()
......
from __future__ import with_statement from __future__ import with_statement
from Queue import Full, Empty from Queue import Full, Empty
import gevent from gevent.greenlet import Timeout
from gevent import coros from gevent import coros
...@@ -45,7 +45,7 @@ class Queue(object): ...@@ -45,7 +45,7 @@ class Queue(object):
else: else:
if timeout < 0: if timeout < 0:
raise ValueError("'timeout' must be a positive number") raise ValueError("'timeout' must be a positive number")
with gevent.timeout(timeout, Full): with Timeout(timeout, Full):
# XXX even if timeout fires, item ends up in a queue anyway, because # XXX even if timeout fires, item ends up in a queue anyway, because
# Channel.send is not transactional # Channel.send is not transactional
return self.q.send(item) return self.q.send(item)
...@@ -80,7 +80,7 @@ class Queue(object): ...@@ -80,7 +80,7 @@ class Queue(object):
elif timeout < 0: elif timeout < 0:
raise ValueError("'timeout' must be a positive number") raise ValueError("'timeout' must be a positive number")
else: else:
with gevent.timeout(timeout, Empty): with Timeout(timeout, Empty):
return self.q.wait() return self.q.wait()
else: else:
if not self.q: if not self.q:
......
import gevent from gevent import core, greenlet
from gevent import core
def get_fileno(obj): def get_fileno(obj):
try: try:
...@@ -13,9 +12,9 @@ def get_fileno(obj): ...@@ -13,9 +12,9 @@ def get_fileno(obj):
def select(read_list, write_list, error_list, t=None): def select(read_list, write_list, error_list, t=None):
hub = gevent.get_hub() hub = greenlet.get_hub()
t = None t = None
current = gevent.getcurrent() current = greenlet.getcurrent()
assert hub.greenlet is not current, 'do not call blocking functions from the mainloop' assert hub.greenlet is not current, 'do not call blocking functions from the mainloop'
allevents = [] allevents = []
...@@ -33,11 +32,11 @@ def select(read_list, write_list, error_list, t=None): ...@@ -33,11 +32,11 @@ def select(read_list, write_list, error_list, t=None):
allevents.append(core.write(get_fileno(r), callback, arg=w)) allevents.append(core.write(get_fileno(r), callback, arg=w))
if t is not None: if t is not None:
t = gevent.timeout(t) t = greenlet.Timeout(t)
try: try:
try: try:
return hub.switch() result = hub.switch()
except gevent.TimeoutError: except greenlet.TimeoutError:
return [], [], [] return [], [], []
if hasattr(result, '__len__') and len(result)==3: if hasattr(result, '__len__') and len(result)==3:
return result return result
......
...@@ -18,15 +18,6 @@ ...@@ -18,15 +18,6 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # THE SOFTWARE.
from gevent import wait_reader, wait_writer, spawn
BUFFER_SIZE = 4096
import errno
import os
import time
from errno import EAGAIN
__all__ = ['GreenSocket', 'GreenFile', 'GreenPipe'] __all__ = ['GreenSocket', 'GreenFile', 'GreenPipe']
import _socket import _socket
...@@ -40,6 +31,15 @@ __socket__ = __import__('socket') ...@@ -40,6 +31,15 @@ __socket__ = __import__('socket')
_fileobject = __socket__._fileobject _fileobject = __socket__._fileobject
sslerror = __socket__.sslerror sslerror = __socket__.sslerror
import errno
import os
import time
from errno import EAGAIN
from gevent.greenlet import wait_reader, wait_writer, spawn
BUFFER_SIZE = 4096
try: try:
from OpenSSL import SSL from OpenSSL import SSL
except ImportError: except ImportError:
......
"""implements standard module 'thread' with greenlets""" """implements standard module 'thread' with greenlets"""
__thread = __import__('thread') __thread = __import__('thread')
from gevent import spawn, getcurrent, GreenletExit from gevent.greenlet import spawn, getcurrent, GreenletExit
from gevent.coros import Semaphore as LockType from gevent.coros import Semaphore as LockType
def get_ident(gr=None): def get_ident(gr=None):
......
...@@ -25,6 +25,7 @@ import os ...@@ -25,6 +25,7 @@ import os
import errno import errno
import unittest import unittest
import gevent import gevent
from gevent.greenlet import get_hub
disabled_marker = '-*-*-*-*-*- disabled -*-*-*-*-*-' disabled_marker = '-*-*-*-*-*- disabled -*-*-*-*-*-'
def exit_disabled(): def exit_disabled():
...@@ -38,6 +39,7 @@ class TestCase(unittest.TestCase): ...@@ -38,6 +39,7 @@ class TestCase(unittest.TestCase):
__timeout__ = 1 __timeout__ = 1
__switch_check__ = True __switch_check__ = True
_switch_count = None
def disable_switch_check(self): def disable_switch_check(self):
self._switch_count = None self._switch_count = None
...@@ -47,14 +49,16 @@ class TestCase(unittest.TestCase): ...@@ -47,14 +49,16 @@ class TestCase(unittest.TestCase):
gevent.sleep(0) # switch at least once to setup signal handlers gevent.sleep(0) # switch at least once to setup signal handlers
if hasattr(core, '_event_count'): if hasattr(core, '_event_count'):
self._event_count = (core._event_count(), core._event_count_active()) self._event_count = (core._event_count(), core._event_count_active())
self._switch_count = gevent.get_hub().switch_count if hasattr(get_hub(), 'switch_count'):
self._timer = gevent.timeout(self.__timeout__, RuntimeError('test is taking too long')) self._switch_count = get_hub().switch_count
self._timer = gevent.Timeout(self.__timeout__, RuntimeError('test is taking too long'))
def tearDown(self): def tearDown(self):
if hasattr(self, '_timer'): if hasattr(self, '_timer'):
self._timer.cancel() self._timer.cancel()
if self.__switch_check__ and self._switch_count is not None and gevent.get_hub().switch_count <= self._switch_count: if self.__switch_check__ and self._switch_count is not None and hasattr(get_hub(), 'switch_count') and get_hub().switch_count <= self._switch_count:
sys.stderr.write('WARNING: %s.%s did not switch\n' % (type(self).__name__, self._testMethodName)) name = getattr(self, '_testMethodName', '') # 2.4 does not have it
sys.stderr.write('WARNING: %s.%s did not switch\n' % (type(self).__name__, name))
from gevent import core from gevent import core
if hasattr(core, '_event_count'): if hasattr(core, '_event_count'):
event_count = (core._event_count(), core._event_count_active()) event_count = (core._event_count(), core._event_count_active())
...@@ -75,7 +79,7 @@ def find_command(command): ...@@ -75,7 +79,7 @@ def find_command(command):
main = unittest.main main = unittest.main
_original_Hub = gevent.Hub _original_Hub = gevent.greenlet.Hub
class CountingHub(_original_Hub): class CountingHub(_original_Hub):
...@@ -85,4 +89,4 @@ class CountingHub(_original_Hub): ...@@ -85,4 +89,4 @@ class CountingHub(_original_Hub):
self.switch_count += 1 self.switch_count += 1
return _original_Hub.switch(self) return _original_Hub.switch(self)
gevent.Hub = CountingHub gevent.greenlet.Hub = CountingHub
...@@ -24,6 +24,7 @@ import os.path ...@@ -24,6 +24,7 @@ import os.path
from greentest import TestCase, main from greentest import TestCase, main
import gevent import gevent
from gevent import greenlet
from gevent import socket from gevent import socket
...@@ -119,7 +120,7 @@ class TestApi(TestCase): ...@@ -119,7 +120,7 @@ class TestApi(TestCase):
try: try:
desc = socket.GreenSocket() desc = socket.GreenSocket()
desc.connect(('127.0.0.1', bound_port)) desc.connect(('127.0.0.1', bound_port))
gevent.wait_reader(desc.fileno(), timeout=0.1) greenlet.wait_reader(desc.fileno(), timeout=0.1)
except gevent.TimeoutError: except gevent.TimeoutError:
pass # test passed pass # test passed
else: else:
...@@ -138,7 +139,7 @@ class TestApi(TestCase): ...@@ -138,7 +139,7 @@ class TestApi(TestCase):
desc = socket.GreenSocket() desc = socket.GreenSocket()
desc.connect(('127.0.0.1', bound_port)) desc.connect(('127.0.0.1', bound_port))
try: try:
gevent.wait_reader(desc.fileno(), timeout=0.1) greenlet.wait_reader(desc.fileno(), timeout=0.1)
except gevent.TimeoutError: except gevent.TimeoutError:
assert False, "Timed out" assert False, "Timed out"
...@@ -175,7 +176,7 @@ class TestApi(TestCase): ...@@ -175,7 +176,7 @@ class TestApi(TestCase):
try: try:
# try and get some data off of this pipe # try and get some data off of this pipe
# but bail before any is sent # but bail before any is sent
gevent.timeout(0.01) gevent.Timeout(0.01)
_c = wrap_rfile.read(1) _c = wrap_rfile.read(1)
self.fail() self.fail()
except gevent.TimeoutError: except gevent.TimeoutError:
......
...@@ -87,7 +87,7 @@ class TestEvent(TestCase): ...@@ -87,7 +87,7 @@ class TestEvent(TestCase):
self.assertRaises(RuntimeError, evt.wait) self.assertRaises(RuntimeError, evt.wait)
evt.reset() evt.reset()
# shouldn't see the RuntimeError again # shouldn't see the RuntimeError again
gevent.timeout(0.001, gevent.TimeoutError('from test_double_exception')) gevent.Timeout(0.001, gevent.TimeoutError('from test_double_exception'))
self.assertRaises(gevent.TimeoutError, evt.wait) self.assertRaises(gevent.TimeoutError, evt.wait)
......
...@@ -72,7 +72,7 @@ class TestGreenIo(TestCase): ...@@ -72,7 +72,7 @@ class TestGreenIo(TestCase):
def test_del_closes_socket(self): def test_del_closes_socket(self):
timer = gevent.timeout(0.5) timer = gevent.Timeout(0.5)
def accept_once(listener): def accept_once(listener):
# delete/overwrite the original conn # delete/overwrite the original conn
# object, only keeping the file object around # object, only keeping the file object around
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
import greentest import greentest
import gevent import gevent
from gevent import core
DELAY = 0.1 DELAY = 0.1
...@@ -65,7 +66,7 @@ class TestTimers(greentest.TestCase): ...@@ -65,7 +66,7 @@ class TestTimers(greentest.TestCase):
def test_timer_fired(self): def test_timer_fired(self):
def func(): def func():
gevent.timer(0.1, self.lst.pop) core.timer(0.1, self.lst.pop)
gevent.sleep(0.2) gevent.sleep(0.2)
gevent.spawn(func) gevent.spawn(func)
......
...@@ -24,7 +24,8 @@ import sys ...@@ -24,7 +24,8 @@ import sys
import greentest import greentest
import weakref import weakref
import time import time
from gevent import sleep, timeout, TimeoutError, _SilentException from gevent import sleep, Timeout, TimeoutError
from gevent.greenlet import _SilentException
DELAY = 0.04 DELAY = 0.04
class Error(Exception): class Error(Exception):
...@@ -34,13 +35,13 @@ class Test(greentest.TestCase): ...@@ -34,13 +35,13 @@ class Test(greentest.TestCase):
def test_api(self): def test_api(self):
# Nothing happens if with-block finishes before the timeout expires # Nothing happens if with-block finishes before the timeout expires
with timeout(DELAY*2): with Timeout(DELAY*2):
sleep(DELAY) sleep(DELAY)
sleep(DELAY*2) # check if timer was actually cancelled sleep(DELAY*2) # check if timer was actually cancelled
# An exception will be raised if it's not # An exception will be raised if it's not
try: try:
with timeout(DELAY): with Timeout(DELAY):
sleep(DELAY*2) sleep(DELAY*2)
except TimeoutError: except TimeoutError:
pass pass
...@@ -49,14 +50,14 @@ class Test(greentest.TestCase): ...@@ -49,14 +50,14 @@ class Test(greentest.TestCase):
# You can customize the exception raised: # You can customize the exception raised:
try: try:
with timeout(DELAY, IOError("Operation takes way too long")): with Timeout(DELAY, IOError("Operation takes way too long")):
sleep(DELAY*2) sleep(DELAY*2)
except IOError, ex: except IOError, ex:
assert str(ex)=="Operation takes way too long", repr(ex) assert str(ex)=="Operation takes way too long", repr(ex)
# Providing classes instead of values should be possible too: # Providing classes instead of values should be possible too:
try: try:
with timeout(DELAY, ValueError): with Timeout(DELAY, ValueError):
sleep(DELAY*2) sleep(DELAY*2)
except ValueError: except ValueError:
pass pass
...@@ -65,7 +66,7 @@ class Test(greentest.TestCase): ...@@ -65,7 +66,7 @@ class Test(greentest.TestCase):
1/0 1/0
except: except:
try: try:
with timeout(DELAY, sys.exc_info()[0]): with Timeout(DELAY, sys.exc_info()[0]):
sleep(DELAY*2) sleep(DELAY*2)
raise AssertionError('should not get there') raise AssertionError('should not get there')
raise AssertionError('should not get there') raise AssertionError('should not get there')
...@@ -75,7 +76,7 @@ class Test(greentest.TestCase): ...@@ -75,7 +76,7 @@ class Test(greentest.TestCase):
raise AssertionError('should not get there') raise AssertionError('should not get there')
# It's possible to cancel the timer inside the block: # It's possible to cancel the timer inside the block:
with timeout(DELAY) as timer: with Timeout(DELAY) as timer:
timer.cancel() timer.cancel()
sleep(DELAY*2) sleep(DELAY*2)
...@@ -84,39 +85,40 @@ class Test(greentest.TestCase): ...@@ -84,39 +85,40 @@ class Test(greentest.TestCase):
# outside. # outside.
XDELAY=0.1 XDELAY=0.1
start = time.time() start = time.time()
with timeout(XDELAY, None): with Timeout(XDELAY, None):
sleep(XDELAY*2) sleep(XDELAY*2)
delta = (time.time()-start) delta = (time.time()-start)
assert delta<XDELAY*2, delta assert delta<XDELAY*2, delta
# passing None as seconds disables the timer # passing None as seconds disables the timer
with timeout(None): with Timeout(None):
sleep(DELAY) sleep(DELAY)
sleep(DELAY) sleep(DELAY)
def test_ref(self): def test_ref(self):
err = Error() err = Error()
err_ref = weakref.ref(err) err_ref = weakref.ref(err)
with timeout(DELAY*2, err): with Timeout(DELAY*2, err):
sleep(DELAY) sleep(DELAY)
del err del err
assert not err_ref(), repr(err_ref()) assert not err_ref(), repr(err_ref())
def test_nested_timeout(self): def test_nested_timeout(self):
with timeout(DELAY, None): with Timeout(DELAY, None):
with timeout(DELAY*2, None): with Timeout(DELAY*2, None):
sleep(DELAY*3) sleep(DELAY*3)
raise AssertionError('should not get there') raise AssertionError('should not get there')
with timeout(DELAY, _SilentException()): with Timeout(DELAY, _SilentException()):
with timeout(DELAY*2, _SilentException()): with Timeout(DELAY*2, _SilentException()):
sleep(DELAY*3) sleep(DELAY*3)
raise AssertionError('should not get there') raise AssertionError('should not get there')
# this case fails and there's no intent to fix it. # this case fails and there's no intent to fix it.
# just don't do it like that # just don't do it like that
#with timeout(DELAY, _SilentException): #with Timeout(DELAY, _SilentException):
# with timeout(DELAY*2, _SilentException): # with Timeout(DELAY*2, _SilentException):
# sleep(DELAY*3) # sleep(DELAY*3)
# assert False, 'should not get there' # assert False, 'should not get there'
......
...@@ -21,7 +21,7 @@ class TestQueue(TestCase): ...@@ -21,7 +21,7 @@ class TestQueue(TestCase):
def test_send_last(self): def test_send_last(self):
q = coros.Queue() q = coros.Queue()
def waiter(q): def waiter(q):
timer = gevent.timeout(0.1, gevent.TimeoutError) timer = gevent.Timeout(0.1, gevent.TimeoutError)
self.assertEquals(q.wait(), 'hi2') self.assertEquals(q.wait(), 'hi2')
timer.cancel() timer.cancel()
...@@ -90,7 +90,7 @@ class TestQueue(TestCase): ...@@ -90,7 +90,7 @@ class TestQueue(TestCase):
results = set() results = set()
def collect_pending_results(): def collect_pending_results():
for i, e in enumerate(evts): for i, e in enumerate(evts):
timer = gevent.timeout(0.001, gevent.TimeoutError) timer = gevent.Timeout(0.001, gevent.TimeoutError)
try: try:
x = e.wait() x = e.wait()
results.add(x) results.add(x)
...@@ -110,7 +110,7 @@ class TestQueue(TestCase): ...@@ -110,7 +110,7 @@ class TestQueue(TestCase):
q = coros.Queue() q = coros.Queue()
def do_receive(q, evt): def do_receive(q, evt):
gevent.timeout(0, RuntimeError()) gevent.Timeout(0, RuntimeError())
try: try:
result = q.wait() result = q.wait()
evt.send(result) evt.send(result)
...@@ -138,7 +138,7 @@ class TestQueue(TestCase): ...@@ -138,7 +138,7 @@ class TestQueue(TestCase):
def waiter(q, evt): def waiter(q, evt):
evt.send(q.wait()) evt.send(q.wait())
def do_receive(q, evt): def do_receive(q, evt):
gevent.timeout(0, RuntimeError()) gevent.Timeout(0, RuntimeError())
try: try:
result = q.wait() result = q.wait()
evt.send(result) evt.send(result)
...@@ -157,7 +157,7 @@ class TestQueue(TestCase): ...@@ -157,7 +157,7 @@ class TestQueue(TestCase):
def test_two_bogus_waiters(self): def test_two_bogus_waiters(self):
def do_receive(q, evt): def do_receive(q, evt):
gevent.timeout(0, RuntimeError()) gevent.Timeout(0, RuntimeError())
try: try:
result = q.wait() result = q.wait()
evt.send(result) evt.send(result)
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
import greentest import greentest
from gevent.coros import event from gevent.coros import event
from gevent import spawn, sleep, timeout, with_timeout from gevent import spawn, sleep, Timeout, with_timeout
from greentest import TestCase from greentest import TestCase
DELAY= 0.01 DELAY= 0.01
...@@ -50,7 +50,7 @@ class TestEvent(TestCase): ...@@ -50,7 +50,7 @@ class TestEvent(TestCase):
event2 = event() event2 = event()
spawn(event1.send, 'hello event1') spawn(event1.send, 'hello event1')
timeout(0, ValueError('interrupted')) Timeout(0, ValueError('interrupted'))
try: try:
result = event1.wait() result = event1.wait()
except ValueError: except ValueError:
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
import greentest import greentest
import time import time
import gevent import gevent
from gevent import core
from gevent import socket from gevent import socket
DELAY = 0.1 DELAY = 0.1
...@@ -37,7 +38,7 @@ class TestScheduleCall(greentest.TestCase): ...@@ -37,7 +38,7 @@ class TestScheduleCall(greentest.TestCase):
def test_global(self): def test_global(self):
lst = [1] lst = [1]
gevent.spawn(gevent.timer, DELAY, lst.pop) gevent.spawn(core.timer, DELAY, lst.pop)
gevent.sleep(DELAY*2) gevent.sleep(DELAY*2)
assert lst == [], lst assert lst == [], lst
...@@ -47,7 +48,7 @@ class TestCloseSocketWhilePolling(greentest.TestCase): ...@@ -47,7 +48,7 @@ class TestCloseSocketWhilePolling(greentest.TestCase):
def test(self): def test(self):
try: try:
sock = socket.socket() sock = socket.socket()
gevent.timer(0, sock.close) core.timer(0, sock.close)
sock.connect(('python.org', 81)) sock.connect(('python.org', 81))
except Exception: except Exception:
gevent.sleep(0) gevent.sleep(0)
...@@ -68,7 +69,7 @@ class TestExceptionInMainloop(greentest.TestCase): ...@@ -68,7 +69,7 @@ class TestExceptionInMainloop(greentest.TestCase):
def fail(): def fail():
1/0 1/0
gevent.timer(0, fail) core.timer(0, fail)
start = time.time() start = time.time()
gevent.sleep(DELAY) gevent.sleep(DELAY)
......
...@@ -95,7 +95,7 @@ class TestCoroutinePool(TestCase): ...@@ -95,7 +95,7 @@ class TestCoroutinePool(TestCase):
gevent.sleep(0) gevent.sleep(0)
self.assertEqual(pool.free_count(), 1) self.assertEqual(pool.free_count(), 1)
# shouldn't block when trying to get # shouldn't block when trying to get
t = gevent.timeout(0.1) t = gevent.Timeout(0.1)
try: try:
pool.execute(gevent.sleep, 1) pool.execute(gevent.sleep, 1)
finally: finally:
......
...@@ -164,7 +164,7 @@ class TestHttpd(TestCase): ...@@ -164,7 +164,7 @@ class TestHttpd(TestCase):
fd = sock.makeGreenFile() fd = sock.makeGreenFile()
fd.write('GET / HTTP/1.1\r\nHost: localhost\r\n\r\n') fd.write('GET / HTTP/1.1\r\nHost: localhost\r\n\r\n')
cancel = gevent.timeout(1, RuntimeError) cancel = gevent.Timeout(1, RuntimeError)
self.assertRaises(TypeError, fd.read, "This shouldn't work") self.assertRaises(TypeError, fd.read, "This shouldn't work")
cancel.cancel() cancel.cancel()
fd.close() fd.close()
...@@ -278,42 +278,6 @@ class TestHttpd(TestCase): ...@@ -278,42 +278,6 @@ class TestHttpd(TestCase):
chunklen = int(fd.readline(), 16) chunklen = int(fd.readline(), 16)
self.assert_(chunks > 1) self.assert_(chunks > 1)
def test_012_ssl_server(self):
def wsgi_app(environ, start_response):
start_response('200 OK', {})
return [environ['wsgi.input'].read()]
certificate_file = os.path.join(os.path.dirname(__file__), 'test_server.crt')
private_key_file = os.path.join(os.path.dirname(__file__), 'test_server.key')
sock = socket.ssl_listener(('', 4201), certificate_file, private_key_file)
g = gevent.spawn(wsgi.server, sock, wsgi_app)
try:
req = HTTPRequest("https://localhost:4201/foo", method="POST", data='abc')
f = urllib2.urlopen(req)
result = f.read()
self.assertEquals(result, 'abc')
finally:
gevent.kill(g)
def test_013_empty_return(self):
def wsgi_app(environ, start_response):
start_response("200 OK", [])
return [""]
certificate_file = os.path.join(os.path.dirname(__file__), 'test_server.crt')
private_key_file = os.path.join(os.path.dirname(__file__), 'test_server.key')
sock = socket.ssl_listener(('', 4202), certificate_file, private_key_file)
g = gevent.spawn(wsgi.server, sock, wsgi_app)
try:
req = HTTPRequest("https://localhost:4202/foo")
f = urllib2.urlopen(req)
result = f.read()
self.assertEquals(result, '')
finally:
gevent.kill(g)
def test_014_chunked_post(self): def test_014_chunked_post(self):
self.site.application = chunked_post self.site.application = chunked_post
sock = socket.connect_tcp(('127.0.0.1', 12346)) sock = socket.connect_tcp(('127.0.0.1', 12346))
...@@ -359,6 +323,46 @@ class TestHttpd(TestCase): ...@@ -359,6 +323,46 @@ class TestHttpd(TestCase):
self.assert_(headers['transfer-encoding'] == 'chunked') self.assert_(headers['transfer-encoding'] == 'chunked')
class TestHttps(TestCase):
mode = 'static'
def test_012_ssl_server(self):
def wsgi_app(environ, start_response):
start_response('200 OK', {})
return [environ['wsgi.input'].read()]
certificate_file = os.path.join(os.path.dirname(__file__), 'test_server.crt')
private_key_file = os.path.join(os.path.dirname(__file__), 'test_server.key')
sock = socket.ssl_listener(('', 4201), certificate_file, private_key_file)
g = gevent.spawn(wsgi.server, sock, wsgi_app)
try:
req = HTTPRequest("https://localhost:4201/foo", method="POST", data='abc')
f = urllib2.urlopen(req)
result = f.read()
self.assertEquals(result, 'abc')
finally:
gevent.kill(g)
def test_013_empty_return(self):
def wsgi_app(environ, start_response):
start_response("200 OK", [])
return [""]
certificate_file = os.path.join(os.path.dirname(__file__), 'test_server.crt')
private_key_file = os.path.join(os.path.dirname(__file__), 'test_server.key')
sock = socket.ssl_listener(('', 4202), certificate_file, private_key_file)
g = gevent.spawn(wsgi.server, sock, wsgi_app)
try:
req = HTTPRequest("https://localhost:4202/foo")
f = urllib2.urlopen(req)
result = f.read()
self.assertEquals(result, '')
finally:
gevent.kill(g)
class HTTPRequest(urllib2.Request): class HTTPRequest(urllib2.Request):
"""Hack urllib2.Request to support PUT and DELETE methods.""" """Hack urllib2.Request to support PUT and DELETE methods."""
......
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