PEP-8 fixes
This commit is contained in:
parent
e9486899e0
commit
203e629212
@ -5,12 +5,12 @@ import random
|
||||
from eventlet.support import six
|
||||
|
||||
|
||||
def measure_best(repeat, iters,
|
||||
common_setup='pass',
|
||||
def measure_best(repeat, iters,
|
||||
common_setup='pass',
|
||||
common_cleanup='pass',
|
||||
*funcs):
|
||||
funcs = list(funcs)
|
||||
results = dict([(f,[]) for f in funcs])
|
||||
results = dict([(f, []) for f in funcs])
|
||||
|
||||
for i in six.moves.range(repeat):
|
||||
random.shuffle(funcs)
|
||||
|
@ -19,6 +19,7 @@ if len(sys.argv) >= 2:
|
||||
|
||||
l = []
|
||||
|
||||
|
||||
def work(n):
|
||||
l.append(n)
|
||||
|
||||
@ -37,9 +38,9 @@ for timeout in timeouts:
|
||||
scheduled.append(t)
|
||||
|
||||
hub.prepare_timers()
|
||||
hub.fire_timers(time.time()+11)
|
||||
hub.fire_timers(time.time() + 11)
|
||||
hub.prepare_timers()
|
||||
|
||||
end = time.time()
|
||||
|
||||
print("Duration: %f" % (end-start,))
|
||||
print("Duration: %f" % (end - start,))
|
||||
|
@ -7,10 +7,10 @@ import benchmarks
|
||||
from eventlet.support import six
|
||||
|
||||
|
||||
BYTES=1000
|
||||
SIZE=1
|
||||
CONCURRENCY=50
|
||||
TRIES=5
|
||||
BYTES = 1000
|
||||
SIZE = 1
|
||||
CONCURRENCY = 50
|
||||
TRIES = 5
|
||||
|
||||
|
||||
def reader(sock):
|
||||
@ -25,7 +25,7 @@ def writer(addr, socket_impl):
|
||||
sock.connect(addr)
|
||||
sent = 0
|
||||
while sent < BYTES:
|
||||
d = 'xy' * (max(min(SIZE/2, BYTES-sent), 1))
|
||||
d = 'xy' * (max(min(SIZE / 2, BYTES - sent), 1))
|
||||
sock.sendall(d)
|
||||
sent += len(d)
|
||||
|
||||
@ -97,12 +97,11 @@ if __name__ == "__main__":
|
||||
parser.add_option('-t', '--tries', type='int', dest='tries',
|
||||
default=TRIES)
|
||||
|
||||
|
||||
opts, args = parser.parse_args()
|
||||
BYTES=opts.bytes
|
||||
SIZE=opts.size
|
||||
CONCURRENCY=opts.concurrency
|
||||
TRIES=opts.tries
|
||||
BYTES = opts.bytes
|
||||
SIZE = opts.size
|
||||
CONCURRENCY = opts.concurrency
|
||||
TRIES = opts.tries
|
||||
|
||||
funcs = [launch_green_threads]
|
||||
if opts.threading:
|
||||
@ -113,4 +112,4 @@ if __name__ == "__main__":
|
||||
print("green:", results[launch_green_threads])
|
||||
if opts.threading:
|
||||
print("threads:", results[launch_heavy_threads])
|
||||
print("%", (results[launch_green_threads]-results[launch_heavy_threads])/results[launch_heavy_threads] * 100)
|
||||
print("%", (results[launch_green_threads] - results[launch_heavy_threads]) / results[launch_heavy_threads] * 100)
|
||||
|
@ -10,13 +10,15 @@ def cleanup():
|
||||
|
||||
|
||||
iters = 10000
|
||||
best = benchmarks.measure_best(5, iters,
|
||||
best = benchmarks.measure_best(
|
||||
5, iters,
|
||||
'pass',
|
||||
cleanup,
|
||||
eventlet.sleep)
|
||||
print("eventlet.sleep (main)", best[eventlet.sleep])
|
||||
|
||||
gt = eventlet.spawn(benchmarks.measure_best,5, iters,
|
||||
gt = eventlet.spawn(
|
||||
benchmarks.measure_best, 5, iters,
|
||||
'pass',
|
||||
cleanup,
|
||||
eventlet.sleep)
|
||||
@ -40,7 +42,8 @@ def run_spawn_n_kw():
|
||||
eventlet.spawn_n(dummy, i=1)
|
||||
|
||||
|
||||
best = benchmarks.measure_best(5, iters,
|
||||
best = benchmarks.measure_best(
|
||||
5, iters,
|
||||
'pass',
|
||||
cleanup,
|
||||
run_spawn_n,
|
||||
@ -49,7 +52,7 @@ best = benchmarks.measure_best(5, iters,
|
||||
print("eventlet.spawn", best[run_spawn])
|
||||
print("eventlet.spawn_n", best[run_spawn_n])
|
||||
print("eventlet.spawn_n(**kw)", best[run_spawn_n_kw])
|
||||
print("%% %0.1f" % ((best[run_spawn]-best[run_spawn_n])/best[run_spawn_n] * 100))
|
||||
print("%% %0.1f" % ((best[run_spawn] - best[run_spawn_n]) / best[run_spawn_n] * 100))
|
||||
|
||||
pool = None
|
||||
|
||||
@ -71,7 +74,8 @@ def cleanup_pool():
|
||||
pool.waitall()
|
||||
|
||||
|
||||
best = benchmarks.measure_best(3, iters,
|
||||
best = benchmarks.measure_best(
|
||||
3, iters,
|
||||
setup,
|
||||
cleanup_pool,
|
||||
run_pool_spawn,
|
||||
@ -79,4 +83,4 @@ best = benchmarks.measure_best(3, iters,
|
||||
)
|
||||
print("eventlet.GreenPool.spawn", best[run_pool_spawn])
|
||||
print("eventlet.GreenPool.spawn_n", best[run_pool_spawn_n])
|
||||
print("%% %0.1f" % ((best[run_pool_spawn]-best[run_pool_spawn_n])/best[run_pool_spawn_n] * 100))
|
||||
print("%% %0.1f" % ((best[run_pool_spawn] - best[run_pool_spawn_n]) / best[run_pool_spawn_n] * 100))
|
||||
|
@ -15,46 +15,55 @@ DATA_DIR = 'plot_data'
|
||||
if not os.path.exists(DATA_DIR):
|
||||
os.makedirs(DATA_DIR)
|
||||
|
||||
|
||||
def write_result(filename, best):
|
||||
fd = open(os.path.join(DATA_DIR, filename), 'w')
|
||||
fd.write('YVALUE=%s' % best)
|
||||
fd.close()
|
||||
|
||||
|
||||
def cleanup():
|
||||
eventlet.sleep(0.2)
|
||||
|
||||
iters = 10000
|
||||
best = benchmarks.measure_best(5, iters,
|
||||
best = benchmarks.measure_best(
|
||||
5, iters,
|
||||
'pass',
|
||||
cleanup,
|
||||
eventlet.sleep)
|
||||
|
||||
write_result('eventlet.sleep_main', best[eventlet.sleep])
|
||||
|
||||
gt = eventlet.spawn(benchmarks.measure_best,5, iters,
|
||||
gt = eventlet.spawn(
|
||||
benchmarks.measure_best, 5, iters,
|
||||
'pass',
|
||||
cleanup,
|
||||
eventlet.sleep)
|
||||
best = gt.wait()
|
||||
write_result('eventlet.sleep_gt', best[eventlet.sleep])
|
||||
|
||||
|
||||
def dummy(i=None):
|
||||
return i
|
||||
|
||||
|
||||
def run_spawn():
|
||||
eventlet.spawn(dummy, 1)
|
||||
|
||||
|
||||
|
||||
def run_spawn_n():
|
||||
eventlet.spawn_n(dummy, 1)
|
||||
|
||||
|
||||
def run_spawn_n_kw():
|
||||
eventlet.spawn_n(dummy, i=1)
|
||||
|
||||
|
||||
best = benchmarks.measure_best(5, iters,
|
||||
best = benchmarks.measure_best(
|
||||
5, iters,
|
||||
'pass',
|
||||
cleanup,
|
||||
run_spawn_n,
|
||||
run_spawn_n,
|
||||
run_spawn,
|
||||
run_spawn_n_kw)
|
||||
write_result('eventlet.spawn', best[run_spawn])
|
||||
@ -62,24 +71,30 @@ write_result('eventlet.spawn_n', best[run_spawn_n])
|
||||
write_result('eventlet.spawn_n_kw', best[run_spawn_n_kw])
|
||||
|
||||
pool = None
|
||||
|
||||
|
||||
def setup():
|
||||
global pool
|
||||
pool = eventlet.GreenPool(iters)
|
||||
|
||||
|
||||
def run_pool_spawn():
|
||||
pool.spawn(dummy, 1)
|
||||
|
||||
|
||||
|
||||
def run_pool_spawn_n():
|
||||
pool.spawn_n(dummy, 1)
|
||||
|
||||
|
||||
|
||||
def cleanup_pool():
|
||||
pool.waitall()
|
||||
|
||||
|
||||
best = benchmarks.measure_best(3, iters,
|
||||
|
||||
best = benchmarks.measure_best(
|
||||
3, iters,
|
||||
setup,
|
||||
cleanup_pool,
|
||||
run_pool_spawn,
|
||||
run_pool_spawn,
|
||||
run_pool_spawn_n,
|
||||
)
|
||||
write_result('eventlet.GreenPool.spawn', best[run_pool_spawn])
|
||||
|
@ -18,25 +18,29 @@ __all__ = [
|
||||
'ssl_listener', 'tcp_listener', 'trampoline',
|
||||
'unspew', 'use_hub', 'with_timeout', 'timeout']
|
||||
|
||||
warnings.warn("eventlet.api is deprecated! Nearly everything in it has moved "
|
||||
warnings.warn(
|
||||
"eventlet.api is deprecated! Nearly everything in it has moved "
|
||||
"to the eventlet module.", DeprecationWarning, stacklevel=2)
|
||||
|
||||
|
||||
def get_hub(*a, **kw):
|
||||
warnings.warn("eventlet.api.get_hub has moved to eventlet.hubs.get_hub",
|
||||
warnings.warn(
|
||||
"eventlet.api.get_hub has moved to eventlet.hubs.get_hub",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
return hubs.get_hub(*a, **kw)
|
||||
|
||||
|
||||
def get_default_hub(*a, **kw):
|
||||
warnings.warn("eventlet.api.get_default_hub has moved to"
|
||||
warnings.warn(
|
||||
"eventlet.api.get_default_hub has moved to"
|
||||
" eventlet.hubs.get_default_hub",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
return hubs.get_default_hub(*a, **kw)
|
||||
|
||||
|
||||
def use_hub(*a, **kw):
|
||||
warnings.warn("eventlet.api.use_hub has moved to eventlet.hubs.use_hub",
|
||||
warnings.warn(
|
||||
"eventlet.api.use_hub has moved to eventlet.hubs.use_hub",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
return hubs.use_hub(*a, **kw)
|
||||
|
||||
@ -55,7 +59,8 @@ def tcp_listener(address, backlog=50):
|
||||
socket object on which one should call ``accept()`` to accept a connection
|
||||
on the newly bound socket.
|
||||
"""
|
||||
warnings.warn("""eventlet.api.tcp_listener is deprecated. Please use eventlet.listen instead.""",
|
||||
warnings.warn(
|
||||
"""eventlet.api.tcp_listener is deprecated. Please use eventlet.listen instead.""",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
|
||||
from eventlet import greenio, util
|
||||
@ -74,8 +79,9 @@ def ssl_listener(address, certificate, private_key):
|
||||
Returns a socket object on which one should call ``accept()`` to
|
||||
accept a connection on the newly bound socket.
|
||||
"""
|
||||
warnings.warn("""eventlet.api.ssl_listener is deprecated. Please use eventlet.wrap_ssl(eventlet.listen()) instead.""",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
warnings.warn("""eventlet.api.ssl_listener is deprecated. Please use eventlet.wrap_ssl(eventlet.listen(
|
||||
)) instead.""",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
from eventlet import util
|
||||
import socket
|
||||
|
||||
@ -90,7 +96,8 @@ def connect_tcp(address, localaddr=None):
|
||||
Create a TCP connection to address ``(host, port)`` and return the socket.
|
||||
Optionally, bind to localaddr ``(host, port)`` first.
|
||||
"""
|
||||
warnings.warn("""eventlet.api.connect_tcp is deprecated. Please use eventlet.connect instead.""",
|
||||
warnings.warn(
|
||||
"""eventlet.api.connect_tcp is deprecated. Please use eventlet.connect instead.""",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
|
||||
from eventlet import greenio, util
|
||||
|
@ -4,6 +4,7 @@ from eventlet import greenthread
|
||||
|
||||
__all__ = ['get_ident', 'local']
|
||||
|
||||
|
||||
def get_ident():
|
||||
""" Returns ``id()`` of current greenlet. Useful for debugging."""
|
||||
return id(greenthread.getcurrent())
|
||||
@ -13,14 +14,16 @@ def get_ident():
|
||||
# arguments in a local variable without calling __init__ directly
|
||||
class _localbase(object):
|
||||
__slots__ = '_local__args', '_local__greens'
|
||||
|
||||
def __new__(cls, *args, **kw):
|
||||
self = object.__new__(cls)
|
||||
object.__setattr__(self, '_local__args', (args, kw))
|
||||
object.__setattr__(self, '_local__greens', weakref.WeakKeyDictionary())
|
||||
if (args or kw) and (cls.__init__ is object.__init__):
|
||||
raise TypeError("Initialization arguments are not supported")
|
||||
return self
|
||||
|
||||
return self
|
||||
|
||||
|
||||
def _patch(thrl):
|
||||
greens = object.__getattribute__(thrl, '_local__greens')
|
||||
# until we can store the localdict on greenlets themselves,
|
||||
@ -34,7 +37,7 @@ def _patch(thrl):
|
||||
args, kw = object.__getattribute__(thrl, '_local__args')
|
||||
thrl.__init__(*args, **kw)
|
||||
object.__setattr__(thrl, '__dict__', greens[cur])
|
||||
|
||||
|
||||
|
||||
class local(_localbase):
|
||||
def __getattribute__(self, attr):
|
||||
|
@ -20,34 +20,38 @@ NOT_USED = NOT_USED()
|
||||
|
||||
def Event(*a, **kw):
|
||||
warnings.warn("The Event class has been moved to the event module! "
|
||||
"Please construct event.Event objects instead.",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
"Please construct event.Event objects instead.",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
return _event.Event(*a, **kw)
|
||||
|
||||
|
||||
def event(*a, **kw):
|
||||
warnings.warn("The event class has been capitalized and moved! Please "
|
||||
warnings.warn(
|
||||
"The event class has been capitalized and moved! Please "
|
||||
"construct event.Event objects instead.",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
return _event.Event(*a, **kw)
|
||||
|
||||
|
||||
def Semaphore(count):
|
||||
warnings.warn("The Semaphore class has moved! Please "
|
||||
warnings.warn(
|
||||
"The Semaphore class has moved! Please "
|
||||
"use semaphore.Semaphore instead.",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
return semaphoremod.Semaphore(count)
|
||||
|
||||
|
||||
def BoundedSemaphore(count):
|
||||
warnings.warn("The BoundedSemaphore class has moved! Please "
|
||||
warnings.warn(
|
||||
"The BoundedSemaphore class has moved! Please "
|
||||
"use semaphore.BoundedSemaphore instead.",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
return semaphoremod.BoundedSemaphore(count)
|
||||
|
||||
|
||||
def semaphore(count=0, limit=None):
|
||||
warnings.warn("coros.semaphore is deprecated. Please use either "
|
||||
warnings.warn(
|
||||
"coros.semaphore is deprecated. Please use either "
|
||||
"semaphore.Semaphore or semaphore.BoundedSemaphore instead.",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
if limit is None:
|
||||
@ -74,6 +78,7 @@ class metaphore(object):
|
||||
A decrementing
|
||||
B decrementing
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.counter = 0
|
||||
self.event = _event.Event()
|
||||
@ -126,13 +131,15 @@ def execute(func, *args, **kw):
|
||||
>>> evt.wait()
|
||||
('foo', 1)
|
||||
"""
|
||||
warnings.warn("Coros.execute is deprecated. Please use eventlet.spawn "
|
||||
warnings.warn(
|
||||
"Coros.execute is deprecated. Please use eventlet.spawn "
|
||||
"instead.", DeprecationWarning, stacklevel=2)
|
||||
return greenthread.spawn(func, *args, **kw)
|
||||
|
||||
|
||||
def CoroutinePool(*args, **kwargs):
|
||||
warnings.warn("CoroutinePool is deprecated. Please use "
|
||||
warnings.warn(
|
||||
"CoroutinePool is deprecated. Please use "
|
||||
"eventlet.GreenPool instead.", DeprecationWarning, stacklevel=2)
|
||||
from eventlet.pool import Pool
|
||||
return Pool(*args, **kwargs)
|
||||
@ -141,14 +148,15 @@ def CoroutinePool(*args, **kwargs):
|
||||
class Queue(object):
|
||||
|
||||
def __init__(self):
|
||||
warnings.warn("coros.Queue is deprecated. Please use "
|
||||
warnings.warn(
|
||||
"coros.Queue is deprecated. Please use "
|
||||
"eventlet.queue.Queue instead.",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
self.items = collections.deque()
|
||||
self._waiters = set()
|
||||
|
||||
def __nonzero__(self):
|
||||
return len(self.items)>0
|
||||
return len(self.items) > 0
|
||||
|
||||
__bool__ = __nonzero__
|
||||
|
||||
@ -215,7 +223,8 @@ class Queue(object):
|
||||
class Channel(object):
|
||||
|
||||
def __init__(self, max_size=0):
|
||||
warnings.warn("coros.Channel is deprecated. Please use "
|
||||
warnings.warn(
|
||||
"coros.Channel is deprecated. Please use "
|
||||
"eventlet.queue.Queue(0) instead.",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
self.max_size = max_size
|
||||
@ -224,7 +233,7 @@ class Channel(object):
|
||||
self._senders = set()
|
||||
|
||||
def __nonzero__(self):
|
||||
return len(self.items)>0
|
||||
return len(self.items) > 0
|
||||
|
||||
__bool__ = __nonzero__
|
||||
|
||||
|
@ -268,6 +268,7 @@ class TpooledConnectionPool(BaseConnectionPool):
|
||||
"""A pool which gives out :class:`~eventlet.tpool.Proxy`-based database
|
||||
connections.
|
||||
"""
|
||||
|
||||
def create(self):
|
||||
now = time.time()
|
||||
return now, now, self.connect(
|
||||
@ -287,6 +288,7 @@ class TpooledConnectionPool(BaseConnectionPool):
|
||||
class RawConnectionPool(BaseConnectionPool):
|
||||
"""A pool which gives out plain database connections.
|
||||
"""
|
||||
|
||||
def create(self):
|
||||
now = time.time()
|
||||
return now, now, self.connect(
|
||||
@ -316,38 +318,71 @@ class GenericConnectionWrapper(object):
|
||||
# * def __getattr__(self, name): if name in (...): return getattr(self._base, name)
|
||||
# * other?
|
||||
def __enter__(self): return self._base.__enter__()
|
||||
|
||||
def __exit__(self, exc, value, tb): return self._base.__exit__(exc, value, tb)
|
||||
|
||||
def __repr__(self): return self._base.__repr__()
|
||||
|
||||
def affected_rows(self): return self._base.affected_rows()
|
||||
|
||||
def autocommit(self, *args, **kwargs): return self._base.autocommit(*args, **kwargs)
|
||||
|
||||
def begin(self): return self._base.begin()
|
||||
|
||||
def change_user(self, *args, **kwargs): return self._base.change_user(*args, **kwargs)
|
||||
|
||||
def character_set_name(self, *args, **kwargs): return self._base.character_set_name(*args, **kwargs)
|
||||
|
||||
def close(self, *args, **kwargs): return self._base.close(*args, **kwargs)
|
||||
|
||||
def commit(self, *args, **kwargs): return self._base.commit(*args, **kwargs)
|
||||
|
||||
def cursor(self, *args, **kwargs): return self._base.cursor(*args, **kwargs)
|
||||
|
||||
def dump_debug_info(self, *args, **kwargs): return self._base.dump_debug_info(*args, **kwargs)
|
||||
|
||||
def errno(self, *args, **kwargs): return self._base.errno(*args, **kwargs)
|
||||
|
||||
def error(self, *args, **kwargs): return self._base.error(*args, **kwargs)
|
||||
|
||||
def errorhandler(self, *args, **kwargs): return self._base.errorhandler(*args, **kwargs)
|
||||
|
||||
def insert_id(self, *args, **kwargs): return self._base.insert_id(*args, **kwargs)
|
||||
|
||||
def literal(self, *args, **kwargs): return self._base.literal(*args, **kwargs)
|
||||
|
||||
def set_character_set(self, *args, **kwargs): return self._base.set_character_set(*args, **kwargs)
|
||||
|
||||
def set_sql_mode(self, *args, **kwargs): return self._base.set_sql_mode(*args, **kwargs)
|
||||
|
||||
def show_warnings(self): return self._base.show_warnings()
|
||||
|
||||
def warning_count(self): return self._base.warning_count()
|
||||
|
||||
def ping(self, *args, **kwargs): return self._base.ping(*args, **kwargs)
|
||||
|
||||
def query(self, *args, **kwargs): return self._base.query(*args, **kwargs)
|
||||
|
||||
def rollback(self, *args, **kwargs): return self._base.rollback(*args, **kwargs)
|
||||
|
||||
def select_db(self, *args, **kwargs): return self._base.select_db(*args, **kwargs)
|
||||
|
||||
def set_server_option(self, *args, **kwargs): return self._base.set_server_option(*args, **kwargs)
|
||||
|
||||
def server_capabilities(self, *args, **kwargs): return self._base.server_capabilities(*args, **kwargs)
|
||||
|
||||
def shutdown(self, *args, **kwargs): return self._base.shutdown(*args, **kwargs)
|
||||
|
||||
def sqlstate(self, *args, **kwargs): return self._base.sqlstate(*args, **kwargs)
|
||||
|
||||
def stat(self, *args, **kwargs): return self._base.stat(*args, **kwargs)
|
||||
|
||||
def store_result(self, *args, **kwargs): return self._base.store_result(*args, **kwargs)
|
||||
|
||||
def string_literal(self, *args, **kwargs): return self._base.string_literal(*args, **kwargs)
|
||||
|
||||
def thread_id(self, *args, **kwargs): return self._base.thread_id(*args, **kwargs)
|
||||
|
||||
def use_result(self, *args, **kwargs): return self._base.use_result(*args, **kwargs)
|
||||
|
||||
|
||||
@ -357,6 +392,7 @@ class PooledConnectionWrapper(GenericConnectionWrapper):
|
||||
- ``bool(conn)`` returns a reasonable value
|
||||
- returns itself to the pool if it gets garbage collected
|
||||
"""
|
||||
|
||||
def __init__(self, baseconn, pool):
|
||||
super(PooledConnectionWrapper, self).__init__(baseconn)
|
||||
self._pool = pool
|
||||
@ -385,7 +421,7 @@ class PooledConnectionWrapper(GenericConnectionWrapper):
|
||||
def __del__(self):
|
||||
return # this causes some issues if __del__ is called in the
|
||||
# main coroutine, so for now this is disabled
|
||||
#self.close()
|
||||
# self.close()
|
||||
|
||||
|
||||
class DatabaseConnector(object):
|
||||
@ -393,6 +429,7 @@ class DatabaseConnector(object):
|
||||
This is an object which will maintain a collection of database
|
||||
connection pools on a per-host basis.
|
||||
"""
|
||||
|
||||
def __init__(self, module, credentials,
|
||||
conn_pool=None, *args, **kwargs):
|
||||
"""constructor
|
||||
@ -408,7 +445,8 @@ class DatabaseConnector(object):
|
||||
self._module = module
|
||||
self._args = args
|
||||
self._kwargs = kwargs
|
||||
self._credentials = credentials # this is a map of hostname to username/password
|
||||
# this is a map of hostname to username/password
|
||||
self._credentials = credentials
|
||||
self._databases = {}
|
||||
|
||||
def credentials_for(self, host):
|
||||
|
@ -40,6 +40,7 @@ class Event(object):
|
||||
"""
|
||||
_result = None
|
||||
_exc = None
|
||||
|
||||
def __init__(self):
|
||||
self._waiters = set()
|
||||
self.reset()
|
||||
|
@ -4,15 +4,16 @@ from eventlet.green import SimpleHTTPServer
|
||||
from eventlet.green import urllib
|
||||
from eventlet.green import select
|
||||
|
||||
test = None # bind prior to patcher.inject to silence pyflakes warning below
|
||||
patcher.inject('CGIHTTPServer',
|
||||
test = None # bind prior to patcher.inject to silence pyflakes warning below
|
||||
patcher.inject(
|
||||
'CGIHTTPServer',
|
||||
globals(),
|
||||
('BaseHTTPServer', BaseHTTPServer),
|
||||
('SimpleHTTPServer', SimpleHTTPServer),
|
||||
('urllib', urllib),
|
||||
('select', select))
|
||||
('urllib', urllib),
|
||||
('select', select))
|
||||
|
||||
del patcher
|
||||
|
||||
if __name__ == '__main__':
|
||||
test() # pyflakes false alarm here unless test = None above
|
||||
test() # pyflakes false alarm here unless test = None above
|
||||
|
@ -5,9 +5,11 @@ from eventlet import greenio
|
||||
from eventlet.hubs import trampoline
|
||||
import socket
|
||||
|
||||
|
||||
class GreenConnection(greenio.GreenSocket):
|
||||
""" Nonblocking wrapper for SSL.Connection objects.
|
||||
"""
|
||||
|
||||
def __init__(self, ctx, sock=None):
|
||||
if sock is not None:
|
||||
fd = orig_SSL.Connection(ctx, sock)
|
||||
@ -16,10 +18,10 @@ class GreenConnection(greenio.GreenSocket):
|
||||
# this is used in the inherited accept() method
|
||||
fd = ctx
|
||||
super(ConnectionType, self).__init__(fd)
|
||||
|
||||
|
||||
def do_handshake(self):
|
||||
""" Perform an SSL handshake (usually called after renegotiate or one of
|
||||
set_accept_state or set_accept_state). This can raise the same exceptions as
|
||||
""" Perform an SSL handshake (usually called after renegotiate or one of
|
||||
set_accept_state or set_accept_state). This can raise the same exceptions as
|
||||
send and recv. """
|
||||
if self.act_non_blocking:
|
||||
return self.fd.do_handshake()
|
||||
@ -27,24 +29,24 @@ class GreenConnection(greenio.GreenSocket):
|
||||
try:
|
||||
return self.fd.do_handshake()
|
||||
except WantReadError:
|
||||
trampoline(self.fd.fileno(),
|
||||
read=True,
|
||||
timeout=self.gettimeout(),
|
||||
trampoline(self.fd.fileno(),
|
||||
read=True,
|
||||
timeout=self.gettimeout(),
|
||||
timeout_exc=socket.timeout)
|
||||
except WantWriteError:
|
||||
trampoline(self.fd.fileno(),
|
||||
write=True,
|
||||
timeout=self.gettimeout(),
|
||||
trampoline(self.fd.fileno(),
|
||||
write=True,
|
||||
timeout=self.gettimeout(),
|
||||
timeout_exc=socket.timeout)
|
||||
|
||||
|
||||
def dup(self):
|
||||
raise NotImplementedError("Dup not supported on SSL sockets")
|
||||
|
||||
|
||||
def makefile(self, mode='r', bufsize=-1):
|
||||
raise NotImplementedError("Makefile not supported on SSL sockets")
|
||||
|
||||
raise NotImplementedError("Makefile not supported on SSL sockets")
|
||||
|
||||
def read(self, size):
|
||||
"""Works like a blocking call to SSL_read(), whose behavior is
|
||||
"""Works like a blocking call to SSL_read(), whose behavior is
|
||||
described here: http://www.openssl.org/docs/ssl/SSL_read.html"""
|
||||
if self.act_non_blocking:
|
||||
return self.fd.read(size)
|
||||
@ -52,44 +54,44 @@ class GreenConnection(greenio.GreenSocket):
|
||||
try:
|
||||
return self.fd.read(size)
|
||||
except WantReadError:
|
||||
trampoline(self.fd.fileno(),
|
||||
read=True,
|
||||
timeout=self.gettimeout(),
|
||||
trampoline(self.fd.fileno(),
|
||||
read=True,
|
||||
timeout=self.gettimeout(),
|
||||
timeout_exc=socket.timeout)
|
||||
except WantWriteError:
|
||||
trampoline(self.fd.fileno(),
|
||||
write=True,
|
||||
timeout=self.gettimeout(),
|
||||
trampoline(self.fd.fileno(),
|
||||
write=True,
|
||||
timeout=self.gettimeout(),
|
||||
timeout_exc=socket.timeout)
|
||||
except SysCallError as e:
|
||||
if get_errno(e) == -1 or get_errno(e) > 0:
|
||||
return ''
|
||||
|
||||
|
||||
recv = read
|
||||
|
||||
|
||||
def write(self, data):
|
||||
"""Works like a blocking call to SSL_write(), whose behavior is
|
||||
"""Works like a blocking call to SSL_write(), whose behavior is
|
||||
described here: http://www.openssl.org/docs/ssl/SSL_write.html"""
|
||||
if not data:
|
||||
return 0 # calling SSL_write() with 0 bytes to be sent is undefined
|
||||
return 0 # calling SSL_write() with 0 bytes to be sent is undefined
|
||||
if self.act_non_blocking:
|
||||
return self.fd.write(data)
|
||||
while True:
|
||||
try:
|
||||
return self.fd.write(data)
|
||||
except WantReadError:
|
||||
trampoline(self.fd.fileno(),
|
||||
read=True,
|
||||
timeout=self.gettimeout(),
|
||||
trampoline(self.fd.fileno(),
|
||||
read=True,
|
||||
timeout=self.gettimeout(),
|
||||
timeout_exc=socket.timeout)
|
||||
except WantWriteError:
|
||||
trampoline(self.fd.fileno(),
|
||||
write=True,
|
||||
timeout=self.gettimeout(),
|
||||
trampoline(self.fd.fileno(),
|
||||
write=True,
|
||||
timeout=self.gettimeout(),
|
||||
timeout_exc=socket.timeout)
|
||||
|
||||
|
||||
send = write
|
||||
|
||||
|
||||
def sendall(self, data):
|
||||
"""Send "all" data on the connection. This calls send() repeatedly until
|
||||
all data is sent. If an error occurs, it's impossible to tell how much data
|
||||
@ -99,7 +101,7 @@ class GreenConnection(greenio.GreenSocket):
|
||||
tail = self.send(data)
|
||||
while tail < len(data):
|
||||
tail += self.send(data[tail:])
|
||||
|
||||
|
||||
def shutdown(self):
|
||||
if self.act_non_blocking:
|
||||
return self.fd.shutdown()
|
||||
@ -107,14 +109,14 @@ class GreenConnection(greenio.GreenSocket):
|
||||
try:
|
||||
return self.fd.shutdown()
|
||||
except WantReadError:
|
||||
trampoline(self.fd.fileno(),
|
||||
read=True,
|
||||
timeout=self.gettimeout(),
|
||||
trampoline(self.fd.fileno(),
|
||||
read=True,
|
||||
timeout=self.gettimeout(),
|
||||
timeout_exc=socket.timeout)
|
||||
except WantWriteError:
|
||||
trampoline(self.fd.fileno(),
|
||||
write=True,
|
||||
timeout=self.gettimeout(),
|
||||
trampoline(self.fd.fileno(),
|
||||
write=True,
|
||||
timeout=self.gettimeout(),
|
||||
timeout_exc=socket.timeout)
|
||||
|
||||
Connection = ConnectionType = GreenConnection
|
||||
|
@ -1,2 +1,5 @@
|
||||
import rand, crypto, SSL, tsafe
|
||||
from version import __version__
|
||||
import rand
|
||||
import crypto
|
||||
import SSL
|
||||
import tsafe
|
||||
from version import __version__
|
||||
|
@ -1 +1 @@
|
||||
from OpenSSL.crypto import *
|
||||
from OpenSSL.crypto import *
|
||||
|
@ -1 +1 @@
|
||||
from OpenSSL.rand import *
|
||||
from OpenSSL.rand import *
|
||||
|
@ -1 +1 @@
|
||||
from OpenSSL.tsafe import *
|
||||
from OpenSSL.tsafe import *
|
||||
|
@ -1 +1 @@
|
||||
from OpenSSL.version import __version__, __doc__
|
||||
from OpenSSL.version import __version__, __doc__
|
||||
|
@ -6,23 +6,27 @@ __patched__ = ['LifoQueue', 'PriorityQueue', 'Queue']
|
||||
|
||||
# these classes exist to paper over the major operational difference between
|
||||
# eventlet.queue.Queue and the stdlib equivalents
|
||||
|
||||
|
||||
class Queue(queue.Queue):
|
||||
def __init__(self, maxsize=0):
|
||||
if maxsize == 0:
|
||||
maxsize = None
|
||||
super(Queue, self).__init__(maxsize)
|
||||
|
||||
|
||||
|
||||
class PriorityQueue(queue.PriorityQueue):
|
||||
def __init__(self, maxsize=0):
|
||||
if maxsize == 0:
|
||||
maxsize = None
|
||||
super(PriorityQueue, self).__init__(maxsize)
|
||||
|
||||
|
||||
|
||||
class LifoQueue(queue.LifoQueue):
|
||||
def __init__(self, maxsize=0):
|
||||
if maxsize == 0:
|
||||
maxsize = None
|
||||
super(LifoQueue, self).__init__(maxsize)
|
||||
|
||||
|
||||
Empty = queue.Empty
|
||||
Full = queue.Full
|
||||
|
@ -2,12 +2,13 @@ from eventlet import patcher
|
||||
from eventlet.green import BaseHTTPServer
|
||||
from eventlet.green import urllib
|
||||
|
||||
patcher.inject('SimpleHTTPServer',
|
||||
patcher.inject(
|
||||
'SimpleHTTPServer',
|
||||
globals(),
|
||||
('BaseHTTPServer', BaseHTTPServer),
|
||||
('urllib', urllib))
|
||||
('urllib', urllib))
|
||||
|
||||
del patcher
|
||||
|
||||
if __name__ == '__main__':
|
||||
test()
|
||||
test()
|
||||
|
@ -1,11 +1,11 @@
|
||||
__socket = __import__('socket')
|
||||
|
||||
__all__ = __socket.__all__
|
||||
__all__ = __socket.__all__
|
||||
__patched__ = ['fromfd', 'socketpair', 'ssl', 'socket']
|
||||
|
||||
from eventlet.patcher import slurp_properties
|
||||
slurp_properties(__socket, globals(),
|
||||
ignore=__patched__, srckeys=dir(__socket))
|
||||
ignore=__patched__, srckeys=dir(__socket))
|
||||
|
||||
os = __import__('os')
|
||||
import sys
|
||||
@ -18,6 +18,7 @@ from eventlet.greenio import _fileobject
|
||||
|
||||
try:
|
||||
__original_fromfd__ = __socket.fromfd
|
||||
|
||||
def fromfd(*args):
|
||||
return socket(__original_fromfd__(*args))
|
||||
except AttributeError:
|
||||
@ -25,6 +26,7 @@ except AttributeError:
|
||||
|
||||
try:
|
||||
__original_socketpair__ = __socket.socketpair
|
||||
|
||||
def socketpair(*args):
|
||||
one, two = __original_socketpair__(*args)
|
||||
return socket(one), socket(two)
|
||||
@ -32,7 +34,6 @@ except AttributeError:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
def _convert_to_sslerror(ex):
|
||||
""" Transliterates SSL.SysCallErrors to socket.sslerrors"""
|
||||
return sslerror((ex.args[0], ex.args[1]))
|
||||
@ -41,6 +42,7 @@ def _convert_to_sslerror(ex):
|
||||
class GreenSSLObject(object):
|
||||
""" Wrapper object around the SSLObjects returned by socket.ssl, which have a
|
||||
slightly different interface from SSL.Connection objects. """
|
||||
|
||||
def __init__(self, green_ssl_obj):
|
||||
""" Should only be called by a 'green' socket.ssl """
|
||||
self.connection = green_ssl_obj
|
||||
|
@ -2,9 +2,10 @@ from eventlet import patcher
|
||||
from eventlet.green import asyncore
|
||||
from eventlet.green import socket
|
||||
|
||||
patcher.inject('asynchat',
|
||||
patcher.inject(
|
||||
'asynchat',
|
||||
globals(),
|
||||
('asyncore', asyncore),
|
||||
('socket', socket))
|
||||
|
||||
del patcher
|
||||
del patcher
|
||||
|
@ -3,10 +3,11 @@ from eventlet.green import select
|
||||
from eventlet.green import socket
|
||||
from eventlet.green import time
|
||||
|
||||
patcher.inject("asyncore",
|
||||
patcher.inject(
|
||||
"asyncore",
|
||||
globals(),
|
||||
('select', select),
|
||||
('socket', socket),
|
||||
('time', time))
|
||||
|
||||
del patcher
|
||||
del patcher
|
||||
|
@ -11,12 +11,16 @@ from eventlet.patcher import slurp_properties
|
||||
__all__ = os_orig.__all__
|
||||
__patched__ = ['fdopen', 'read', 'write', 'wait', 'waitpid', 'open']
|
||||
|
||||
slurp_properties(os_orig, globals(),
|
||||
ignore=__patched__, srckeys=dir(os_orig))
|
||||
slurp_properties(
|
||||
os_orig,
|
||||
globals(),
|
||||
ignore=__patched__,
|
||||
srckeys=dir(os_orig))
|
||||
|
||||
|
||||
def fdopen(fd, *args, **kw):
|
||||
"""fdopen(fd [, mode='r' [, bufsize]]) -> file_object
|
||||
|
||||
|
||||
Return an open file object connected to a file descriptor."""
|
||||
if not isinstance(fd, int):
|
||||
raise TypeError('fd should be int, not %r' % fd)
|
||||
@ -26,9 +30,11 @@ def fdopen(fd, *args, **kw):
|
||||
raise OSError(*e.args)
|
||||
|
||||
__original_read__ = os_orig.read
|
||||
|
||||
|
||||
def read(fd, n):
|
||||
"""read(fd, buffersize) -> string
|
||||
|
||||
|
||||
Read a file descriptor."""
|
||||
while True:
|
||||
try:
|
||||
@ -46,9 +52,11 @@ def read(fd, n):
|
||||
return ''
|
||||
|
||||
__original_write__ = os_orig.write
|
||||
|
||||
|
||||
def write(fd, st):
|
||||
"""write(fd, string) -> byteswritten
|
||||
|
||||
|
||||
Write a string to a file descriptor.
|
||||
"""
|
||||
while True:
|
||||
@ -61,18 +69,21 @@ def write(fd, st):
|
||||
if get_errno(e) != errno.EPIPE:
|
||||
raise
|
||||
hubs.trampoline(fd, write=True)
|
||||
|
||||
|
||||
|
||||
def wait():
|
||||
"""wait() -> (pid, status)
|
||||
|
||||
|
||||
Wait for completion of a child process."""
|
||||
return waitpid(0,0)
|
||||
return waitpid(0, 0)
|
||||
|
||||
__original_waitpid__ = os_orig.waitpid
|
||||
|
||||
|
||||
def waitpid(pid, options):
|
||||
"""waitpid(...)
|
||||
waitpid(pid, options) -> (pid, status)
|
||||
|
||||
|
||||
Wait for completion of a given child process."""
|
||||
if options & os_orig.WNOHANG != 0:
|
||||
return __original_waitpid__(pid, options)
|
||||
|
@ -46,11 +46,11 @@ from eventlet.support import six
|
||||
thread = patcher.original('thread') # non-monkeypatched module needed
|
||||
|
||||
|
||||
#This class provides the start() and stop() functions
|
||||
# This class provides the start() and stop() functions
|
||||
class Profile(profile_orig.Profile):
|
||||
base = profile_orig.Profile
|
||||
|
||||
def __init__(self, timer = None, bias=None):
|
||||
def __init__(self, timer=None, bias=None):
|
||||
self.current_tasklet = greenthread.getcurrent()
|
||||
self.thread_id = thread.get_ident()
|
||||
self.base.__init__(self, timer, bias)
|
||||
@ -68,7 +68,7 @@ class Profile(profile_orig.Profile):
|
||||
self.thread_id = thread.get_ident()
|
||||
self.simulate_call("profiler")
|
||||
|
||||
def start(self, name = "start"):
|
||||
def start(self, name="start"):
|
||||
if getattr(self, "running", False):
|
||||
return
|
||||
self._setup()
|
||||
@ -81,8 +81,8 @@ class Profile(profile_orig.Profile):
|
||||
self.running = False
|
||||
self.TallyTimings()
|
||||
|
||||
#special cases for the original run commands, makin sure to
|
||||
#clear the timer context.
|
||||
# special cases for the original run commands, makin sure to
|
||||
# clear the timer context.
|
||||
def runctx(self, cmd, globals, locals):
|
||||
if not getattr(self, "_has_setup", False):
|
||||
self._setup()
|
||||
@ -99,7 +99,6 @@ class Profile(profile_orig.Profile):
|
||||
finally:
|
||||
self.TallyTimings()
|
||||
|
||||
|
||||
def trace_dispatch_return_extend_back(self, frame, t):
|
||||
"""A hack function to override error checking in parent class. It
|
||||
allows invalid returns (where frames weren't preveiously entered into
|
||||
@ -110,33 +109,32 @@ class Profile(profile_orig.Profile):
|
||||
if isinstance(self.cur[-2], Profile.fake_frame):
|
||||
return False
|
||||
self.trace_dispatch_call(frame, 0)
|
||||
return self.trace_dispatch_return(frame, t);
|
||||
return self.trace_dispatch_return(frame, t)
|
||||
|
||||
def trace_dispatch_c_return_extend_back(self, frame, t):
|
||||
#same for c return
|
||||
# same for c return
|
||||
if isinstance(self.cur[-2], Profile.fake_frame):
|
||||
return False #ignore bogus returns
|
||||
return False # ignore bogus returns
|
||||
self.trace_dispatch_c_call(frame, 0)
|
||||
return self.trace_dispatch_return(frame,t)
|
||||
return self.trace_dispatch_return(frame, t)
|
||||
|
||||
|
||||
#Add "return safety" to the dispatchers
|
||||
# Add "return safety" to the dispatchers
|
||||
dispatch = dict(profile_orig.Profile.dispatch)
|
||||
dispatch.update({
|
||||
"return": trace_dispatch_return_extend_back,
|
||||
"c_return": trace_dispatch_c_return_extend_back,
|
||||
})
|
||||
})
|
||||
|
||||
def SwitchTasklet(self, t0, t1, t):
|
||||
#tally the time spent in the old tasklet
|
||||
# tally the time spent in the old tasklet
|
||||
pt, it, et, fn, frame, rcur = self.cur
|
||||
cur = (pt, it+t, et, fn, frame, rcur)
|
||||
cur = (pt, it + t, et, fn, frame, rcur)
|
||||
|
||||
#we are switching to a new tasklet, store the old
|
||||
# we are switching to a new tasklet, store the old
|
||||
self.sleeping[t0] = cur, self.timings
|
||||
self.current_tasklet = t1
|
||||
|
||||
#find the new one
|
||||
# find the new one
|
||||
try:
|
||||
self.cur, self.timings = self.sleeping.pop(t1)
|
||||
except KeyError:
|
||||
@ -144,30 +142,29 @@ class Profile(profile_orig.Profile):
|
||||
self.simulate_call("profiler")
|
||||
self.simulate_call("new_tasklet")
|
||||
|
||||
|
||||
def ContextWrap(f):
|
||||
@functools.wraps(f)
|
||||
def ContextWrapper(self, arg, t):
|
||||
current = greenthread.getcurrent()
|
||||
if current != self.current_tasklet:
|
||||
self.SwitchTasklet(self.current_tasklet, current, t)
|
||||
t = 0.0 #the time was billed to the previous tasklet
|
||||
t = 0.0 # the time was billed to the previous tasklet
|
||||
return f(self, arg, t)
|
||||
return ContextWrapper
|
||||
|
||||
#Add automatic tasklet detection to the callbacks.
|
||||
# Add automatic tasklet detection to the callbacks.
|
||||
dispatch = dict([(key, ContextWrap(val)) for key, val in six.iteritems(dispatch)])
|
||||
|
||||
def TallyTimings(self):
|
||||
oldtimings = self.sleeping
|
||||
self.sleeping = {}
|
||||
|
||||
#first, unwind the main "cur"
|
||||
# first, unwind the main "cur"
|
||||
self.cur = self.Unwind(self.cur, self.timings)
|
||||
|
||||
#we must keep the timings dicts separate for each tasklet, since it contains
|
||||
#the 'ns' item, recursion count of each function in that tasklet. This is
|
||||
#used in the Unwind dude.
|
||||
# we must keep the timings dicts separate for each tasklet, since it contains
|
||||
# the 'ns' item, recursion count of each function in that tasklet. This is
|
||||
# used in the Unwind dude.
|
||||
for tasklet, (cur, timings) in six.iteritems(oldtimings):
|
||||
self.Unwind(cur, timings)
|
||||
|
||||
@ -175,23 +172,23 @@ class Profile(profile_orig.Profile):
|
||||
if k not in self.timings:
|
||||
self.timings[k] = v
|
||||
else:
|
||||
#accumulate all to the self.timings
|
||||
# accumulate all to the self.timings
|
||||
cc, ns, tt, ct, callers = self.timings[k]
|
||||
#ns should be 0 after unwinding
|
||||
cc+=v[0]
|
||||
tt+=v[2]
|
||||
ct+=v[3]
|
||||
# ns should be 0 after unwinding
|
||||
cc += v[0]
|
||||
tt += v[2]
|
||||
ct += v[3]
|
||||
for k1, v1 in six.iteritems(v[4]):
|
||||
callers[k1] = callers.get(k1, 0)+v1
|
||||
callers[k1] = callers.get(k1, 0) + v1
|
||||
self.timings[k] = cc, ns, tt, ct, callers
|
||||
|
||||
def Unwind(self, cur, timings):
|
||||
"A function to unwind a 'cur' frame and tally the results"
|
||||
"see profile.trace_dispatch_return() for details"
|
||||
#also see simulate_cmd_complete()
|
||||
# also see simulate_cmd_complete()
|
||||
while(cur[-1]):
|
||||
rpt, rit, ret, rfn, frame, rcur = cur
|
||||
frame_total = rit+ret
|
||||
frame_total = rit + ret
|
||||
|
||||
if rfn in timings:
|
||||
cc, ns, tt, ct, callers = timings[rfn]
|
||||
|
@ -39,7 +39,7 @@ def select(read_list, write_list, error_list, timeout=None):
|
||||
assert hub.greenlet is not current, 'do not call blocking functions from the mainloop'
|
||||
ds = {}
|
||||
for r in read_list:
|
||||
ds[get_fileno(r)] = {'read' : r}
|
||||
ds[get_fileno(r)] = {'read': r}
|
||||
for w in write_list:
|
||||
ds.setdefault(get_fileno(w), {})['write'] = w
|
||||
for e in error_list:
|
||||
|
@ -4,15 +4,15 @@ from eventlet.hubs import get_hub
|
||||
__import__('eventlet.green._socket_nodns')
|
||||
__socket = sys.modules['eventlet.green._socket_nodns']
|
||||
|
||||
__all__ = __socket.__all__
|
||||
__patched__ = __socket.__patched__ + ['gethostbyname', 'getaddrinfo', 'create_connection',]
|
||||
__all__ = __socket.__all__
|
||||
__patched__ = __socket.__patched__ + ['gethostbyname', 'getaddrinfo', 'create_connection', ]
|
||||
|
||||
from eventlet.patcher import slurp_properties
|
||||
slurp_properties(__socket, globals(), srckeys=dir(__socket))
|
||||
|
||||
|
||||
greendns = None
|
||||
if os.environ.get("EVENTLET_NO_GREENDNS",'').lower() != "yes":
|
||||
if os.environ.get("EVENTLET_NO_GREENDNS", '').lower() != "yes":
|
||||
try:
|
||||
from eventlet.support import greendns
|
||||
except ImportError as ex:
|
||||
@ -25,8 +25,9 @@ if greendns:
|
||||
getnameinfo = greendns.getnameinfo
|
||||
__patched__ = __patched__ + ['gethostbyname_ex', 'getnameinfo']
|
||||
|
||||
def create_connection(address,
|
||||
timeout=_GLOBAL_DEFAULT_TIMEOUT,
|
||||
|
||||
def create_connection(address,
|
||||
timeout=_GLOBAL_DEFAULT_TIMEOUT,
|
||||
source_address=None):
|
||||
"""Connect to *address* and return the socket object.
|
||||
|
||||
@ -57,5 +58,3 @@ def create_connection(address,
|
||||
sock.close()
|
||||
|
||||
raise error(msg)
|
||||
|
||||
|
||||
|
@ -12,7 +12,7 @@ from eventlet.hubs import trampoline, IOClosed
|
||||
from eventlet.greenio import set_nonblocking, GreenSocket, SOCKET_CLOSED, CONNECT_ERR, CONNECT_SUCCESS
|
||||
orig_socket = __import__('socket')
|
||||
socket = orig_socket.socket
|
||||
if sys.version_info >= (2,7):
|
||||
if sys.version_info >= (2, 7):
|
||||
has_ciphers = True
|
||||
timeout_exc = SSLError
|
||||
else:
|
||||
@ -21,7 +21,9 @@ else:
|
||||
|
||||
__patched__ = ['SSLSocket', 'wrap_socket', 'sslwrap_simple']
|
||||
|
||||
|
||||
class GreenSSLSocket(__ssl.SSLSocket):
|
||||
|
||||
""" This is a green version of the SSLSocket class from the ssl module added
|
||||
in 2.6. For documentation on it, please see the Python standard
|
||||
documentation.
|
||||
@ -37,6 +39,7 @@ class GreenSSLSocket(__ssl.SSLSocket):
|
||||
"""
|
||||
# we are inheriting from SSLSocket because its constructor calls
|
||||
# do_handshake whose behavior we wish to override
|
||||
|
||||
def __init__(self, sock, *args, **kw):
|
||||
if not isinstance(sock, GreenSocket):
|
||||
sock = GreenSocket(sock)
|
||||
@ -104,7 +107,7 @@ class GreenSSLSocket(__ssl.SSLSocket):
|
||||
except IOClosed:
|
||||
return ''
|
||||
|
||||
def send (self, data, flags=0):
|
||||
def send(self, data, flags=0):
|
||||
if self._sslobj:
|
||||
return self._call_trampolining(
|
||||
super(GreenSSLSocket, self).send, data, flags)
|
||||
@ -112,7 +115,7 @@ class GreenSSLSocket(__ssl.SSLSocket):
|
||||
trampoline(self, write=True, timeout_exc=timeout_exc('timed out'))
|
||||
return socket.send(self, data, flags)
|
||||
|
||||
def sendto (self, data, addr, flags=0):
|
||||
def sendto(self, data, addr, flags=0):
|
||||
# *NOTE: gross, copied code from ssl.py becase it's not factored well enough to be used as-is
|
||||
if self._sslobj:
|
||||
raise ValueError("sendto not allowed on instances of %s" %
|
||||
@ -121,7 +124,7 @@ class GreenSSLSocket(__ssl.SSLSocket):
|
||||
trampoline(self, write=True, timeout_exc=timeout_exc('timed out'))
|
||||
return socket.sendto(self, data, addr, flags)
|
||||
|
||||
def sendall (self, data, flags=0):
|
||||
def sendall(self, data, flags=0):
|
||||
# *NOTE: gross, copied code from ssl.py becase it's not factored well enough to be used as-is
|
||||
if self._sslobj:
|
||||
if flags != 0:
|
||||
@ -176,25 +179,24 @@ class GreenSSLSocket(__ssl.SSLSocket):
|
||||
return ''
|
||||
raise
|
||||
|
||||
|
||||
def recv_into (self, buffer, nbytes=None, flags=0):
|
||||
def recv_into(self, buffer, nbytes=None, flags=0):
|
||||
if not self.act_non_blocking:
|
||||
trampoline(self, read=True, timeout=self.gettimeout(), timeout_exc=timeout_exc('timed out'))
|
||||
return super(GreenSSLSocket, self).recv_into(buffer, nbytes, flags)
|
||||
|
||||
def recvfrom (self, addr, buflen=1024, flags=0):
|
||||
def recvfrom(self, addr, buflen=1024, flags=0):
|
||||
if not self.act_non_blocking:
|
||||
trampoline(self, read=True, timeout=self.gettimeout(), timeout_exc=timeout_exc('timed out'))
|
||||
return super(GreenSSLSocket, self).recvfrom(addr, buflen, flags)
|
||||
|
||||
def recvfrom_into (self, buffer, nbytes=None, flags=0):
|
||||
def recvfrom_into(self, buffer, nbytes=None, flags=0):
|
||||
if not self.act_non_blocking:
|
||||
trampoline(self, read=True, timeout=self.gettimeout(), timeout_exc=timeout_exc('timed out'))
|
||||
return super(GreenSSLSocket, self).recvfrom_into(buffer, nbytes, flags)
|
||||
|
||||
def unwrap(self):
|
||||
return GreenSocket(self._call_trampolining(
|
||||
super(GreenSSLSocket, self).unwrap))
|
||||
super(GreenSSLSocket, self).unwrap))
|
||||
|
||||
def do_handshake(self):
|
||||
"""Perform a TLS/SSL handshake."""
|
||||
@ -227,7 +229,7 @@ class GreenSSLSocket(__ssl.SSLSocket):
|
||||
except orig_socket.error as exc:
|
||||
if get_errno(exc) in CONNECT_ERR:
|
||||
trampoline(self, write=True,
|
||||
timeout=end-time.time(), timeout_exc=timeout_exc('timed out'))
|
||||
timeout=end - time.time(), timeout_exc=timeout_exc('timed out'))
|
||||
elif get_errno(exc) in CONNECT_SUCCESS:
|
||||
return
|
||||
else:
|
||||
@ -235,7 +237,6 @@ class GreenSSLSocket(__ssl.SSLSocket):
|
||||
if time.time() >= end:
|
||||
raise timeout_exc('timed out')
|
||||
|
||||
|
||||
def connect(self, addr):
|
||||
"""Connects to remote ADDR, and then wraps the connection in
|
||||
an SSL channel."""
|
||||
@ -272,17 +273,18 @@ class GreenSSLSocket(__ssl.SSLSocket):
|
||||
if get_errno(e) != errno.EWOULDBLOCK:
|
||||
raise
|
||||
trampoline(self, read=True, timeout=self.gettimeout(),
|
||||
timeout_exc=timeout_exc('timed out'))
|
||||
timeout_exc=timeout_exc('timed out'))
|
||||
|
||||
new_ssl = type(self)(newsock,
|
||||
keyfile=self.keyfile,
|
||||
certfile=self.certfile,
|
||||
server_side=True,
|
||||
cert_reqs=self.cert_reqs,
|
||||
ssl_version=self.ssl_version,
|
||||
ca_certs=self.ca_certs,
|
||||
do_handshake_on_connect=self.do_handshake_on_connect,
|
||||
suppress_ragged_eofs=self.suppress_ragged_eofs)
|
||||
new_ssl = type(self)(
|
||||
newsock,
|
||||
keyfile=self.keyfile,
|
||||
certfile=self.certfile,
|
||||
server_side=True,
|
||||
cert_reqs=self.cert_reqs,
|
||||
ssl_version=self.ssl_version,
|
||||
ca_certs=self.ca_certs,
|
||||
do_handshake_on_connect=self.do_handshake_on_connect,
|
||||
suppress_ragged_eofs=self.suppress_ragged_eofs)
|
||||
return (new_ssl, addr)
|
||||
|
||||
def dup(self):
|
||||
@ -290,6 +292,7 @@ class GreenSSLSocket(__ssl.SSLSocket):
|
||||
|
||||
SSLSocket = GreenSSLSocket
|
||||
|
||||
|
||||
def wrap_socket(sock, *a, **kw):
|
||||
return GreenSSLSocket(sock, *a, **kw)
|
||||
|
||||
|
@ -20,6 +20,7 @@ if getattr(subprocess_orig, 'TimeoutExpired', None) is None:
|
||||
"""This exception is raised when the timeout expires while waiting for
|
||||
a child process.
|
||||
"""
|
||||
|
||||
def __init__(self, cmd, output=None):
|
||||
self.cmd = cmd
|
||||
self.output = output
|
||||
|
@ -66,6 +66,7 @@ def interrupt_main():
|
||||
|
||||
if hasattr(__thread, 'stack_size'):
|
||||
__original_stack_size__ = __thread.stack_size
|
||||
|
||||
def stack_size(size=None):
|
||||
if size is None:
|
||||
return __original_stack_size__()
|
||||
|
@ -12,7 +12,8 @@ __orig_threading = patcher.original('threading')
|
||||
__threadlocal = __orig_threading.local()
|
||||
|
||||
|
||||
patcher.inject('threading',
|
||||
patcher.inject(
|
||||
'threading',
|
||||
globals(),
|
||||
('thread', thread),
|
||||
('time', time))
|
||||
@ -21,9 +22,12 @@ del patcher
|
||||
|
||||
|
||||
_count = 1
|
||||
|
||||
|
||||
class _GreenThread(object):
|
||||
"""Wrapper for GreenThread objects to provide Thread-like attributes
|
||||
and methods"""
|
||||
|
||||
def __init__(self, g):
|
||||
global _count
|
||||
self._g = g
|
||||
@ -61,6 +65,7 @@ class _GreenThread(object):
|
||||
|
||||
__threading = None
|
||||
|
||||
|
||||
def _fixup_thread(t):
|
||||
# Some third-party packages (lockfile) will try to patch the
|
||||
# threading.Thread class with a get_name attribute if it doesn't
|
||||
@ -73,7 +78,7 @@ def _fixup_thread(t):
|
||||
__threading = __import__('threading')
|
||||
|
||||
if (hasattr(__threading.Thread, 'get_name') and
|
||||
not hasattr(t, 'get_name')):
|
||||
not hasattr(t, 'get_name')):
|
||||
t.get_name = t.getName
|
||||
return t
|
||||
|
||||
@ -88,7 +93,7 @@ def current_thread():
|
||||
active = __threadlocal.active
|
||||
except AttributeError:
|
||||
active = __threadlocal.active = {}
|
||||
|
||||
|
||||
try:
|
||||
t = active[id(g)]
|
||||
except KeyError:
|
||||
|
@ -3,4 +3,4 @@ from eventlet.patcher import slurp_properties
|
||||
__patched__ = ['sleep']
|
||||
slurp_properties(__time, globals(), ignore=__patched__, srckeys=dir(__time))
|
||||
from eventlet.greenthread import sleep
|
||||
sleep # silence pyflakes
|
||||
sleep # silence pyflakes
|
||||
|
@ -5,7 +5,8 @@ from eventlet.green import socket
|
||||
from eventlet.green import time
|
||||
from eventlet.green import urllib
|
||||
|
||||
patcher.inject('urllib2',
|
||||
patcher.inject(
|
||||
'urllib2',
|
||||
globals(),
|
||||
('httplib', httplib),
|
||||
('socket', socket),
|
||||
|
@ -33,6 +33,7 @@ class _QueueLock(object):
|
||||
is called, the threads are awoken in the order they blocked,
|
||||
one at a time. This lock can be required recursively by the same
|
||||
thread."""
|
||||
|
||||
def __init__(self):
|
||||
self._waiters = deque()
|
||||
self._count = 0
|
||||
@ -118,6 +119,7 @@ class _BlockedThread(object):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class Context(__zmq__.Context):
|
||||
"""Subclass of :class:`zmq.core.context.Context`
|
||||
"""
|
||||
@ -133,6 +135,7 @@ class Context(__zmq__.Context):
|
||||
raise ZMQError(ENOTSUP)
|
||||
return Socket(self, socket_type)
|
||||
|
||||
|
||||
def _wraps(source_fn):
|
||||
"""A decorator that copies the __name__ and __doc__ from the given
|
||||
function
|
||||
@ -191,6 +194,7 @@ _Socket_send_multipart = _Socket.send_multipart
|
||||
_Socket_recv_multipart = _Socket.recv_multipart
|
||||
_Socket_getsockopt = _Socket.getsockopt
|
||||
|
||||
|
||||
class Socket(_Socket):
|
||||
"""Green version of :class:`zmq.core.socket.Socket
|
||||
|
||||
@ -206,6 +210,7 @@ class Socket(_Socket):
|
||||
* send_multipart
|
||||
* recv_multipart
|
||||
"""
|
||||
|
||||
def __init__(self, context, socket_type):
|
||||
super(Socket, self).__init__(context, socket_type)
|
||||
|
||||
@ -292,7 +297,6 @@ class Socket(_Socket):
|
||||
# receiver. (Could check EVENTS for POLLIN here)
|
||||
self._eventlet_recv_event.wake()
|
||||
|
||||
|
||||
@_wraps(_Socket.send_multipart)
|
||||
def send_multipart(self, msg_parts, flags=0, copy=True, track=False):
|
||||
"""A send_multipart method that's safe to use when multiple
|
||||
|
@ -118,6 +118,7 @@ class GreenSocket(object):
|
||||
Pass False to indicate that socket is already in non-blocking mode
|
||||
to save syscalls.
|
||||
"""
|
||||
|
||||
def __init__(self, family_or_realsock=socket.AF_INET, *args, **kwargs):
|
||||
should_set_nonblocking = kwargs.pop('set_nonblocking', True)
|
||||
if isinstance(family_or_realsock, six.integer_types):
|
||||
@ -534,6 +535,7 @@ class GreenPipe(_fileobject):
|
||||
- Universal new lines are not supported and newlines property not implementeded
|
||||
- file argument can be descriptor, file name or file object.
|
||||
"""
|
||||
|
||||
def __init__(self, f, mode='r', bufsize=-1):
|
||||
if not isinstance(f, six.string_types + (int, file)):
|
||||
raise TypeError('f(ile) should be int, str, unicode or file, not %r' % f)
|
||||
|
@ -15,6 +15,7 @@ DEBUG = True
|
||||
class GreenPool(object):
|
||||
"""The GreenPool class is a pool of green threads.
|
||||
"""
|
||||
|
||||
def __init__(self, size=1000):
|
||||
self.size = size
|
||||
self.coroutines_running = set()
|
||||
@ -187,6 +188,7 @@ class GreenPile(object):
|
||||
than the one which is calling spawn. The iterator will exit early in that
|
||||
situation.
|
||||
"""
|
||||
|
||||
def __init__(self, size_or_pool=1000):
|
||||
if isinstance(size_or_pool, GreenPool):
|
||||
self.pool = size_or_pool
|
||||
|
@ -12,6 +12,7 @@ __all__ = ['getcurrent', 'sleep', 'spawn', 'spawn_n', 'spawn_after', 'spawn_afte
|
||||
|
||||
getcurrent = greenlet.getcurrent
|
||||
|
||||
|
||||
def sleep(seconds=0):
|
||||
"""Yield control to another eligible coroutine until at least *seconds* have
|
||||
elapsed.
|
||||
@ -109,7 +110,8 @@ def spawn_after_local(seconds, func, *args, **kwargs):
|
||||
|
||||
|
||||
def call_after_global(seconds, func, *args, **kwargs):
|
||||
warnings.warn("call_after_global is renamed to spawn_after, which"
|
||||
warnings.warn(
|
||||
"call_after_global is renamed to spawn_after, which"
|
||||
"has the same signature and semantics (plus a bit extra). Please do a"
|
||||
" quick search-and-replace on your codebase, thanks!",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
@ -117,7 +119,8 @@ def call_after_global(seconds, func, *args, **kwargs):
|
||||
|
||||
|
||||
def call_after_local(seconds, function, *args, **kwargs):
|
||||
warnings.warn("call_after_local is renamed to spawn_after_local, which"
|
||||
warnings.warn(
|
||||
"call_after_local is renamed to spawn_after_local, which"
|
||||
"has the same signature and semantics (plus a bit extra).",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
hub = hubs.get_hub()
|
||||
@ -142,6 +145,7 @@ def exc_after(seconds, *throw_args):
|
||||
TimeoutError = timeout.Timeout
|
||||
with_timeout = timeout.with_timeout
|
||||
|
||||
|
||||
def _spawn_n(seconds, func, args, kwargs):
|
||||
hub = hubs.get_hub()
|
||||
g = greenlet.greenlet(func, parent=hub.greenlet)
|
||||
@ -154,6 +158,7 @@ class GreenThread(greenlet.greenlet):
|
||||
property of being able to retrieve the return value of the main function.
|
||||
Do not construct GreenThread objects directly; call :func:`spawn` to get one.
|
||||
"""
|
||||
|
||||
def __init__(self, parent):
|
||||
greenlet.greenlet.__init__(self, self.main, parent)
|
||||
self._exit_event = event.Event()
|
||||
@ -239,6 +244,7 @@ class GreenThread(greenlet.greenlet):
|
||||
to :class:`greenlet.GreenletExit`)."""
|
||||
return cancel(self, *throw_args)
|
||||
|
||||
|
||||
def cancel(g, *throw_args):
|
||||
"""Like :func:`kill`, but only terminates the greenthread if it hasn't
|
||||
already started execution. If the grenthread has already started
|
||||
@ -246,6 +252,7 @@ def cancel(g, *throw_args):
|
||||
if not g:
|
||||
kill(g, *throw_args)
|
||||
|
||||
|
||||
def kill(g, *throw_args):
|
||||
"""Terminates the target greenthread by raising an exception into it.
|
||||
Whatever that greenthread might be doing; be it waiting for I/O or another
|
||||
|
@ -32,6 +32,7 @@ from eventlet.hubs.poll import READ, WRITE
|
||||
# NOTE: we rely on the fact that the epoll flag constants
|
||||
# are identical in value to the poll constants
|
||||
|
||||
|
||||
class Hub(poll.Hub):
|
||||
def __init__(self, clock=time.time):
|
||||
BaseHub.__init__(self, clock)
|
||||
|
@ -1,10 +1,9 @@
|
||||
import errno
|
||||
import heapq
|
||||
import math
|
||||
import traceback
|
||||
import signal
|
||||
import sys
|
||||
import warnings
|
||||
import traceback
|
||||
|
||||
arm_alarm = None
|
||||
if hasattr(signal, 'setitimer'):
|
||||
@ -20,15 +19,15 @@ else:
|
||||
signal.alarm(math.ceil(seconds))
|
||||
arm_alarm = alarm_signal
|
||||
|
||||
from eventlet.support import greenlets as greenlet, clear_sys_exc_info
|
||||
from eventlet.hubs import timer, IOClosed
|
||||
from eventlet import patcher
|
||||
from eventlet.hubs import timer, IOClosed
|
||||
from eventlet.support import greenlets as greenlet, clear_sys_exc_info
|
||||
time = patcher.original('time')
|
||||
|
||||
g_prevent_multiple_readers = True
|
||||
|
||||
READ="read"
|
||||
WRITE="write"
|
||||
READ = "read"
|
||||
WRITE = "write"
|
||||
|
||||
|
||||
def closed_callback(fileno):
|
||||
@ -39,6 +38,7 @@ def closed_callback(fileno):
|
||||
|
||||
|
||||
class FdListener(object):
|
||||
|
||||
def __init__(self, evtype, fileno, cb, tb, mark_as_closed):
|
||||
""" The following are required:
|
||||
cb - the standard callback, which will switch into the
|
||||
@ -61,6 +61,7 @@ class FdListener(object):
|
||||
self.mark_as_closed = mark_as_closed
|
||||
self.spent = False
|
||||
self.greenlet = greenlet.getcurrent()
|
||||
|
||||
def __repr__(self):
|
||||
return "%s(%r, %r, %r, %r)" % (type(self).__name__, self.evtype, self.fileno,
|
||||
self.cb, self.tb)
|
||||
@ -77,10 +78,15 @@ noop = FdListener(READ, 0, lambda x: None, lambda x: None, None)
|
||||
|
||||
|
||||
# in debug mode, track the call site that created the listener
|
||||
|
||||
|
||||
class DebugListener(FdListener):
|
||||
|
||||
def __init__(self, evtype, fileno, cb, tb, mark_as_closed):
|
||||
self.where_called = traceback.format_stack()
|
||||
self.greenlet = greenlet.getcurrent()
|
||||
super(DebugListener, self).__init__(evtype, fileno, cb, tb, mark_as_closed)
|
||||
|
||||
def __repr__(self):
|
||||
return "DebugListener(%r, %r, %r, %r, %r, %r)\n%sEndDebugFdListener" % (
|
||||
self.evtype,
|
||||
@ -108,8 +114,8 @@ class BaseHub(object):
|
||||
WRITE = WRITE
|
||||
|
||||
def __init__(self, clock=time.time):
|
||||
self.listeners = {READ:{}, WRITE:{}}
|
||||
self.secondaries = {READ:{}, WRITE:{}}
|
||||
self.listeners = {READ: {}, WRITE: {}}
|
||||
self.secondaries = {READ: {}, WRITE: {}}
|
||||
self.closed = []
|
||||
|
||||
self.clock = clock
|
||||
@ -134,7 +140,7 @@ class BaseHub(object):
|
||||
|
||||
def block_detect_post(self):
|
||||
if (hasattr(self, "_old_signal_handler") and
|
||||
self._old_signal_handler):
|
||||
self._old_signal_handler):
|
||||
signal.signal(signal.SIGALRM, self._old_signal_handler)
|
||||
signal.alarm(0)
|
||||
|
||||
@ -159,14 +165,15 @@ class BaseHub(object):
|
||||
bucket = self.listeners[evtype]
|
||||
if fileno in bucket:
|
||||
if g_prevent_multiple_readers:
|
||||
raise RuntimeError("Second simultaneous %s on fileno %s "\
|
||||
"detected. Unless you really know what you're doing, "\
|
||||
"make sure that only one greenthread can %s any "\
|
||||
"particular socket. Consider using a pools.Pool. "\
|
||||
"If you do know what you're doing and want to disable "\
|
||||
"this error, call "\
|
||||
"eventlet.debug.hub_prevent_multiple_readers(False) - MY THREAD=%s; THAT THREAD=%s" % (
|
||||
evtype, fileno, evtype, cb, bucket[fileno]))
|
||||
raise RuntimeError(
|
||||
"Second simultaneous %s on fileno %s "
|
||||
"detected. Unless you really know what you're doing, "
|
||||
"make sure that only one greenthread can %s any "
|
||||
"particular socket. Consider using a pools.Pool. "
|
||||
"If you do know what you're doing and want to disable "
|
||||
"this error, call "
|
||||
"eventlet.debug.hub_prevent_multiple_readers(False) - MY THREAD=%s; THAT THREAD=%s" % (
|
||||
evtype, fileno, evtype, cb, bucket[fileno]))
|
||||
# store off the second listener in another structure
|
||||
self.secondaries[evtype].setdefault(fileno, []).append(listener)
|
||||
else:
|
||||
@ -232,7 +239,6 @@ class BaseHub(object):
|
||||
"""
|
||||
self._obsolete(fileno)
|
||||
|
||||
|
||||
def remove_descriptor(self, fileno):
|
||||
""" Completely remove all listeners for this fileno. For internal use
|
||||
only."""
|
||||
@ -244,7 +250,7 @@ class BaseHub(object):
|
||||
for listener in listeners:
|
||||
try:
|
||||
listener.cb(fileno)
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
self.squelch_generic_exception(sys.exc_info())
|
||||
|
||||
def close_one(self):
|
||||
@ -386,7 +392,7 @@ class BaseHub(object):
|
||||
def timer_canceled(self, timer):
|
||||
self.timers_canceled += 1
|
||||
len_timers = len(self.timers) + len(self.next_timers)
|
||||
if len_timers > 1000 and len_timers/2 <= self.timers_canceled:
|
||||
if len_timers > 1000 and len_timers / 2 <= self.timers_canceled:
|
||||
self.timers_canceled = 0
|
||||
self.timers = [t for t in self.timers if not t[1].called]
|
||||
self.next_timers = [t for t in self.next_timers if not t[1].called]
|
||||
|
@ -6,7 +6,7 @@ select = patcher.original('select')
|
||||
time = patcher.original('time')
|
||||
sleep = time.sleep
|
||||
|
||||
from eventlet.support import get_errno, clear_sys_exc_info
|
||||
from eventlet.support import clear_sys_exc_info
|
||||
from eventlet.hubs.hub import BaseHub, READ, WRITE, noop
|
||||
|
||||
|
||||
@ -53,8 +53,7 @@ class Hub(BaseHub):
|
||||
events = self._events.setdefault(fileno, {})
|
||||
if evtype not in events:
|
||||
try:
|
||||
event = select.kevent(fileno,
|
||||
FILTERS.get(evtype), select.KQ_EV_ADD)
|
||||
event = select.kevent(fileno, FILTERS.get(evtype), select.KQ_EV_ADD)
|
||||
self._control([event], 0, 0)
|
||||
events[evtype] = event
|
||||
except ValueError:
|
||||
@ -63,8 +62,10 @@ class Hub(BaseHub):
|
||||
return listener
|
||||
|
||||
def _delete_events(self, events):
|
||||
del_events = [select.kevent(e.ident, e.filter, select.KQ_EV_DELETE)
|
||||
for e in events]
|
||||
del_events = [
|
||||
select.kevent(e.ident, e.filter, select.KQ_EV_DELETE)
|
||||
for e in events
|
||||
]
|
||||
self._control(del_events, 0, 0)
|
||||
|
||||
def remove(self, listener):
|
||||
@ -75,7 +76,7 @@ class Hub(BaseHub):
|
||||
event = self._events[fileno].pop(evtype)
|
||||
try:
|
||||
self._delete_events([event])
|
||||
except OSError as e:
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
def remove_descriptor(self, fileno):
|
||||
@ -83,9 +84,9 @@ class Hub(BaseHub):
|
||||
try:
|
||||
events = self._events.pop(fileno).values()
|
||||
self._delete_events(events)
|
||||
except KeyError as e:
|
||||
except KeyError:
|
||||
pass
|
||||
except OSError as e:
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
def wait(self, seconds=None):
|
||||
|
@ -1,13 +1,13 @@
|
||||
import sys
|
||||
import errno
|
||||
import signal
|
||||
import sys
|
||||
|
||||
from eventlet import patcher
|
||||
select = patcher.original('select')
|
||||
time = patcher.original('time')
|
||||
sleep = time.sleep
|
||||
|
||||
from eventlet.hubs.hub import BaseHub, READ, WRITE, noop
|
||||
from eventlet.support import get_errno, clear_sys_exc_info
|
||||
from eventlet.hubs.hub import BaseHub, READ, WRITE, noop, alarm_handler
|
||||
|
||||
EXC_MASK = select.POLLERR | select.POLLHUP
|
||||
READ_MASK = select.POLLIN | select.POLLPRI
|
||||
|
@ -4,8 +4,7 @@ import event
|
||||
import types
|
||||
|
||||
from eventlet.support import greenlets as greenlet, six
|
||||
from eventlet.hubs.hub import BaseHub, FdListener, READ, WRITE
|
||||
from eventlet.support import six
|
||||
from eventlet.hubs.hub import BaseHub, READ, WRITE
|
||||
|
||||
|
||||
class event_wrapper(object):
|
||||
@ -35,12 +34,13 @@ class event_wrapper(object):
|
||||
def pending(self):
|
||||
return bool(self.impl and self.impl.pending())
|
||||
|
||||
|
||||
class Hub(BaseHub):
|
||||
|
||||
SYSTEM_EXCEPTIONS = (KeyboardInterrupt, SystemExit)
|
||||
|
||||
def __init__(self):
|
||||
super(Hub,self).__init__()
|
||||
super(Hub, self).__init__()
|
||||
event.init()
|
||||
|
||||
self.signal_exc_info = None
|
||||
@ -112,7 +112,7 @@ class Hub(BaseHub):
|
||||
elif evtype is WRITE:
|
||||
evt = event.write(fileno, cb, fileno)
|
||||
|
||||
return super(Hub,self).add(evtype, fileno, evt, real_tb, mac)
|
||||
return super(Hub, self).add(evtype, fileno, evt, real_tb, mac)
|
||||
|
||||
def signal(self, signalnum, handler):
|
||||
def wrapper():
|
||||
@ -167,6 +167,7 @@ def _scheduled_call(event_impl, handle, evtype, arg):
|
||||
finally:
|
||||
event_impl.delete()
|
||||
|
||||
|
||||
def _scheduled_call_local(event_impl, handle, evtype, arg):
|
||||
cb, args, kwargs, caller_greenlet = arg
|
||||
try:
|
||||
|
@ -1,7 +1,7 @@
|
||||
import sys
|
||||
import errno
|
||||
import sys
|
||||
from eventlet import patcher
|
||||
from eventlet.support import get_errno, clear_sys_exc_info, six
|
||||
from eventlet.support import get_errno, clear_sys_exc_info
|
||||
select = patcher.original('select')
|
||||
time = patcher.original('time')
|
||||
|
||||
|
@ -4,6 +4,7 @@ from twisted.internet.base import DelayedCall as TwistedDelayedCall
|
||||
from eventlet.support import greenlets as greenlet
|
||||
from eventlet.hubs.hub import FdListener, READ, WRITE
|
||||
|
||||
|
||||
class DelayedCall(TwistedDelayedCall):
|
||||
"fix DelayedCall to behave like eventlet's Timer in some respects"
|
||||
|
||||
@ -13,6 +14,7 @@ class DelayedCall(TwistedDelayedCall):
|
||||
return
|
||||
return TwistedDelayedCall.cancel(self)
|
||||
|
||||
|
||||
class LocalDelayedCall(DelayedCall):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@ -29,6 +31,7 @@ class LocalDelayedCall(DelayedCall):
|
||||
|
||||
cancelled = property(_get_cancelled, _set_cancelled)
|
||||
|
||||
|
||||
def callLater(DelayedCallClass, reactor, _seconds, _f, *args, **kw):
|
||||
# the same as original but creates fixed DelayedCall instance
|
||||
assert callable(_f), "%s is not callable" % _f
|
||||
@ -43,13 +46,15 @@ def callLater(DelayedCallClass, reactor, _seconds, _f, *args, **kw):
|
||||
reactor._newTimedCalls.append(tple)
|
||||
return tple
|
||||
|
||||
|
||||
class socket_rwdescriptor(FdListener):
|
||||
#implements(IReadWriteDescriptor)
|
||||
# implements(IReadWriteDescriptor)
|
||||
def __init__(self, evtype, fileno, cb):
|
||||
super(socket_rwdescriptor, self).__init__(evtype, fileno, cb)
|
||||
if not isinstance(fileno, (int,long)):
|
||||
if not isinstance(fileno, (int, long)):
|
||||
raise TypeError("Expected int or long, got %s" % type(fileno))
|
||||
# Twisted expects fileno to be a callable, not an attribute
|
||||
|
||||
def _fileno():
|
||||
return fileno
|
||||
self.fileno = _fileno
|
||||
@ -131,6 +136,7 @@ class BaseTwistedHub(object):
|
||||
|
||||
def schedule_call_local(self, seconds, func, *args, **kwargs):
|
||||
from twisted.internet import reactor
|
||||
|
||||
def call_if_greenlet_alive(*args1, **kwargs1):
|
||||
if timer.greenlet.dead:
|
||||
return
|
||||
@ -166,7 +172,6 @@ class BaseTwistedHub(object):
|
||||
from twisted.internet import reactor
|
||||
return reactor.getWriters()
|
||||
|
||||
|
||||
def get_timers_count(self):
|
||||
from twisted.internet import reactor
|
||||
return len(reactor.getDelayedCalls())
|
||||
@ -191,7 +196,7 @@ class TwistedHub(BaseTwistedHub):
|
||||
installSignalHandlers = False
|
||||
|
||||
def __init__(self):
|
||||
assert Hub.state==0, ('%s hub can only be instantiated once'%type(self).__name__,
|
||||
assert Hub.state == 0, ('%s hub can only be instantiated once' % type(self).__name__,
|
||||
Hub.state)
|
||||
Hub.state = 1
|
||||
make_twisted_threadpool_daemonic() # otherwise the program
|
||||
@ -253,10 +258,12 @@ class TwistedHub(BaseTwistedHub):
|
||||
|
||||
Hub = TwistedHub
|
||||
|
||||
|
||||
class DaemonicThread(threading.Thread):
|
||||
def _set_daemon(self):
|
||||
return True
|
||||
|
||||
|
||||
def make_twisted_threadpool_daemonic():
|
||||
from twisted.python.threadpool import ThreadPool
|
||||
if ThreadPool.threadFactory != DaemonicThread:
|
||||
|
@ -1,5 +1,5 @@
|
||||
import sys
|
||||
import imp
|
||||
import sys
|
||||
|
||||
from eventlet.support import six
|
||||
|
||||
@ -13,6 +13,7 @@ class SysModulesSaver(object):
|
||||
"""Class that captures some subset of the current state of
|
||||
sys.modules. Pass in an iterator of module names to the
|
||||
constructor."""
|
||||
|
||||
def __init__(self, module_names=()):
|
||||
self._saved = {}
|
||||
imp.acquire_lock()
|
||||
@ -69,7 +70,7 @@ def inject(module_name, new_globals, *additional_modules):
|
||||
_green_socket_modules() +
|
||||
_green_thread_modules() +
|
||||
_green_time_modules())
|
||||
#_green_MySQLdb()) # enable this after a short baking-in period
|
||||
# _green_MySQLdb()) # enable this after a short baking-in period
|
||||
|
||||
# after this we are gonna screw with sys.modules, so capture the
|
||||
# state of all the modules we're going to mess with, and lock
|
||||
@ -81,22 +82,22 @@ def inject(module_name, new_globals, *additional_modules):
|
||||
for name, mod in additional_modules:
|
||||
sys.modules[name] = mod
|
||||
|
||||
## Remove the old module from sys.modules and reimport it while
|
||||
## the specified modules are in place
|
||||
# Remove the old module from sys.modules and reimport it while
|
||||
# the specified modules are in place
|
||||
sys.modules.pop(module_name, None)
|
||||
try:
|
||||
module = __import__(module_name, {}, {}, module_name.split('.')[:-1])
|
||||
|
||||
if new_globals is not None:
|
||||
## Update the given globals dictionary with everything from this new module
|
||||
# Update the given globals dictionary with everything from this new module
|
||||
for name in dir(module):
|
||||
if name not in __exclude:
|
||||
new_globals[name] = getattr(module, name)
|
||||
|
||||
## Keep a reference to the new module to prevent it from dying
|
||||
# Keep a reference to the new module to prevent it from dying
|
||||
sys.modules[patched_name] = module
|
||||
finally:
|
||||
saver.restore() ## Put the original modules back
|
||||
saver.restore() # Put the original modules back
|
||||
|
||||
return module
|
||||
|
||||
@ -140,6 +141,7 @@ def patch_function(func, *additional_modules):
|
||||
saver.restore()
|
||||
return patched
|
||||
|
||||
|
||||
def _original_patch_function(func, *module_names):
|
||||
"""Kind of the contrapositive of patch_function: decorates a
|
||||
function such that when it's called, sys.modules is populated only
|
||||
@ -201,6 +203,8 @@ def original(modname):
|
||||
return sys.modules[original_name]
|
||||
|
||||
already_patched = {}
|
||||
|
||||
|
||||
def monkey_patch(**on):
|
||||
"""Globally patches certain system modules to be greenthread-friendly.
|
||||
|
||||
@ -216,11 +220,11 @@ def monkey_patch(**on):
|
||||
"""
|
||||
accepted_args = set(('os', 'select', 'socket',
|
||||
'thread', 'time', 'psycopg', 'MySQLdb', '__builtin__'))
|
||||
default_on = on.pop("all",None)
|
||||
default_on = on.pop("all", None)
|
||||
for k in six.iterkeys(on):
|
||||
if k not in accepted_args:
|
||||
raise TypeError("monkey_patch() got an unexpected "\
|
||||
"keyword argument %r" % k)
|
||||
raise TypeError("monkey_patch() got an unexpected "
|
||||
"keyword argument %r" % k)
|
||||
if default_on is None:
|
||||
default_on = not (True in on.values())
|
||||
for modname in accepted_args:
|
||||
@ -279,6 +283,7 @@ def monkey_patch(**on):
|
||||
finally:
|
||||
imp.release_lock()
|
||||
|
||||
|
||||
def is_monkey_patched(module):
|
||||
"""Returns True if the given module is monkeypatched currently, False if
|
||||
not. *module* can be either the module itself or its name.
|
||||
@ -288,16 +293,19 @@ def is_monkey_patched(module):
|
||||
import_patched), this might not be correct about that particular
|
||||
module."""
|
||||
return module in already_patched or \
|
||||
getattr(module, '__name__', None) in already_patched
|
||||
getattr(module, '__name__', None) in already_patched
|
||||
|
||||
|
||||
def _green_os_modules():
|
||||
from eventlet.green import os
|
||||
return [('os', os)]
|
||||
|
||||
|
||||
def _green_select_modules():
|
||||
from eventlet.green import select
|
||||
return [('select', select)]
|
||||
|
||||
|
||||
def _green_socket_modules():
|
||||
from eventlet.green import socket
|
||||
try:
|
||||
@ -306,6 +314,7 @@ def _green_socket_modules():
|
||||
except ImportError:
|
||||
return [('socket', socket)]
|
||||
|
||||
|
||||
def _green_thread_modules():
|
||||
from eventlet.green import Queue
|
||||
from eventlet.green import thread
|
||||
@ -315,10 +324,12 @@ def _green_thread_modules():
|
||||
if six.PY3:
|
||||
return [('queue', Queue), ('_thread', thread), ('threading', threading)]
|
||||
|
||||
|
||||
def _green_time_modules():
|
||||
from eventlet.green import time
|
||||
return [('time', time)]
|
||||
|
||||
|
||||
def _green_MySQLdb():
|
||||
try:
|
||||
from eventlet.green import MySQLdb
|
||||
@ -326,6 +337,7 @@ def _green_MySQLdb():
|
||||
except ImportError:
|
||||
return []
|
||||
|
||||
|
||||
def _green_builtins():
|
||||
try:
|
||||
from eventlet.green import builtin
|
||||
@ -344,16 +356,14 @@ def slurp_properties(source, destination, ignore=[], srckeys=None):
|
||||
"""
|
||||
if srckeys is None:
|
||||
srckeys = source.__all__
|
||||
destination.update(dict([(name, getattr(source, name))
|
||||
for name in srckeys
|
||||
if not (
|
||||
name.startswith('__') or
|
||||
name in ignore)
|
||||
]))
|
||||
destination.update(dict([
|
||||
(name, getattr(source, name))
|
||||
for name in srckeys
|
||||
if not (name.startswith('__') or name in ignore)
|
||||
]))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
sys.argv.pop(0)
|
||||
monkey_patch()
|
||||
with open(sys.argv[0]) as f:
|
||||
|
@ -54,6 +54,7 @@ class Pool(object):
|
||||
greenthread calling :meth:`get` to cooperatively yield until an item
|
||||
is :meth:`put` in.
|
||||
"""
|
||||
|
||||
def __init__(self, min_size=0, max_size=4, order_as_stack=False, create=None):
|
||||
"""*order_as_stack* governs the ordering of the items in the free pool.
|
||||
If ``False`` (the default), the free items collection (of items that
|
||||
@ -89,7 +90,7 @@ class Pool(object):
|
||||
self.current_size -= 1
|
||||
raise
|
||||
return created
|
||||
self.current_size -= 1 # did not create
|
||||
self.current_size -= 1 # did not create
|
||||
return self.channel.get()
|
||||
|
||||
@contextmanager
|
||||
@ -176,6 +177,6 @@ class TokenPool(Pool):
|
||||
that the coroutine which holds the token has a right to consume some
|
||||
limited resource.
|
||||
"""
|
||||
|
||||
def create(self):
|
||||
return Token()
|
||||
|
||||
|
@ -302,7 +302,7 @@ class Source(object):
|
||||
if self._exc is None:
|
||||
res = repr(self.value)
|
||||
if len(res) > 50:
|
||||
res = res[:50]+'...'
|
||||
res = res[:50] + '...'
|
||||
result.append('result=%s' % res)
|
||||
else:
|
||||
result.append('raised=%s' % (self._exc, ))
|
||||
@ -737,5 +737,3 @@ class Pool(object):
|
||||
g = self.linkable_class()
|
||||
g.link(lambda *_args: self.semaphore.release())
|
||||
return g
|
||||
|
||||
|
||||
|
@ -116,7 +116,7 @@ class Process(object):
|
||||
written = self.child_stdin.write(stuff)
|
||||
self.child_stdin.flush()
|
||||
except ValueError as e:
|
||||
## File was closed
|
||||
# File was closed
|
||||
assert str(e) == 'I/O operation on closed file'
|
||||
if written == 0:
|
||||
self.dead_callback()
|
||||
|
@ -147,7 +147,7 @@ class LightQueue(object):
|
||||
"""
|
||||
|
||||
def __init__(self, maxsize=None):
|
||||
if maxsize is None or maxsize < 0: #None is not comparable in 3.x
|
||||
if maxsize is None or maxsize < 0: # None is not comparable in 3.x
|
||||
self.maxsize = None
|
||||
else:
|
||||
self.maxsize = maxsize
|
||||
@ -193,7 +193,7 @@ class LightQueue(object):
|
||||
"""Resizes the queue's maximum size.
|
||||
|
||||
If the size is increased, and there are putters waiting, they may be woken up."""
|
||||
if self.maxsize is not None and (size is None or size > self.maxsize): # None is not comparable in 3.x
|
||||
if self.maxsize is not None and (size is None or size > self.maxsize): # None is not comparable in 3.x
|
||||
# Maybe wake some stuff up
|
||||
self._schedule_unlock()
|
||||
self.maxsize = size
|
||||
@ -217,7 +217,7 @@ class LightQueue(object):
|
||||
|
||||
``Queue(None)`` is never full.
|
||||
"""
|
||||
return self.maxsize is not None and self.qsize() >= self.maxsize # None is not comparable in 3.x
|
||||
return self.maxsize is not None and self.qsize() >= self.maxsize # None is not comparable in 3.x
|
||||
|
||||
def put(self, item, block=True, timeout=None):
|
||||
"""Put an item into the queue.
|
||||
@ -335,7 +335,7 @@ class LightQueue(object):
|
||||
getter = self.getters.pop()
|
||||
if getter:
|
||||
item = putter.item
|
||||
putter.item = _NONE # this makes greenlet calling put() not to call _put() again
|
||||
putter.item = _NONE # this makes greenlet calling put() not to call _put() again
|
||||
self._put(item)
|
||||
item = self._get()
|
||||
getter.switch(item)
|
||||
@ -348,7 +348,7 @@ class LightQueue(object):
|
||||
else:
|
||||
break
|
||||
finally:
|
||||
self._event_unlock = None # QQQ maybe it's possible to obtain this info from libevent?
|
||||
self._event_unlock = None # QQQ maybe it's possible to obtain this info from libevent?
|
||||
# i.e. whether this event is pending _OR_ currently executing
|
||||
# testcase: 2 greenlets: while True: q.put(q.get()) - nothing else has a change to execute
|
||||
# to avoid this, schedule unlock with timer(0, ...) once in a while
|
||||
@ -378,6 +378,7 @@ class Queue(LightQueue):
|
||||
In all other respects, this Queue class resembled the standard library,
|
||||
:class:`Queue`.
|
||||
'''
|
||||
|
||||
def __init__(self, maxsize=None):
|
||||
LightQueue.__init__(self, maxsize)
|
||||
self.unfinished_tasks = 0
|
||||
|
@ -14,7 +14,8 @@ def get_errno(exc):
|
||||
"""
|
||||
|
||||
try:
|
||||
if exc.errno is not None: return exc.errno
|
||||
if exc.errno is not None:
|
||||
return exc.errno
|
||||
except AttributeError:
|
||||
pass
|
||||
try:
|
||||
|
@ -34,6 +34,8 @@
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
import struct
|
||||
import sys
|
||||
|
||||
from eventlet import patcher
|
||||
from eventlet.green import _socket_nodns
|
||||
@ -45,23 +47,28 @@ dns = patcher.import_patched('dns',
|
||||
time=time,
|
||||
select=select)
|
||||
for pkg in ('dns.query', 'dns.exception', 'dns.inet', 'dns.message',
|
||||
'dns.rdatatype','dns.resolver', 'dns.reversename'):
|
||||
setattr(dns, pkg.split('.')[1], patcher.import_patched(pkg,
|
||||
socket=_socket_nodns,
|
||||
time=time,
|
||||
select=select))
|
||||
'dns.rdatatype', 'dns.resolver', 'dns.reversename'):
|
||||
setattr(dns, pkg.split('.')[1], patcher.import_patched(
|
||||
pkg,
|
||||
socket=_socket_nodns,
|
||||
time=time,
|
||||
select=select))
|
||||
|
||||
socket = _socket_nodns
|
||||
|
||||
DNS_QUERY_TIMEOUT = 10.0
|
||||
|
||||
|
||||
#
|
||||
# Resolver instance used to perfrom DNS lookups.
|
||||
#
|
||||
class FakeAnswer(list):
|
||||
expiration = 0
|
||||
expiration = 0
|
||||
|
||||
|
||||
class FakeRecord(object):
|
||||
pass
|
||||
pass
|
||||
|
||||
|
||||
class ResolverProxy(object):
|
||||
def __init__(self, *args, **kwargs):
|
||||
@ -94,7 +101,7 @@ class ResolverProxy(object):
|
||||
|
||||
def query(self, *args, **kwargs):
|
||||
if self._resolver is None:
|
||||
self._resolver = dns.resolver.Resolver(filename = self._filename)
|
||||
self._resolver = dns.resolver.Resolver(filename=self._filename)
|
||||
self._resolver.cache = dns.resolver.Cache()
|
||||
|
||||
query = args[0]
|
||||
@ -111,7 +118,8 @@ class ResolverProxy(object):
|
||||
#
|
||||
# cache
|
||||
#
|
||||
resolver = ResolverProxy(dev=True)
|
||||
resolver = ResolverProxy(dev=True)
|
||||
|
||||
|
||||
def resolve(name):
|
||||
error = None
|
||||
@ -120,13 +128,13 @@ def resolve(name):
|
||||
if rrset is None or time.time() > rrset.expiration:
|
||||
try:
|
||||
rrset = resolver.query(name)
|
||||
except dns.exception.Timeout as e:
|
||||
except dns.exception.Timeout:
|
||||
error = (socket.EAI_AGAIN, 'Lookup timed out')
|
||||
except dns.exception.DNSException as e:
|
||||
except dns.exception.DNSException:
|
||||
error = (socket.EAI_NODATA, 'No address associated with hostname')
|
||||
else:
|
||||
pass
|
||||
#responses.insert(name, rrset)
|
||||
# responses.insert(name, rrset)
|
||||
|
||||
if error:
|
||||
if rrset is None:
|
||||
@ -134,6 +142,8 @@ def resolve(name):
|
||||
else:
|
||||
sys.stderr.write('DNS error: %r %r\n' % (name, error))
|
||||
return rrset
|
||||
|
||||
|
||||
#
|
||||
# methods
|
||||
#
|
||||
@ -147,9 +157,9 @@ def getaliases(host):
|
||||
|
||||
try:
|
||||
answers = dns.resolver.query(host, 'cname')
|
||||
except dns.exception.Timeout as e:
|
||||
except dns.exception.Timeout:
|
||||
error = (socket.EAI_AGAIN, 'Lookup timed out')
|
||||
except dns.exception.DNSException as e:
|
||||
except dns.exception.DNSException:
|
||||
error = (socket.EAI_NODATA, 'No address associated with hostname')
|
||||
else:
|
||||
for record in answers:
|
||||
@ -160,6 +170,7 @@ def getaliases(host):
|
||||
|
||||
return cnames
|
||||
|
||||
|
||||
def getaddrinfo(host, port, family=0, socktype=0, proto=0, flags=0):
|
||||
"""Replacement for Python's socket.getaddrinfo.
|
||||
|
||||
@ -178,6 +189,7 @@ def getaddrinfo(host, port, family=0, socktype=0, proto=0, flags=0):
|
||||
value.append((socket.AF_INET, socktype, proto, '', (rr.address, port)))
|
||||
return value
|
||||
|
||||
|
||||
def gethostbyname(hostname):
|
||||
"""Replacement for Python's socket.gethostbyname.
|
||||
|
||||
@ -189,6 +201,7 @@ def gethostbyname(hostname):
|
||||
rrset = resolve(hostname)
|
||||
return rrset[0].address
|
||||
|
||||
|
||||
def gethostbyname_ex(hostname):
|
||||
"""Replacement for Python's socket.gethostbyname_ex.
|
||||
|
||||
@ -204,6 +217,7 @@ def gethostbyname_ex(hostname):
|
||||
addrs.append(rr.address)
|
||||
return (hostname, [], addrs)
|
||||
|
||||
|
||||
def getnameinfo(sockaddr, flags):
|
||||
"""Replacement for Python's socket.getnameinfo.
|
||||
|
||||
@ -227,15 +241,15 @@ def getnameinfo(sockaddr, flags):
|
||||
|
||||
if is_ipv4_addr(host):
|
||||
try:
|
||||
rrset = resolver.query(
|
||||
rrset = resolver.query(
|
||||
dns.reversename.from_address(host), dns.rdatatype.PTR)
|
||||
if len(rrset) > 1:
|
||||
raise socket.error('sockaddr resolved to multiple addresses')
|
||||
host = rrset[0].target.to_text(omit_final_dot=True)
|
||||
except dns.exception.Timeout as e:
|
||||
except dns.exception.Timeout:
|
||||
if flags & socket.NI_NAMEREQD:
|
||||
raise socket.gaierror((socket.EAI_AGAIN, 'Lookup timed out'))
|
||||
except dns.exception.DNSException as e:
|
||||
except dns.exception.DNSException:
|
||||
if flags & socket.NI_NAMEREQD:
|
||||
raise socket.gaierror(
|
||||
(socket.EAI_NONAME, 'Name or service not known'))
|
||||
@ -246,9 +260,9 @@ def getnameinfo(sockaddr, flags):
|
||||
raise socket.error('sockaddr resolved to multiple addresses')
|
||||
if flags & socket.NI_NUMERICHOST:
|
||||
host = rrset[0].address
|
||||
except dns.exception.Timeout as e:
|
||||
except dns.exception.Timeout:
|
||||
raise socket.gaierror((socket.EAI_AGAIN, 'Lookup timed out'))
|
||||
except dns.exception.DNSException as e:
|
||||
except dns.exception.DNSException:
|
||||
raise socket.gaierror(
|
||||
(socket.EAI_NODATA, 'No address associated with hostname'))
|
||||
|
||||
@ -272,6 +286,7 @@ def is_ipv4_addr(host):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def _net_read(sock, count, expiration):
|
||||
"""coro friendly replacement for dns.query._net_write
|
||||
Read the specified number of bytes from sock. Keep trying until we
|
||||
@ -284,7 +299,7 @@ def _net_read(sock, count, expiration):
|
||||
try:
|
||||
n = sock.recv(count)
|
||||
except socket.timeout:
|
||||
## Q: Do we also need to catch coro.CoroutineSocketWake and pass?
|
||||
# Q: Do we also need to catch coro.CoroutineSocketWake and pass?
|
||||
if expiration - time.time() <= 0.0:
|
||||
raise dns.exception.Timeout
|
||||
if n == '':
|
||||
@ -293,6 +308,7 @@ def _net_read(sock, count, expiration):
|
||||
s = s + n
|
||||
return s
|
||||
|
||||
|
||||
def _net_write(sock, data, expiration):
|
||||
"""coro friendly replacement for dns.query._net_write
|
||||
Write the specified data to the socket.
|
||||
@ -305,13 +321,13 @@ def _net_write(sock, data, expiration):
|
||||
try:
|
||||
current += sock.send(data[current:])
|
||||
except socket.timeout:
|
||||
## Q: Do we also need to catch coro.CoroutineSocketWake and pass?
|
||||
# Q: Do we also need to catch coro.CoroutineSocketWake and pass?
|
||||
if expiration - time.time() <= 0.0:
|
||||
raise dns.exception.Timeout
|
||||
|
||||
def udp(
|
||||
q, where, timeout=DNS_QUERY_TIMEOUT, port=53, af=None, source=None,
|
||||
source_port=0, ignore_unexpected=False):
|
||||
|
||||
def udp(q, where, timeout=DNS_QUERY_TIMEOUT, port=53, af=None, source=None,
|
||||
source_port=0, ignore_unexpected=False):
|
||||
"""coro friendly replacement for dns.query.udp
|
||||
Return the response obtained after sending a query via UDP.
|
||||
|
||||
@ -362,14 +378,14 @@ def udp(
|
||||
try:
|
||||
s.sendto(wire, destination)
|
||||
except socket.timeout:
|
||||
## Q: Do we also need to catch coro.CoroutineSocketWake and pass?
|
||||
# Q: Do we also need to catch coro.CoroutineSocketWake and pass?
|
||||
if expiration - time.time() <= 0.0:
|
||||
raise dns.exception.Timeout
|
||||
while 1:
|
||||
try:
|
||||
(wire, from_address) = s.recvfrom(65535)
|
||||
except socket.timeout:
|
||||
## Q: Do we also need to catch coro.CoroutineSocketWake and pass?
|
||||
# Q: Do we also need to catch coro.CoroutineSocketWake and pass?
|
||||
if expiration - time.time() <= 0.0:
|
||||
raise dns.exception.Timeout
|
||||
if from_address == destination:
|
||||
@ -377,7 +393,7 @@ def udp(
|
||||
if not ignore_unexpected:
|
||||
raise dns.query.UnexpectedSource(
|
||||
'got a response from %s instead of %s'
|
||||
% (from_address, destination))
|
||||
% (from_address, destination))
|
||||
finally:
|
||||
s.close()
|
||||
|
||||
@ -386,8 +402,9 @@ def udp(
|
||||
raise dns.query.BadResponse()
|
||||
return r
|
||||
|
||||
|
||||
def tcp(q, where, timeout=DNS_QUERY_TIMEOUT, port=53,
|
||||
af=None, source=None, source_port=0):
|
||||
af=None, source=None, source_port=0):
|
||||
"""coro friendly replacement for dns.query.tcp
|
||||
Return the response obtained after sending a query via TCP.
|
||||
|
||||
@ -434,7 +451,7 @@ def tcp(q, where, timeout=DNS_QUERY_TIMEOUT, port=53,
|
||||
try:
|
||||
s.connect(destination)
|
||||
except socket.timeout:
|
||||
## Q: Do we also need to catch coro.CoroutineSocketWake and pass?
|
||||
# Q: Do we also need to catch coro.CoroutineSocketWake and pass?
|
||||
if expiration - time.time() <= 0.0:
|
||||
raise dns.exception.Timeout
|
||||
|
||||
@ -454,10 +471,10 @@ def tcp(q, where, timeout=DNS_QUERY_TIMEOUT, port=53,
|
||||
raise dns.query.BadResponse()
|
||||
return r
|
||||
|
||||
|
||||
def reset():
|
||||
resolver.clear()
|
||||
resolver.clear()
|
||||
|
||||
# Install our coro-friendly replacements for the tcp and udp query methods.
|
||||
dns.query.tcp = tcp
|
||||
dns.query.udp = udp
|
||||
|
||||
|
@ -24,6 +24,6 @@ except ImportError as e:
|
||||
try:
|
||||
from support.stacklesss import greenlet, getcurrent, GreenletExit
|
||||
preserves_excinfo = False
|
||||
(greenlet, getcurrent, GreenletExit) # silence pyflakes
|
||||
(greenlet, getcurrent, GreenletExit) # silence pyflakes
|
||||
except ImportError as e:
|
||||
raise ImportError("Unable to find an implementation of greenlet.")
|
||||
|
@ -5,17 +5,17 @@ Use `make_psycopg_green()` to enable eventlet support in Psycopg.
|
||||
|
||||
# Copyright (C) 2010 Daniele Varrazzo <daniele.varrazzo@gmail.com>
|
||||
# and licensed under the MIT license:
|
||||
#
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
@ -29,6 +29,7 @@ from psycopg2 import extensions
|
||||
|
||||
from eventlet.hubs import trampoline
|
||||
|
||||
|
||||
def make_psycopg_green():
|
||||
"""Configure Psycopg to be used with eventlet in non-blocking way."""
|
||||
if not hasattr(extensions, 'set_wait_callback'):
|
||||
@ -38,6 +39,7 @@ def make_psycopg_green():
|
||||
|
||||
extensions.set_wait_callback(eventlet_wait_callback)
|
||||
|
||||
|
||||
def eventlet_wait_callback(conn, timeout=-1):
|
||||
"""A wait callback useful to allow eventlet to work with Psycopg."""
|
||||
while 1:
|
||||
|
@ -3,10 +3,10 @@ from py.magic import greenlet
|
||||
import sys
|
||||
import types
|
||||
|
||||
|
||||
def emulate():
|
||||
module = types.ModuleType('greenlet')
|
||||
sys.modules['greenlet'] = module
|
||||
module.greenlet = greenlet
|
||||
module.getcurrent = greenlet.getcurrent
|
||||
module.GreenletExit = greenlet.GreenletExit
|
||||
|
||||
|
@ -110,7 +110,7 @@ class MovedModule(_LazyDescr):
|
||||
# well if this MovedModule is for an module that is unavailable on this
|
||||
# machine (like winreg on Unix systems). Thus, we pretend __file__ and
|
||||
# __name__ don't exist if the module hasn't been loaded yet. See issues
|
||||
# #51 and #53.
|
||||
# 51 and #53.
|
||||
if attr in ("__file__", "__name__") and self.mod not in sys.modules:
|
||||
raise AttributeError
|
||||
_module = self._resolve()
|
||||
@ -159,7 +159,6 @@ class MovedAttribute(_LazyDescr):
|
||||
return getattr(module, self.attr)
|
||||
|
||||
|
||||
|
||||
class _MovedItems(_LazyModule):
|
||||
"""Lazy loading of moved objects"""
|
||||
|
||||
@ -477,14 +476,17 @@ def iterkeys(d, **kw):
|
||||
"""Return an iterator over the keys of a dictionary."""
|
||||
return iter(getattr(d, _iterkeys)(**kw))
|
||||
|
||||
|
||||
def itervalues(d, **kw):
|
||||
"""Return an iterator over the values of a dictionary."""
|
||||
return iter(getattr(d, _itervalues)(**kw))
|
||||
|
||||
|
||||
def iteritems(d, **kw):
|
||||
"""Return an iterator over the (key, value) pairs of a dictionary."""
|
||||
return iter(getattr(d, _iteritems)(**kw))
|
||||
|
||||
|
||||
def iterlists(d, **kw):
|
||||
"""Return an iterator over the (key, [values]) pairs of a dictionary."""
|
||||
return iter(getattr(d, _iterlists)(**kw))
|
||||
@ -493,6 +495,7 @@ def iterlists(d, **kw):
|
||||
if PY3:
|
||||
def b(s):
|
||||
return s.encode("latin-1")
|
||||
|
||||
def u(s):
|
||||
return s
|
||||
unichr = chr
|
||||
@ -512,14 +515,18 @@ else:
|
||||
def b(s):
|
||||
return s
|
||||
# Workaround for standalone backslash
|
||||
|
||||
def u(s):
|
||||
return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape")
|
||||
unichr = unichr
|
||||
int2byte = chr
|
||||
|
||||
def byte2int(bs):
|
||||
return ord(bs[0])
|
||||
|
||||
def indexbytes(buf, i):
|
||||
return ord(buf[i])
|
||||
|
||||
def iterbytes(buf):
|
||||
return (ord(byte) for byte in buf)
|
||||
import StringIO
|
||||
@ -531,7 +538,6 @@ _add_doc(u, """Text literal""")
|
||||
if PY3:
|
||||
exec_ = getattr(moves.builtins, "exec")
|
||||
|
||||
|
||||
def reraise(tp, value, tb=None):
|
||||
if value.__traceback__ is not tb:
|
||||
raise value.with_traceback(tb)
|
||||
@ -550,7 +556,6 @@ else:
|
||||
_locs_ = _globs_
|
||||
exec("""exec _code_ in _globs_, _locs_""")
|
||||
|
||||
|
||||
exec_("""def reraise(tp, value, tb=None):
|
||||
raise tp, value, tb
|
||||
""")
|
||||
@ -563,6 +568,7 @@ if print_ is None:
|
||||
fp = kwargs.pop("file", sys.stdout)
|
||||
if fp is None:
|
||||
return
|
||||
|
||||
def write(data):
|
||||
if not isinstance(data, basestring):
|
||||
data = str(data)
|
||||
@ -618,6 +624,7 @@ def with_metaclass(meta, *bases):
|
||||
"""Create a base class with a metaclass."""
|
||||
return meta("NewBase", bases, {})
|
||||
|
||||
|
||||
def add_metaclass(metaclass):
|
||||
"""Class decorator for creating a class with a metaclass."""
|
||||
def wrapper(cls):
|
||||
|
@ -3,10 +3,10 @@ from stackless import greenlet
|
||||
import sys
|
||||
import types
|
||||
|
||||
|
||||
def emulate():
|
||||
module = types.ModuleType('greenlet')
|
||||
sys.modules['greenlet'] = module
|
||||
module.greenlet = greenlet
|
||||
module.getcurrent = greenlet.getcurrent
|
||||
module.GreenletExit = greenlet.GreenletExit
|
||||
|
||||
|
@ -22,7 +22,7 @@ class FirstSwitch(object):
|
||||
self.gr = gr
|
||||
|
||||
def __call__(self, *args, **kw):
|
||||
#print("first call", args, kw)
|
||||
# print("first call", args, kw)
|
||||
gr = self.gr
|
||||
del gr.switch
|
||||
run, gr.run = gr.run, None
|
||||
@ -46,7 +46,7 @@ class greenlet(object):
|
||||
self.switch = FirstSwitch(self)
|
||||
|
||||
def switch(self, *args):
|
||||
#print("switch", args)
|
||||
# print("switch", args)
|
||||
global caller
|
||||
caller = stackless.getcurrent()
|
||||
coro_args[self] = args
|
||||
|
@ -30,6 +30,8 @@ _NONE = object()
|
||||
|
||||
# deriving from BaseException so that "except Exception as e" doesn't catch
|
||||
# Timeout exceptions.
|
||||
|
||||
|
||||
class Timeout(BaseException):
|
||||
"""Raises *exception* in the current greenthread after *timeout* seconds.
|
||||
|
||||
@ -54,13 +56,13 @@ class Timeout(BaseException):
|
||||
it should not be called explicitly, unless the timer has been
|
||||
canceled."""
|
||||
assert not self.pending, \
|
||||
'%r is already started; to restart it, cancel it first' % self
|
||||
if self.seconds is None: # "fake" timeout (never expires)
|
||||
'%r is already started; to restart it, cancel it first' % self
|
||||
if self.seconds is None: # "fake" timeout (never expires)
|
||||
self.timer = None
|
||||
elif self.exception is None or isinstance(self.exception, bool): # timeout that raises self
|
||||
elif self.exception is None or isinstance(self.exception, bool): # timeout that raises self
|
||||
self.timer = get_hub().schedule_call_global(
|
||||
self.seconds, greenlet.getcurrent().throw, self)
|
||||
else: # regular timeout with user-provided exception
|
||||
else: # regular timeout with user-provided exception
|
||||
self.timer = get_hub().schedule_call_global(
|
||||
self.seconds, greenlet.getcurrent().throw, self.exception)
|
||||
return self
|
||||
|
@ -166,6 +166,7 @@ class Proxy(object):
|
||||
of strings, which represent the names of attributes that should be
|
||||
wrapped in Proxy objects when accessed.
|
||||
"""
|
||||
|
||||
def __init__(self, obj, autowrap=(), autowrap_names=()):
|
||||
self._obj = obj
|
||||
self._autowrap = autowrap
|
||||
|
@ -1,11 +1,13 @@
|
||||
import socket
|
||||
import sys
|
||||
import warnings
|
||||
|
||||
|
||||
__original_socket__ = socket.socket
|
||||
|
||||
|
||||
def tcp_socket():
|
||||
warnings.warn("eventlet.util.tcp_socket is deprecated. "
|
||||
warnings.warn(
|
||||
"eventlet.util.tcp_socket is deprecated. "
|
||||
"Please use the standard socket technique for this instead: "
|
||||
"sock = socket.socket()",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
@ -15,8 +17,11 @@ def tcp_socket():
|
||||
|
||||
# if ssl is available, use eventlet.green.ssl for our ssl implementation
|
||||
from eventlet.green import ssl
|
||||
|
||||
|
||||
def wrap_ssl(sock, certificate=None, private_key=None, server_side=False):
|
||||
warnings.warn("eventlet.util.wrap_ssl is deprecated. "
|
||||
warnings.warn(
|
||||
"eventlet.util.wrap_ssl is deprecated. "
|
||||
"Please use the eventlet.green.ssl.wrap_socket()",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
return ssl.wrap_socket(
|
||||
@ -28,7 +33,8 @@ def wrap_ssl(sock, certificate=None, private_key=None, server_side=False):
|
||||
|
||||
|
||||
def wrap_socket_with_coroutine_socket(use_thread_pool=None):
|
||||
warnings.warn("eventlet.util.wrap_socket_with_coroutine_socket() is now "
|
||||
warnings.warn(
|
||||
"eventlet.util.wrap_socket_with_coroutine_socket() is now "
|
||||
"eventlet.patcher.monkey_patch(all=False, socket=True)",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
from eventlet import patcher
|
||||
@ -36,7 +42,8 @@ def wrap_socket_with_coroutine_socket(use_thread_pool=None):
|
||||
|
||||
|
||||
def wrap_pipes_with_coroutine_pipes():
|
||||
warnings.warn("eventlet.util.wrap_pipes_with_coroutine_pipes() is now "
|
||||
warnings.warn(
|
||||
"eventlet.util.wrap_pipes_with_coroutine_pipes() is now "
|
||||
"eventlet.patcher.monkey_patch(all=False, os=True)",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
from eventlet import patcher
|
||||
@ -44,7 +51,8 @@ def wrap_pipes_with_coroutine_pipes():
|
||||
|
||||
|
||||
def wrap_select_with_coroutine_select():
|
||||
warnings.warn("eventlet.util.wrap_select_with_coroutine_select() is now "
|
||||
warnings.warn(
|
||||
"eventlet.util.wrap_select_with_coroutine_select() is now "
|
||||
"eventlet.patcher.monkey_patch(all=False, select=True)",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
from eventlet import patcher
|
||||
@ -57,7 +65,8 @@ def wrap_threading_local_with_coro_local():
|
||||
Since greenlets cannot cross threads, so this should be semantically
|
||||
identical to ``threadlocal.local``
|
||||
"""
|
||||
warnings.warn("eventlet.util.wrap_threading_local_with_coro_local() is now "
|
||||
warnings.warn(
|
||||
"eventlet.util.wrap_threading_local_with_coro_local() is now "
|
||||
"eventlet.patcher.monkey_patch(all=False, thread=True) -- though"
|
||||
"note that more than just _local is patched now.",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
@ -67,7 +76,8 @@ def wrap_threading_local_with_coro_local():
|
||||
|
||||
|
||||
def socket_bind_and_listen(descriptor, addr=('', 0), backlog=50):
|
||||
warnings.warn("eventlet.util.socket_bind_and_listen is deprecated."
|
||||
warnings.warn(
|
||||
"eventlet.util.socket_bind_and_listen is deprecated."
|
||||
"Please use the standard socket methodology for this instead:"
|
||||
"sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, 1)"
|
||||
"sock.bind(addr)"
|
||||
@ -80,7 +90,8 @@ def socket_bind_and_listen(descriptor, addr=('', 0), backlog=50):
|
||||
|
||||
|
||||
def set_reuse_addr(descriptor):
|
||||
warnings.warn("eventlet.util.set_reuse_addr is deprecated."
|
||||
warnings.warn(
|
||||
"eventlet.util.set_reuse_addr is deprecated."
|
||||
"Please use the standard socket methodology for this instead:"
|
||||
"sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, 1)",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
|
@ -3,11 +3,11 @@ import codecs
|
||||
import collections
|
||||
import errno
|
||||
from random import Random
|
||||
from socket import error as SocketError
|
||||
import string
|
||||
import struct
|
||||
import sys
|
||||
import time
|
||||
from socket import error as SocketError
|
||||
|
||||
try:
|
||||
from hashlib import md5, sha1
|
||||
@ -15,7 +15,6 @@ except ImportError: # pragma NO COVER
|
||||
from md5 import md5
|
||||
from sha import sha as sha1
|
||||
|
||||
import eventlet
|
||||
from eventlet import semaphore
|
||||
from eventlet import wsgi
|
||||
from eventlet.green import socket
|
||||
@ -215,7 +214,7 @@ class WebSocketWSGI(object):
|
||||
if p in self.supported_protocols:
|
||||
negotiated_protocol = p
|
||||
break
|
||||
#extensions = environ.get('HTTP_SEC_WEBSOCKET_EXTENSIONS', None)
|
||||
# extensions = environ.get('HTTP_SEC_WEBSOCKET_EXTENSIONS', None)
|
||||
# if extensions:
|
||||
# extensions = [i.strip() for i in extensions.split(',')]
|
||||
|
||||
|
@ -2,10 +2,10 @@ import sys
|
||||
from zmq import FORWARDER, PUB, SUB, SUBSCRIBE
|
||||
from zmq.devices import Device
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
usage = 'usage: chat_bridge sub_address pub_address'
|
||||
if len (sys.argv) != 3:
|
||||
if len(sys.argv) != 3:
|
||||
print(usage)
|
||||
sys.exit(1)
|
||||
|
||||
|
@ -1,16 +1,17 @@
|
||||
import eventlet
|
||||
from eventlet.green import socket
|
||||
|
||||
PORT=3001
|
||||
PORT = 3001
|
||||
participants = set()
|
||||
|
||||
|
||||
def read_chat_forever(writer, reader):
|
||||
line = reader.readline()
|
||||
while line:
|
||||
print("Chat:", line.strip())
|
||||
for p in participants:
|
||||
try:
|
||||
if p is not writer: # Don't echo
|
||||
if p is not writer: # Don't echo
|
||||
p.write(line)
|
||||
p.flush()
|
||||
except socket.error as e:
|
||||
@ -30,8 +31,8 @@ try:
|
||||
print("Participant joined chat.")
|
||||
new_writer = new_connection.makefile('w')
|
||||
participants.add(new_writer)
|
||||
eventlet.spawn_n(read_chat_forever,
|
||||
new_writer,
|
||||
eventlet.spawn_n(read_chat_forever,
|
||||
new_writer,
|
||||
new_connection.makefile('r'))
|
||||
except (KeyboardInterrupt, SystemExit):
|
||||
print("ChatServer exiting.")
|
||||
|
@ -13,7 +13,8 @@ $ python examples/distributed_websocket_chat.py -p tcp://127.0.0.1:12345 -s tcp:
|
||||
So all messages are published to port 12345 and the device forwards all the
|
||||
messages to 12346 where they are subscribed to
|
||||
"""
|
||||
import os, sys
|
||||
import os
|
||||
import sys
|
||||
import eventlet
|
||||
from collections import defaultdict
|
||||
from eventlet import spawn_n, sleep
|
||||
@ -26,6 +27,7 @@ from uuid import uuid1
|
||||
use_hub('zeromq')
|
||||
ctx = zmq.Context()
|
||||
|
||||
|
||||
class IDName(object):
|
||||
|
||||
def __init__(self):
|
||||
@ -44,12 +46,13 @@ class IDName(object):
|
||||
def unpack_message(self, msg):
|
||||
sender, message = msg
|
||||
sender_name = 'you said' if sender.id == self.id \
|
||||
else '%s says' % sender
|
||||
else '%s says' % sender
|
||||
return "%s: %s" % (sender_name, message)
|
||||
|
||||
|
||||
participants = defaultdict(IDName)
|
||||
|
||||
|
||||
def subscribe_and_distribute(sub_socket):
|
||||
global participants
|
||||
while True:
|
||||
@ -62,6 +65,7 @@ def subscribe_and_distribute(sub_socket):
|
||||
except:
|
||||
del participants[ws]
|
||||
|
||||
|
||||
@websocket.WebSocketWSGI
|
||||
def handle(ws):
|
||||
global pub_socket
|
||||
@ -81,7 +85,8 @@ def handle(ws):
|
||||
sleep()
|
||||
finally:
|
||||
del participants[ws]
|
||||
|
||||
|
||||
|
||||
def dispatch(environ, start_response):
|
||||
"""Resolves to the web page or the websocket depending on the path."""
|
||||
global port
|
||||
@ -90,14 +95,14 @@ def dispatch(environ, start_response):
|
||||
else:
|
||||
start_response('200 OK', [('content-type', 'text/html')])
|
||||
return [open(os.path.join(
|
||||
os.path.dirname(__file__),
|
||||
os.path.dirname(__file__),
|
||||
'websocket_chat.html')).read() % dict(port=port)]
|
||||
|
||||
port = None
|
||||
|
||||
if __name__ == "__main__":
|
||||
usage = 'usage: websocket_chat -p pub address -s sub address port number'
|
||||
if len (sys.argv) != 6:
|
||||
if len(sys.argv) != 6:
|
||||
print(usage)
|
||||
sys.exit(1)
|
||||
|
||||
|
@ -13,12 +13,14 @@ from __future__ import print_function
|
||||
|
||||
import eventlet
|
||||
|
||||
|
||||
def handle(fd):
|
||||
print("client connected")
|
||||
while True:
|
||||
# pass through every non-eof line
|
||||
x = fd.readline()
|
||||
if not x: break
|
||||
if not x:
|
||||
break
|
||||
fd.write(x)
|
||||
fd.flush()
|
||||
print("echoed", x, end=' ')
|
||||
|
@ -22,4 +22,4 @@ http://ln.hixie.ch/rss/html
|
||||
|
||||
url = 'http://localhost:9010/'
|
||||
result = urllib2.urlopen(url, big_list_of_feeds)
|
||||
print(result.read())
|
||||
print(result.read())
|
||||
|
@ -7,15 +7,17 @@ feedparser = eventlet.import_patched('feedparser')
|
||||
# the pool provides a safety limit on our concurrency
|
||||
pool = eventlet.GreenPool()
|
||||
|
||||
|
||||
def fetch_title(url):
|
||||
d = feedparser.parse(url)
|
||||
return d.feed.get('title', '')
|
||||
|
||||
|
||||
def app(environ, start_response):
|
||||
if environ['REQUEST_METHOD'] != 'POST':
|
||||
start_response('403 Forbidden', [])
|
||||
return []
|
||||
|
||||
|
||||
# the pile collects the result of a concurrent operation -- in this case,
|
||||
# the collection of feed titles
|
||||
pile = eventlet.GreenPile(pool)
|
||||
@ -23,7 +25,7 @@ def app(environ, start_response):
|
||||
url = line.strip()
|
||||
if url:
|
||||
pile.spawn(fetch_title, url)
|
||||
# since the pile is an iterator over the results,
|
||||
# since the pile is an iterator over the results,
|
||||
# you can use it in all sorts of great Pythonic ways
|
||||
titles = '\n'.join(pile)
|
||||
start_response('200 OK', [('Content-type', 'text/plain')])
|
||||
@ -32,4 +34,4 @@ def app(environ, start_response):
|
||||
|
||||
if __name__ == '__main__':
|
||||
from eventlet import wsgi
|
||||
wsgi.server(eventlet.listen(('localhost', 9010)), app)
|
||||
wsgi.server(eventlet.listen(('localhost', 9010)), app)
|
||||
|
@ -1,14 +1,17 @@
|
||||
""" This is an incredibly simple port forwarder from port 7000 to 22 on
|
||||
localhost. It calls a callback function when the socket is closed, to
|
||||
""" This is an incredibly simple port forwarder from port 7000 to 22 on
|
||||
localhost. It calls a callback function when the socket is closed, to
|
||||
demonstrate one way that you could start to do interesting things by
|
||||
starting from a simple framework like this.
|
||||
"""
|
||||
|
||||
import eventlet
|
||||
|
||||
|
||||
def closed_callback():
|
||||
print("called back")
|
||||
|
||||
def forward(source, dest, cb = lambda: None):
|
||||
|
||||
def forward(source, dest, cb=lambda: None):
|
||||
"""Forwards bytes unidirectionally from source to dest"""
|
||||
while True:
|
||||
d = source.recv(32384)
|
||||
|
@ -1,12 +1,12 @@
|
||||
"""This is a recursive web crawler. Don't go pointing this at random sites;
|
||||
it doesn't respect robots.txt and it is pretty brutal about how quickly it
|
||||
it doesn't respect robots.txt and it is pretty brutal about how quickly it
|
||||
fetches pages.
|
||||
|
||||
This is a kind of "producer/consumer" example; the fetch function produces
|
||||
jobs, and the GreenPool itself is the consumer, farming out work concurrently.
|
||||
This is a kind of "producer/consumer" example; the fetch function produces
|
||||
jobs, and the GreenPool itself is the consumer, farming out work concurrently.
|
||||
It's easier to write it this way rather than writing a standard consumer loop;
|
||||
GreenPool handles any exceptions raised and arranges so that there's a set
|
||||
number of "workers", so you don't have to write that tedious management code
|
||||
number of "workers", so you don't have to write that tedious management code
|
||||
yourself.
|
||||
"""
|
||||
from __future__ import with_statement
|
||||
@ -29,16 +29,16 @@ def fetch(url, outq):
|
||||
new_url = url_match.group(0)
|
||||
outq.put(new_url)
|
||||
|
||||
|
||||
|
||||
def producer(start_url):
|
||||
"""Recursively crawl starting from *start_url*. Returns a set of
|
||||
"""Recursively crawl starting from *start_url*. Returns a set of
|
||||
urls that were found."""
|
||||
pool = eventlet.GreenPool()
|
||||
seen = set()
|
||||
q = eventlet.Queue()
|
||||
q.put(start_url)
|
||||
# keep looping if there are new urls, or workers that may produce more urls
|
||||
while True:
|
||||
while True:
|
||||
while not q.empty():
|
||||
url = q.get()
|
||||
# limit requests to eventlet.net so we don't crash all over the internet
|
||||
@ -48,7 +48,7 @@ def producer(start_url):
|
||||
pool.waitall()
|
||||
if q.empty():
|
||||
break
|
||||
|
||||
|
||||
return seen
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
"""This is a recursive web crawler. Don't go pointing this at random sites;
|
||||
it doesn't respect robots.txt and it is pretty brutal about how quickly it
|
||||
it doesn't respect robots.txt and it is pretty brutal about how quickly it
|
||||
fetches pages.
|
||||
|
||||
The code for this is very short; this is perhaps a good indication
|
||||
@ -34,9 +34,10 @@ def fetch(url, seen, pool):
|
||||
# while this seems stack-recursive, it's actually not:
|
||||
# spawned greenthreads start their own stacks
|
||||
pool.spawn_n(fetch, new_url, seen, pool)
|
||||
|
||||
|
||||
|
||||
def crawl(start_url):
|
||||
"""Recursively crawl starting from *start_url*. Returns a set of
|
||||
"""Recursively crawl starting from *start_url*. Returns a set of
|
||||
urls that were found."""
|
||||
pool = eventlet.GreenPool()
|
||||
seen = set()
|
||||
|
@ -13,7 +13,7 @@ class LineOnlyReceiver(basic.LineOnlyReceiver):
|
||||
print('received: %r' % line)
|
||||
if not line:
|
||||
return
|
||||
app, context, node = (line + ' ').split(' ', 3)
|
||||
app, context, node = (line + ' ').split(' ', 3)
|
||||
context = {'u' : 'users', 'g': 'global'}.get(context, context)
|
||||
d = deferToGreenThread(client._get, app, node, globaltree=context=='global')
|
||||
def callback(result):
|
||||
|
@ -24,6 +24,7 @@ def handle(ws):
|
||||
ws.send("0 %s %s\n" % (i, random.random()))
|
||||
eventlet.sleep(0.1)
|
||||
|
||||
|
||||
def dispatch(environ, start_response):
|
||||
""" This resolves to the web page or the websocket depending on
|
||||
the path."""
|
||||
|
@ -8,6 +8,7 @@ PORT = 7000
|
||||
|
||||
participants = set()
|
||||
|
||||
|
||||
@websocket.WebSocketWSGI
|
||||
def handle(ws):
|
||||
participants.add(ws)
|
||||
@ -20,7 +21,8 @@ def handle(ws):
|
||||
p.send(m)
|
||||
finally:
|
||||
participants.remove(ws)
|
||||
|
||||
|
||||
|
||||
def dispatch(environ, start_response):
|
||||
"""Resolves to the web page or the websocket depending on the path."""
|
||||
if environ['PATH_INFO'] == '/chat':
|
||||
@ -29,9 +31,9 @@ def dispatch(environ, start_response):
|
||||
start_response('200 OK', [('content-type', 'text/html')])
|
||||
html_path = os.path.join(os.path.dirname(__file__), 'websocket_chat.html')
|
||||
return [open(html_path).read() % {'port': PORT}]
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# run an example app from the command line
|
||||
# run an example app from the command line
|
||||
listener = eventlet.listen(('127.0.0.1', PORT))
|
||||
print("\nVisit http://localhost:7000/ in your websocket-capable browser.\n")
|
||||
wsgi.server(listener, dispatch)
|
||||
|
@ -8,11 +8,12 @@ http://pypi.python.org/pypi/Spawning/
|
||||
import eventlet
|
||||
from eventlet import wsgi
|
||||
|
||||
|
||||
def hello_world(env, start_response):
|
||||
if env['PATH_INFO'] != '/':
|
||||
start_response('404 Not Found', [('Content-Type', 'text/plain')])
|
||||
return ['Not Found\r\n']
|
||||
start_response('200 OK', [('Content-Type', 'text/plain')])
|
||||
return ['Hello, World!\r\n']
|
||||
|
||||
|
||||
wsgi.server(eventlet.listen(('', 8090)), hello_world)
|
||||
|
@ -1,4 +1,5 @@
|
||||
import eventlet, sys
|
||||
import eventlet
|
||||
import sys
|
||||
from eventlet.green import socket, zmq
|
||||
from eventlet.hubs import use_hub
|
||||
use_hub('zeromq')
|
||||
@ -7,6 +8,7 @@ ADDR = 'ipc:///tmp/chat'
|
||||
|
||||
ctx = zmq.Context()
|
||||
|
||||
|
||||
def publish(writer):
|
||||
|
||||
print("connected")
|
||||
@ -23,7 +25,8 @@ def publish(writer):
|
||||
writer.flush()
|
||||
|
||||
|
||||
PORT=3001
|
||||
PORT = 3001
|
||||
|
||||
|
||||
def read_chat_forever(reader, pub_socket):
|
||||
|
||||
@ -61,4 +64,4 @@ try:
|
||||
new_connection.makefile('r'),
|
||||
pub_socket)
|
||||
except (KeyboardInterrupt, SystemExit):
|
||||
print("ChatServer exiting.")
|
||||
print("ChatServer exiting.")
|
||||
|
@ -3,6 +3,7 @@ import eventlet
|
||||
|
||||
CTX = zmq.Context(1)
|
||||
|
||||
|
||||
def bob_client(ctx, count):
|
||||
print("STARTING BOB")
|
||||
bob = zmq.Socket(CTX, zmq.REQ)
|
||||
@ -13,6 +14,7 @@ def bob_client(ctx, count):
|
||||
bob.send("HI")
|
||||
print("BOB GOT:", bob.recv())
|
||||
|
||||
|
||||
def alice_server(ctx, count):
|
||||
print("STARTING ALICE")
|
||||
alice = zmq.Socket(CTX, zmq.REP)
|
||||
|
@ -36,7 +36,7 @@ class TestServe(LimitedTestCase):
|
||||
# tests that the server closes the client sock on handle() exception
|
||||
def crasher(sock, addr):
|
||||
sock.recv(1024)
|
||||
0//0
|
||||
0 // 0
|
||||
|
||||
l = eventlet.listen(('localhost', 0))
|
||||
gt = eventlet.spawn(eventlet.serve, l, crasher)
|
||||
@ -50,7 +50,7 @@ class TestServe(LimitedTestCase):
|
||||
def crasher(sock, addr):
|
||||
sock.recv(1024)
|
||||
sock.close()
|
||||
0//0
|
||||
0 // 0
|
||||
|
||||
l = eventlet.listen(('localhost', 0))
|
||||
gt = eventlet.spawn(eventlet.serve, l, crasher)
|
||||
|
@ -439,10 +439,10 @@ class DBConnectionPool(DBTester):
|
||||
start = time.time()
|
||||
bench(c)
|
||||
end = time.time()
|
||||
results.append(end-start)
|
||||
results.append(end - start)
|
||||
|
||||
print("\n%u iterations took an average of %f seconds, (%s) in %s\n" % (
|
||||
iterations, sum(results)/len(results), results, type(self)))
|
||||
iterations, sum(results) / len(results), results, type(self)))
|
||||
|
||||
def test_raising_create(self):
|
||||
# if the create() method raises an exception the pool should
|
||||
@ -609,14 +609,14 @@ class MysqlConnectionPool(object):
|
||||
pass
|
||||
dbname = 'test%s' % os.getpid()
|
||||
db = self._dbmodule.connect(**auth).cursor()
|
||||
db.execute("create database "+dbname)
|
||||
db.execute("create database " + dbname)
|
||||
db.close()
|
||||
self._auth['db'] = dbname
|
||||
del db
|
||||
|
||||
def drop_db(self):
|
||||
db = self._dbmodule.connect(**self._auth).cursor()
|
||||
db.execute("drop database "+self._auth['db'])
|
||||
db.execute("drop database " + self._auth['db'])
|
||||
db.close()
|
||||
del db
|
||||
|
||||
@ -679,7 +679,7 @@ class Psycopg2ConnectionPool(object):
|
||||
conn = self._dbmodule.connect(**auth)
|
||||
conn.set_isolation_level(0)
|
||||
db = conn.cursor()
|
||||
db.execute("create database "+dbname)
|
||||
db.execute("create database " + dbname)
|
||||
db.close()
|
||||
conn.close()
|
||||
|
||||
@ -689,7 +689,7 @@ class Psycopg2ConnectionPool(object):
|
||||
conn = self._dbmodule.connect(**auth)
|
||||
conn.set_isolation_level(0)
|
||||
db = conn.cursor()
|
||||
db.execute("drop database "+self._auth['database'])
|
||||
db.execute("drop database " + self._auth['database'])
|
||||
db.close()
|
||||
conn.close()
|
||||
|
||||
|
@ -2,10 +2,12 @@ import eventlet
|
||||
from eventlet import event
|
||||
from tests import LimitedTestCase
|
||||
|
||||
|
||||
class TestEvent(LimitedTestCase):
|
||||
def test_waiting_for_event(self):
|
||||
evt = event.Event()
|
||||
value = 'some stuff'
|
||||
|
||||
def send_to_event():
|
||||
evt.send(value)
|
||||
eventlet.spawn_n(send_to_event)
|
||||
@ -19,8 +21,8 @@ class TestEvent(LimitedTestCase):
|
||||
|
||||
def _test_multiple_waiters(self, exception):
|
||||
evt = event.Event()
|
||||
value = 'some stuff'
|
||||
results = []
|
||||
|
||||
def wait_on_event(i_am_done):
|
||||
evt.wait()
|
||||
results.append(True)
|
||||
@ -48,6 +50,7 @@ class TestEvent(LimitedTestCase):
|
||||
self.assertRaises(AssertionError, evt.reset)
|
||||
|
||||
value = 'some stuff'
|
||||
|
||||
def send_to_event():
|
||||
evt.send(value)
|
||||
eventlet.spawn_n(send_to_event)
|
||||
@ -61,6 +64,7 @@ class TestEvent(LimitedTestCase):
|
||||
|
||||
# reset and everything should be happy
|
||||
evt.reset()
|
||||
|
||||
def send_to_event2():
|
||||
evt.send(value2)
|
||||
eventlet.spawn_n(send_to_event2)
|
||||
@ -75,4 +79,3 @@ class TestEvent(LimitedTestCase):
|
||||
# shouldn't see the RuntimeError again
|
||||
eventlet.Timeout(0.001)
|
||||
self.assertRaises(eventlet.Timeout, evt.wait)
|
||||
|
||||
|
@ -244,7 +244,7 @@ class GreenPool(tests.LimitedTestCase):
|
||||
eventlet.sleep(0)
|
||||
self.assertEqual(p.free(), 2)
|
||||
|
||||
#Once the pool is exhausted, spawning forces a yield.
|
||||
# Once the pool is exhausted, spawning forces a yield.
|
||||
p.spawn_n(foo, 2)
|
||||
self.assertEqual(1, p.free())
|
||||
self.assertEqual(r, [1])
|
||||
|
@ -3,10 +3,13 @@ from eventlet import greenthread
|
||||
from eventlet.support import greenlets as greenlet
|
||||
|
||||
_g_results = []
|
||||
|
||||
|
||||
def passthru(*args, **kw):
|
||||
_g_results.append((args, kw))
|
||||
return args, kw
|
||||
|
||||
|
||||
def waiter(a):
|
||||
greenthread.sleep(0.1)
|
||||
return a
|
||||
@ -19,6 +22,7 @@ class Asserts(object):
|
||||
assert gt.dead
|
||||
assert not gt
|
||||
|
||||
|
||||
class Spawn(LimitedTestCase, Asserts):
|
||||
def tearDown(self):
|
||||
global _g_results
|
||||
@ -27,15 +31,15 @@ class Spawn(LimitedTestCase, Asserts):
|
||||
|
||||
def test_simple(self):
|
||||
gt = greenthread.spawn(passthru, 1, b=2)
|
||||
self.assertEqual(gt.wait(), ((1,),{'b':2}))
|
||||
self.assertEqual(_g_results, [((1,),{'b':2})])
|
||||
self.assertEqual(gt.wait(), ((1,), {'b': 2}))
|
||||
self.assertEqual(_g_results, [((1,), {'b': 2})])
|
||||
|
||||
def test_n(self):
|
||||
gt = greenthread.spawn_n(passthru, 2, b=3)
|
||||
assert not gt.dead
|
||||
greenthread.sleep(0)
|
||||
assert gt.dead
|
||||
self.assertEqual(_g_results, [((2,),{'b':3})])
|
||||
self.assertEqual(_g_results, [((2,), {'b': 3})])
|
||||
|
||||
def test_kill(self):
|
||||
gt = greenthread.spawn(passthru, 6)
|
||||
@ -66,6 +70,7 @@ class Spawn(LimitedTestCase, Asserts):
|
||||
|
||||
def test_link(self):
|
||||
results = []
|
||||
|
||||
def link_func(g, *a, **kw):
|
||||
results.append(g)
|
||||
results.append(a)
|
||||
@ -73,10 +78,11 @@ class Spawn(LimitedTestCase, Asserts):
|
||||
gt = greenthread.spawn(passthru, 5)
|
||||
gt.link(link_func, 4, b=5)
|
||||
self.assertEqual(gt.wait(), ((5,), {}))
|
||||
self.assertEqual(results, [gt, (4,), {'b':5}])
|
||||
self.assertEqual(results, [gt, (4,), {'b': 5}])
|
||||
|
||||
def test_link_after_exited(self):
|
||||
results = []
|
||||
|
||||
def link_func(g, *a, **kw):
|
||||
results.append(g)
|
||||
results.append(a)
|
||||
@ -84,7 +90,7 @@ class Spawn(LimitedTestCase, Asserts):
|
||||
gt = greenthread.spawn(passthru, 5)
|
||||
self.assertEqual(gt.wait(), ((5,), {}))
|
||||
gt.link(link_func, 4, b=5)
|
||||
self.assertEqual(results, [gt, (4,), {'b':5}])
|
||||
self.assertEqual(results, [gt, (4,), {'b': 5}])
|
||||
|
||||
def test_link_relinks(self):
|
||||
# test that linking in a linked func doesn't cause infinite recursion.
|
||||
@ -101,6 +107,7 @@ class Spawn(LimitedTestCase, Asserts):
|
||||
gt.wait()
|
||||
self.assertEqual(called, [True])
|
||||
|
||||
|
||||
class SpawnAfter(Spawn):
|
||||
def test_basic(self):
|
||||
gt = greenthread.spawn_after(0.1, passthru, 20)
|
||||
@ -123,6 +130,7 @@ class SpawnAfter(Spawn):
|
||||
gt.kill()
|
||||
self.assert_dead(gt)
|
||||
|
||||
|
||||
class SpawnAfterLocal(LimitedTestCase, Asserts):
|
||||
def setUp(self):
|
||||
super(SpawnAfterLocal, self).setUp()
|
||||
|
@ -261,7 +261,7 @@ class TestSuspend(LimitedTestCase):
|
||||
import sys
|
||||
import tempfile
|
||||
self.tempdir = tempfile.mkdtemp('test_suspend')
|
||||
filename = os.path.join(self.tempdir, 'test_suspend.py')
|
||||
filename = os.path.join(self.tempdir, 'test_suspend.py')
|
||||
fd = open(filename, "w")
|
||||
fd.write("""import eventlet
|
||||
eventlet.Timeout(0.5)
|
||||
|
@ -125,6 +125,7 @@ except AttributeError:
|
||||
import keyword
|
||||
import re
|
||||
regex = re.compile(r'^[a-z_][a-z0-9_]*$', re.I)
|
||||
|
||||
def _isidentifier(string):
|
||||
if string in keyword.kwlist:
|
||||
return False
|
||||
@ -238,7 +239,7 @@ def _check_signature(func, mock, skipfirst, instance=False):
|
||||
def _copy_func_details(func, funcopy):
|
||||
funcopy.__name__ = func.__name__
|
||||
funcopy.__doc__ = func.__doc__
|
||||
#funcopy.__dict__.update(func.__dict__)
|
||||
# funcopy.__dict__.update(func.__dict__)
|
||||
funcopy.__module__ = func.__module__
|
||||
if not inPy3k:
|
||||
funcopy.func_defaults = func.func_defaults
|
||||
@ -320,12 +321,16 @@ def _setup_func(funcopy, mock):
|
||||
|
||||
def assert_called_with(*args, **kwargs):
|
||||
return mock.assert_called_with(*args, **kwargs)
|
||||
|
||||
def assert_called_once_with(*args, **kwargs):
|
||||
return mock.assert_called_once_with(*args, **kwargs)
|
||||
|
||||
def assert_has_calls(*args, **kwargs):
|
||||
return mock.assert_has_calls(*args, **kwargs)
|
||||
|
||||
def assert_any_call(*args, **kwargs):
|
||||
return mock.assert_any_call(*args, **kwargs)
|
||||
|
||||
def reset_mock():
|
||||
funcopy.method_calls = _CallList()
|
||||
funcopy.mock_calls = _CallList()
|
||||
@ -360,6 +365,7 @@ def _is_magic(name):
|
||||
|
||||
class _SentinelObject(object):
|
||||
"A unique, named, sentinel object."
|
||||
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
@ -369,6 +375,7 @@ class _SentinelObject(object):
|
||||
|
||||
class _Sentinel(object):
|
||||
"""Access attributes to return a named object, usable as a sentinel."""
|
||||
|
||||
def __init__(self):
|
||||
self._sentinels = {}
|
||||
|
||||
@ -413,11 +420,13 @@ _allowed_names = set(
|
||||
def _delegating_property(name):
|
||||
_allowed_names.add(name)
|
||||
_the_name = '_mock_' + name
|
||||
|
||||
def _get(self, name=name, _the_name=_the_name):
|
||||
sig = self._mock_delegate
|
||||
if sig is None:
|
||||
return getattr(self, _the_name)
|
||||
return getattr(sig, name)
|
||||
|
||||
def _set(self, value, name=name, _the_name=_the_name):
|
||||
sig = self._mock_delegate
|
||||
if sig is None:
|
||||
@ -428,7 +437,6 @@ def _delegating_property(name):
|
||||
return property(_get, _set)
|
||||
|
||||
|
||||
|
||||
class _CallList(list):
|
||||
|
||||
def __contains__(self, value):
|
||||
@ -440,7 +448,7 @@ class _CallList(list):
|
||||
return False
|
||||
|
||||
for i in range(0, len_self - len_value + 1):
|
||||
sub_list = self[i:i+len_value]
|
||||
sub_list = self[i:i + len_value]
|
||||
if sub_list == value:
|
||||
return True
|
||||
return False
|
||||
@ -474,15 +482,14 @@ def _check_and_set_parent(parent, value, name, new_name):
|
||||
return True
|
||||
|
||||
|
||||
|
||||
class Base(object):
|
||||
_mock_return_value = DEFAULT
|
||||
_mock_side_effect = None
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class NonCallableMock(Base):
|
||||
"""A non-callable version of `Mock`"""
|
||||
|
||||
@ -494,7 +501,6 @@ class NonCallableMock(Base):
|
||||
instance = object.__new__(new)
|
||||
return instance
|
||||
|
||||
|
||||
def __init__(
|
||||
self, spec=None, wraps=None, name=None, spec_set=None,
|
||||
parent=None, _spec_state=None, _new_name='', _new_parent=None,
|
||||
@ -535,7 +541,6 @@ class NonCallableMock(Base):
|
||||
_spec_state
|
||||
)
|
||||
|
||||
|
||||
def attach_mock(self, mock, attribute):
|
||||
"""
|
||||
Attach a mock as an attribute of this one, replacing its name and
|
||||
@ -548,7 +553,6 @@ class NonCallableMock(Base):
|
||||
|
||||
setattr(self, attribute, mock)
|
||||
|
||||
|
||||
def mock_add_spec(self, spec, spec_set=False):
|
||||
"""Add a spec to a mock. `spec` can either be an object or a
|
||||
list of strings. Only attributes on the `spec` can be fetched as
|
||||
@ -557,7 +561,6 @@ class NonCallableMock(Base):
|
||||
If `spec_set` is True then only attributes on the spec can be set."""
|
||||
self._mock_add_spec(spec, spec_set)
|
||||
|
||||
|
||||
def _mock_add_spec(self, spec, spec_set):
|
||||
_spec_class = None
|
||||
|
||||
@ -574,7 +577,6 @@ class NonCallableMock(Base):
|
||||
__dict__['_spec_set'] = spec_set
|
||||
__dict__['_mock_methods'] = spec
|
||||
|
||||
|
||||
def __get_return_value(self):
|
||||
ret = self._mock_return_value
|
||||
if self._mock_delegate is not None:
|
||||
@ -587,7 +589,6 @@ class NonCallableMock(Base):
|
||||
self.return_value = ret
|
||||
return ret
|
||||
|
||||
|
||||
def __set_return_value(self, value):
|
||||
if self._mock_delegate is not None:
|
||||
self._mock_delegate.return_value = value
|
||||
@ -599,7 +600,6 @@ class NonCallableMock(Base):
|
||||
return_value = property(__get_return_value, __set_return_value,
|
||||
__return_value_doc)
|
||||
|
||||
|
||||
@property
|
||||
def __class__(self):
|
||||
if self._spec_class is None:
|
||||
@ -612,7 +612,6 @@ class NonCallableMock(Base):
|
||||
call_args_list = _delegating_property('call_args_list')
|
||||
mock_calls = _delegating_property('mock_calls')
|
||||
|
||||
|
||||
def __get_side_effect(self):
|
||||
sig = self._mock_delegate
|
||||
if sig is None:
|
||||
@ -629,7 +628,6 @@ class NonCallableMock(Base):
|
||||
|
||||
side_effect = property(__get_side_effect, __set_side_effect)
|
||||
|
||||
|
||||
def reset_mock(self):
|
||||
"Restore the mock object to its initial state."
|
||||
self.called = False
|
||||
@ -648,7 +646,6 @@ class NonCallableMock(Base):
|
||||
if _is_instance_mock(ret) and ret is not self:
|
||||
ret.reset_mock()
|
||||
|
||||
|
||||
def configure_mock(self, **kwargs):
|
||||
"""Set attributes on the mock through keyword arguments.
|
||||
|
||||
@ -670,7 +667,6 @@ class NonCallableMock(Base):
|
||||
obj = getattr(obj, entry)
|
||||
setattr(obj, final, val)
|
||||
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name == '_mock_methods':
|
||||
raise AttributeError(name)
|
||||
@ -694,18 +690,17 @@ class NonCallableMock(Base):
|
||||
parent=self, name=name, wraps=wraps, _new_name=name,
|
||||
_new_parent=self
|
||||
)
|
||||
self._mock_children[name] = result
|
||||
self._mock_children[name] = result
|
||||
|
||||
elif isinstance(result, _SpecState):
|
||||
result = create_autospec(
|
||||
result.spec, result.spec_set, result.instance,
|
||||
result.parent, result.name
|
||||
)
|
||||
self._mock_children[name] = result
|
||||
self._mock_children[name] = result
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
_name_list = [self._mock_new_name]
|
||||
_parent = self._mock_new_parent
|
||||
@ -755,7 +750,6 @@ class NonCallableMock(Base):
|
||||
id(self)
|
||||
)
|
||||
|
||||
|
||||
def __dir__(self):
|
||||
"""Filter the output of `dir(mock)` to only useful members."""
|
||||
extras = self._mock_methods or []
|
||||
@ -769,7 +763,6 @@ class NonCallableMock(Base):
|
||||
return sorted(set(extras + from_type + from_dict +
|
||||
list(self._mock_children)))
|
||||
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
if name in _allowed_names:
|
||||
# property setters go through here
|
||||
@ -803,7 +796,6 @@ class NonCallableMock(Base):
|
||||
self._mock_children[name] = value
|
||||
return object.__setattr__(self, name, value)
|
||||
|
||||
|
||||
def __delattr__(self, name):
|
||||
if name in _all_magics and name in type(self).__dict__:
|
||||
delattr(type(self), name)
|
||||
@ -822,13 +814,10 @@ class NonCallableMock(Base):
|
||||
del self._mock_children[name]
|
||||
self._mock_children[name] = _deleted
|
||||
|
||||
|
||||
|
||||
def _format_mock_call_signature(self, args, kwargs):
|
||||
name = self._mock_name or 'mock'
|
||||
return _format_call_signature(name, args, kwargs)
|
||||
|
||||
|
||||
def _format_mock_failure_message(self, args, kwargs):
|
||||
message = 'Expected call: %s\nActual call: %s'
|
||||
expected_string = self._format_mock_call_signature(args, kwargs)
|
||||
@ -838,7 +827,6 @@ class NonCallableMock(Base):
|
||||
actual_string = self._format_mock_call_signature(*call_args)
|
||||
return message % (expected_string, actual_string)
|
||||
|
||||
|
||||
def assert_called_with(_mock_self, *args, **kwargs):
|
||||
"""assert that the mock was called with the specified arguments.
|
||||
|
||||
@ -853,7 +841,6 @@ class NonCallableMock(Base):
|
||||
msg = self._format_mock_failure_message(args, kwargs)
|
||||
raise AssertionError(msg)
|
||||
|
||||
|
||||
def assert_called_once_with(_mock_self, *args, **kwargs):
|
||||
"""assert that the mock was called exactly once and with the specified
|
||||
arguments."""
|
||||
@ -864,7 +851,6 @@ class NonCallableMock(Base):
|
||||
raise AssertionError(msg)
|
||||
return self.assert_called_with(*args, **kwargs)
|
||||
|
||||
|
||||
def assert_has_calls(self, calls, any_order=False):
|
||||
"""assert the mock has been called with the specified calls.
|
||||
The `mock_calls` list is checked for the calls.
|
||||
@ -896,7 +882,6 @@ class NonCallableMock(Base):
|
||||
'%r not all found in call list' % (tuple(not_found),)
|
||||
)
|
||||
|
||||
|
||||
def assert_any_call(self, *args, **kwargs):
|
||||
"""assert the mock has been called with the specified arguments.
|
||||
|
||||
@ -910,7 +895,6 @@ class NonCallableMock(Base):
|
||||
'%s call not found' % expected_string
|
||||
)
|
||||
|
||||
|
||||
def _get_child_mock(self, **kw):
|
||||
"""Create the child mocks for attributes and return value.
|
||||
By default child mocks will be the same type as the parent.
|
||||
@ -923,14 +907,13 @@ class NonCallableMock(Base):
|
||||
if not issubclass(_type, CallableMixin):
|
||||
if issubclass(_type, NonCallableMagicMock):
|
||||
klass = MagicMock
|
||||
elif issubclass(_type, NonCallableMock) :
|
||||
elif issubclass(_type, NonCallableMock):
|
||||
klass = Mock
|
||||
else:
|
||||
klass = _type.__mro__[1]
|
||||
return klass(**kw)
|
||||
|
||||
|
||||
|
||||
def _try_iter(obj):
|
||||
if obj is None:
|
||||
return obj
|
||||
@ -946,7 +929,6 @@ def _try_iter(obj):
|
||||
return obj
|
||||
|
||||
|
||||
|
||||
class CallableMixin(Base):
|
||||
|
||||
def __init__(self, spec=None, side_effect=None, return_value=DEFAULT,
|
||||
@ -961,19 +943,16 @@ class CallableMixin(Base):
|
||||
|
||||
self.side_effect = side_effect
|
||||
|
||||
|
||||
def _mock_check_sig(self, *args, **kwargs):
|
||||
# stub method that can be replaced with one with a specific signature
|
||||
pass
|
||||
|
||||
|
||||
def __call__(_mock_self, *args, **kwargs):
|
||||
# can't use self in-case a function / method we are mocking uses self
|
||||
# in the signature
|
||||
_mock_self._mock_check_sig(*args, **kwargs)
|
||||
return _mock_self._mock_call(*args, **kwargs)
|
||||
|
||||
|
||||
def _mock_call(_mock_self, *args, **kwargs):
|
||||
self = _mock_self
|
||||
self.called = True
|
||||
@ -1046,7 +1025,6 @@ class CallableMixin(Base):
|
||||
return ret_val
|
||||
|
||||
|
||||
|
||||
class Mock(CallableMixin, NonCallableMock):
|
||||
"""
|
||||
Create a new `Mock` object. `Mock` takes several optional arguments
|
||||
@ -1102,7 +1080,6 @@ class Mock(CallableMixin, NonCallableMock):
|
||||
"""
|
||||
|
||||
|
||||
|
||||
def _dot_lookup(thing, comp, import_path):
|
||||
try:
|
||||
return getattr(thing, comp)
|
||||
@ -1158,7 +1135,6 @@ class _patch(object):
|
||||
self.kwargs = kwargs
|
||||
self.additional_patchers = []
|
||||
|
||||
|
||||
def copy(self):
|
||||
patcher = _patch(
|
||||
self.getter, self.attribute, self.new, self.spec,
|
||||
@ -1171,13 +1147,11 @@ class _patch(object):
|
||||
]
|
||||
return patcher
|
||||
|
||||
|
||||
def __call__(self, func):
|
||||
if isinstance(func, ClassTypes):
|
||||
return self.decorate_class(func)
|
||||
return self.decorate_callable(func)
|
||||
|
||||
|
||||
def decorate_class(self, klass):
|
||||
for attr in dir(klass):
|
||||
if not attr.startswith(patch.TEST_PREFIX):
|
||||
@ -1191,7 +1165,6 @@ class _patch(object):
|
||||
setattr(klass, attr, patcher(attr_value))
|
||||
return klass
|
||||
|
||||
|
||||
def decorate_callable(self, func):
|
||||
if hasattr(func, 'patchings'):
|
||||
func.patchings.append(self)
|
||||
@ -1241,7 +1214,6 @@ class _patch(object):
|
||||
)
|
||||
return patched
|
||||
|
||||
|
||||
def get_original(self):
|
||||
target = self.getter()
|
||||
name = self.attribute
|
||||
@ -1262,7 +1234,6 @@ class _patch(object):
|
||||
)
|
||||
return original, local
|
||||
|
||||
|
||||
def __enter__(self):
|
||||
"""Perform the patch."""
|
||||
new, spec, spec_set = self.new, self.spec, self.spec_set
|
||||
@ -1379,7 +1350,7 @@ class _patch(object):
|
||||
if self.attribute_name is not None:
|
||||
extra_args = {}
|
||||
if self.new is DEFAULT:
|
||||
extra_args[self.attribute_name] = new
|
||||
extra_args[self.attribute_name] = new
|
||||
for patching in self.additional_patchers:
|
||||
arg = patching.__enter__()
|
||||
if patching.new is DEFAULT:
|
||||
@ -1388,7 +1359,6 @@ class _patch(object):
|
||||
|
||||
return new
|
||||
|
||||
|
||||
def __exit__(self, *exc_info):
|
||||
"""Undo the patch."""
|
||||
if not _is_started(self):
|
||||
@ -1409,21 +1379,18 @@ class _patch(object):
|
||||
if _is_started(patcher):
|
||||
patcher.__exit__(*exc_info)
|
||||
|
||||
|
||||
def start(self):
|
||||
"""Activate a patch, returning any created mock."""
|
||||
result = self.__enter__()
|
||||
self._active_patches.add(self)
|
||||
return result
|
||||
|
||||
|
||||
def stop(self):
|
||||
"""Stop an active patch."""
|
||||
self._active_patches.discard(self)
|
||||
return self.__exit__()
|
||||
|
||||
|
||||
|
||||
def _get_target(target):
|
||||
try:
|
||||
target, attribute = target.rsplit('.', 1)
|
||||
@ -1626,10 +1593,10 @@ class _patch_dict(object):
|
||||
self.clear = clear
|
||||
self._original = None
|
||||
|
||||
|
||||
def __call__(self, f):
|
||||
if isinstance(f, ClassTypes):
|
||||
return self.decorate_class(f)
|
||||
|
||||
@wraps(f)
|
||||
def _inner(*args, **kw):
|
||||
self._patch_dict()
|
||||
@ -1640,7 +1607,6 @@ class _patch_dict(object):
|
||||
|
||||
return _inner
|
||||
|
||||
|
||||
def decorate_class(self, klass):
|
||||
for attr in dir(klass):
|
||||
attr_value = getattr(klass, attr)
|
||||
@ -1651,12 +1617,10 @@ class _patch_dict(object):
|
||||
setattr(klass, attr, decorated)
|
||||
return klass
|
||||
|
||||
|
||||
def __enter__(self):
|
||||
"""Patch the dict."""
|
||||
self._patch_dict()
|
||||
|
||||
|
||||
def _patch_dict(self):
|
||||
values = self.values
|
||||
in_dict = self.in_dict
|
||||
@ -1682,7 +1646,6 @@ class _patch_dict(object):
|
||||
for key in values:
|
||||
in_dict[key] = values[key]
|
||||
|
||||
|
||||
def _unpatch_dict(self):
|
||||
in_dict = self.in_dict
|
||||
original = self._original
|
||||
@ -1695,7 +1658,6 @@ class _patch_dict(object):
|
||||
for key in original:
|
||||
in_dict[key] = original[key]
|
||||
|
||||
|
||||
def __exit__(self, *args):
|
||||
"""Unpatch the dict."""
|
||||
self._unpatch_dict()
|
||||
@ -1761,6 +1723,7 @@ _non_defaults = set('__%s__' % method for method in [
|
||||
|
||||
def _get_method(name, func):
|
||||
"Turns a callable object (like a mock) into a real function"
|
||||
|
||||
def method(self, *args, **kw):
|
||||
return func(self, *args, **kw)
|
||||
method.__name__ = name
|
||||
@ -1816,6 +1779,7 @@ def _get_eq(self):
|
||||
return self is other
|
||||
return __eq__
|
||||
|
||||
|
||||
def _get_ne(self):
|
||||
def __ne__(other):
|
||||
if self.__ne__._mock_return_value is not DEFAULT:
|
||||
@ -1823,6 +1787,7 @@ def _get_ne(self):
|
||||
return self is not other
|
||||
return __ne__
|
||||
|
||||
|
||||
def _get_iter(self):
|
||||
def __iter__():
|
||||
ret_val = self.__iter__._mock_return_value
|
||||
@ -1840,7 +1805,6 @@ _side_effect_methods = {
|
||||
}
|
||||
|
||||
|
||||
|
||||
def _set_return_value(mock, method, name):
|
||||
fixed = _return_values.get(name, DEFAULT)
|
||||
if fixed is not DEFAULT:
|
||||
@ -1863,13 +1827,11 @@ def _set_return_value(mock, method, name):
|
||||
method.side_effect = side_effector(mock)
|
||||
|
||||
|
||||
|
||||
class MagicMixin(object):
|
||||
def __init__(self, *args, **kw):
|
||||
_super(MagicMixin, self).__init__(*args, **kw)
|
||||
self._mock_set_magics()
|
||||
|
||||
|
||||
def _mock_set_magics(self):
|
||||
these_magics = _magics
|
||||
|
||||
@ -1892,9 +1854,9 @@ class MagicMixin(object):
|
||||
setattr(_type, entry, MagicProxy(entry, self))
|
||||
|
||||
|
||||
|
||||
class NonCallableMagicMock(MagicMixin, NonCallableMock):
|
||||
"""A version of `MagicMock` that isn't callable."""
|
||||
|
||||
def mock_add_spec(self, spec, spec_set=False):
|
||||
"""Add a spec to a mock. `spec` can either be an object or a
|
||||
list of strings. Only attributes on the `spec` can be fetched as
|
||||
@ -1905,7 +1867,6 @@ class NonCallableMagicMock(MagicMixin, NonCallableMock):
|
||||
self._mock_set_magics()
|
||||
|
||||
|
||||
|
||||
class MagicMock(MagicMixin, Mock):
|
||||
"""
|
||||
MagicMock is a subclass of Mock with default implementations
|
||||
@ -1917,6 +1878,7 @@ class MagicMock(MagicMixin, Mock):
|
||||
|
||||
Attributes and the return value of a `MagicMock` will also be `MagicMocks`.
|
||||
"""
|
||||
|
||||
def mock_add_spec(self, spec, spec_set=False):
|
||||
"""Add a spec to a mock. `spec` can either be an object or a
|
||||
list of strings. Only attributes on the `spec` can be fetched as
|
||||
@ -1927,7 +1889,6 @@ class MagicMock(MagicMixin, Mock):
|
||||
self._mock_set_magics()
|
||||
|
||||
|
||||
|
||||
class MagicProxy(object):
|
||||
def __init__(self, name, parent):
|
||||
self.name = name
|
||||
@ -1950,7 +1911,6 @@ class MagicProxy(object):
|
||||
return self.create_mock()
|
||||
|
||||
|
||||
|
||||
class _ANY(object):
|
||||
"A helper object that compares equal to everything."
|
||||
|
||||
@ -1966,7 +1926,6 @@ class _ANY(object):
|
||||
ANY = _ANY()
|
||||
|
||||
|
||||
|
||||
def _format_call_signature(name, args, kwargs):
|
||||
message = '%s(%%s)' % name
|
||||
formatted_args = ''
|
||||
@ -1984,7 +1943,6 @@ def _format_call_signature(name, args, kwargs):
|
||||
return message % formatted_args
|
||||
|
||||
|
||||
|
||||
class _Call(tuple):
|
||||
"""
|
||||
A tuple for holding the results of a call to a mock, either in the form
|
||||
@ -2036,14 +1994,12 @@ class _Call(tuple):
|
||||
|
||||
return tuple.__new__(cls, (name, args, kwargs))
|
||||
|
||||
|
||||
def __init__(self, value=(), name=None, parent=None, two=False,
|
||||
from_kall=True):
|
||||
self.name = name
|
||||
self.parent = parent
|
||||
self.from_kall = from_kall
|
||||
|
||||
|
||||
def __eq__(self, other):
|
||||
if other is ANY:
|
||||
return True
|
||||
@ -2093,11 +2049,9 @@ class _Call(tuple):
|
||||
# this order is important for ANY to work!
|
||||
return (other_args, other_kwargs) == (self_args, self_kwargs)
|
||||
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self.__eq__(other)
|
||||
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
if self.name is None:
|
||||
return _Call(('', args, kwargs), name='()')
|
||||
@ -2105,14 +2059,12 @@ class _Call(tuple):
|
||||
name = self.name + '()'
|
||||
return _Call((self.name, args, kwargs), name=name, parent=self)
|
||||
|
||||
|
||||
def __getattr__(self, attr):
|
||||
if self.name is None:
|
||||
return _Call(name=attr, from_kall=False)
|
||||
name = '%s.%s' % (self.name, attr)
|
||||
return _Call(name=name, parent=self, from_kall=False)
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
if not self.from_kall:
|
||||
name = self.name or 'call'
|
||||
@ -2133,7 +2085,6 @@ class _Call(tuple):
|
||||
name = 'call%s' % name
|
||||
return _format_call_signature(name, args, kwargs)
|
||||
|
||||
|
||||
def call_list(self):
|
||||
"""For a call object that represents multiple calls, `call_list`
|
||||
returns a list of all the intermediate calls as well as the
|
||||
@ -2150,7 +2101,6 @@ class _Call(tuple):
|
||||
call = _Call(from_kall=False)
|
||||
|
||||
|
||||
|
||||
def create_autospec(spec, spec_set=False, instance=False, _parent=None,
|
||||
_name=None, **kwargs):
|
||||
"""Create a mock object using another object as a spec. Attributes on the
|
||||
@ -2377,10 +2327,12 @@ class PropertyMock(Mock):
|
||||
Fetching a `PropertyMock` instance from an object calls the mock, with
|
||||
no args. Setting it calls the mock with the value being set.
|
||||
"""
|
||||
|
||||
def _get_child_mock(self, **kwargs):
|
||||
return MagicMock(**kwargs)
|
||||
|
||||
def __get__(self, obj, obj_type):
|
||||
return self()
|
||||
|
||||
def __set__(self, obj, val):
|
||||
self(val)
|
||||
|
@ -70,16 +70,16 @@ class TestMySQLdb(LimitedTestCase):
|
||||
self.drop_db()
|
||||
except Exception:
|
||||
pass
|
||||
dbname = 'test_%d_%d' % (os.getpid(), int(time.time()*1000))
|
||||
dbname = 'test_%d_%d' % (os.getpid(), int(time.time() * 1000))
|
||||
db = MySQLdb.connect(**auth).cursor()
|
||||
db.execute("create database "+dbname)
|
||||
db.execute("create database " + dbname)
|
||||
db.close()
|
||||
self._auth['db'] = dbname
|
||||
del db
|
||||
|
||||
def drop_db(self):
|
||||
db = MySQLdb.connect(**self._auth).cursor()
|
||||
db.execute("drop database "+self._auth['db'])
|
||||
db.execute("drop database " + self._auth['db'])
|
||||
db.close()
|
||||
del db
|
||||
|
||||
|
@ -8,6 +8,7 @@ except ImportError:
|
||||
import re
|
||||
import glob
|
||||
|
||||
|
||||
def parse_stdout(s):
|
||||
argv = re.search('^===ARGV=(.*?)$', s, re.M).group(1)
|
||||
argv = argv.split()
|
||||
@ -16,11 +17,11 @@ def parse_stdout(s):
|
||||
hub = None
|
||||
reactor = None
|
||||
while argv:
|
||||
if argv[0]=='--hub':
|
||||
if argv[0] == '--hub':
|
||||
hub = argv[1]
|
||||
del argv[0]
|
||||
del argv[0]
|
||||
elif argv[0]=='--reactor':
|
||||
elif argv[0] == '--reactor':
|
||||
reactor = argv[1]
|
||||
del argv[0]
|
||||
del argv[0]
|
||||
@ -29,11 +30,12 @@ def parse_stdout(s):
|
||||
if reactor is not None:
|
||||
hub += '/%s' % reactor
|
||||
return testname, hub
|
||||
|
||||
|
||||
unittest_delim = '----------------------------------------------------------------------'
|
||||
|
||||
|
||||
def parse_unittest_output(s):
|
||||
s = s[s.rindex(unittest_delim)+len(unittest_delim):]
|
||||
s = s[s.rindex(unittest_delim) + len(unittest_delim):]
|
||||
num = int(re.search('^Ran (\d+) test.*?$', s, re.M).group(1))
|
||||
ok = re.search('^OK$', s, re.M)
|
||||
error, fail, timeout = 0, 0, 0
|
||||
@ -52,6 +54,7 @@ def parse_unittest_output(s):
|
||||
timeout = int(timeout_match.group(1))
|
||||
return num, error, fail, timeout
|
||||
|
||||
|
||||
def main(db):
|
||||
c = sqlite3.connect(db)
|
||||
c.execute('''create table if not exists parsed_command_record
|
||||
@ -68,7 +71,7 @@ def main(db):
|
||||
c.commit()
|
||||
|
||||
parse_error = 0
|
||||
|
||||
|
||||
SQL = ('select command_record.id, command, stdout, exitcode from command_record '
|
||||
'where not exists (select * from parsed_command_record where '
|
||||
'parsed_command_record.id=command_record.id)')
|
||||
@ -80,11 +83,11 @@ def main(db):
|
||||
runs, errors, fails, timeouts = parse_unittest_output(stdout)
|
||||
else:
|
||||
if exitcode == 0:
|
||||
runs, errors, fails, timeouts = 1,0,0,0
|
||||
runs, errors, fails, timeouts = 1, 0, 0, 0
|
||||
if exitcode == 7:
|
||||
runs, errors, fails, timeouts = 0,0,0,1
|
||||
runs, errors, fails, timeouts = 0, 0, 0, 1
|
||||
elif exitcode:
|
||||
runs, errors, fails, timeouts = 1,1,0,0
|
||||
runs, errors, fails, timeouts = 1, 1, 0, 0
|
||||
except Exception:
|
||||
parse_error += 1
|
||||
sys.stderr.write('Failed to parse id=%s\n' % id)
|
||||
@ -98,7 +101,7 @@ def main(db):
|
||||
(id, testname, hub, runs, errors, fails, timeouts))
|
||||
c.commit()
|
||||
|
||||
if __name__=='__main__':
|
||||
if __name__ == '__main__':
|
||||
if not sys.argv[1:]:
|
||||
latest_db = sorted(glob.glob('results.*.db'), key=lambda f: os.stat(f).st_mtime)[-1]
|
||||
print(latest_db)
|
||||
|
@ -399,7 +399,7 @@ print(process.wait())"""
|
||||
self.write_to_tempfile("newmod", new_mod)
|
||||
output, lines = self.launch_subprocess('newmod')
|
||||
self.assertEqual(len(lines), 2, "\n".join(lines))
|
||||
self.assertEqual('1', lines[0], repr(output))
|
||||
self.assertEqual('1', lines[0], repr(output))
|
||||
|
||||
|
||||
class GreenThreadWrapper(ProcessBase):
|
||||
|
@ -22,12 +22,12 @@ class TestIntPool(TestCase):
|
||||
# If you do a get, you should ALWAYS do a put, probably like this:
|
||||
# try:
|
||||
# thing = self.pool.get()
|
||||
# # do stuff
|
||||
# do stuff
|
||||
# finally:
|
||||
# self.pool.put(thing)
|
||||
|
||||
# with self.pool.some_api_name() as thing:
|
||||
# # do stuff
|
||||
# do stuff
|
||||
self.assertEqual(self.pool.get(), 1)
|
||||
self.assertEqual(self.pool.get(), 2)
|
||||
self.assertEqual(self.pool.get(), 3)
|
||||
@ -42,6 +42,7 @@ class TestIntPool(TestCase):
|
||||
|
||||
def test_exhaustion(self):
|
||||
waiter = Queue(0)
|
||||
|
||||
def consumer():
|
||||
gotten = None
|
||||
try:
|
||||
@ -66,6 +67,7 @@ class TestIntPool(TestCase):
|
||||
|
||||
def test_blocks_on_pool(self):
|
||||
waiter = Queue(0)
|
||||
|
||||
def greedy():
|
||||
self.pool.get()
|
||||
self.pool.get()
|
||||
@ -83,13 +85,13 @@ class TestIntPool(TestCase):
|
||||
# no one should be waiting yet.
|
||||
self.assertEqual(self.pool.waiting(), 0)
|
||||
|
||||
## Wait for greedy
|
||||
# Wait for greedy
|
||||
eventlet.sleep(0)
|
||||
|
||||
## Greedy should be blocking on the last get
|
||||
# Greedy should be blocking on the last get
|
||||
self.assertEqual(self.pool.waiting(), 1)
|
||||
|
||||
## Send will never be called, so balance should be 0.
|
||||
# Send will never be called, so balance should be 0.
|
||||
self.assertFalse(not waiter.full())
|
||||
|
||||
eventlet.kill(killable)
|
||||
@ -110,6 +112,7 @@ class TestIntPool(TestCase):
|
||||
self.pool = IntPool(min_size=0, max_size=size)
|
||||
queue = Queue()
|
||||
results = []
|
||||
|
||||
def just_put(pool_item, index):
|
||||
self.pool.put(pool_item)
|
||||
queue.put(index)
|
||||
@ -117,7 +120,7 @@ class TestIntPool(TestCase):
|
||||
pool_item = self.pool.get()
|
||||
eventlet.spawn(just_put, pool_item, index)
|
||||
|
||||
for _ in six.moves.range(size+1):
|
||||
for _ in six.moves.range(size + 1):
|
||||
x = queue.get()
|
||||
results.append(x)
|
||||
self.assertEqual(sorted(results), list(six.moves.range(size + 1)))
|
||||
@ -142,6 +145,7 @@ class TestIntPool(TestCase):
|
||||
|
||||
def test_create_contention(self):
|
||||
creates = [0]
|
||||
|
||||
def sleep_create():
|
||||
creates[0] += 1
|
||||
eventlet.sleep()
|
||||
@ -163,28 +167,31 @@ class TestIntPool(TestCase):
|
||||
|
||||
class TestAbstract(TestCase):
|
||||
mode = 'static'
|
||||
|
||||
def test_abstract(self):
|
||||
## Going for 100% coverage here
|
||||
## A Pool cannot be used without overriding create()
|
||||
# Going for 100% coverage here
|
||||
# A Pool cannot be used without overriding create()
|
||||
pool = pools.Pool()
|
||||
self.assertRaises(NotImplementedError, pool.get)
|
||||
|
||||
|
||||
class TestIntPool2(TestCase):
|
||||
mode = 'static'
|
||||
|
||||
def setUp(self):
|
||||
self.pool = IntPool(min_size=3, max_size=3)
|
||||
|
||||
def test_something(self):
|
||||
self.assertEqual(len(self.pool.free_items), 3)
|
||||
## Cover the clause in get where we get from the free list instead of creating
|
||||
## an item on get
|
||||
# Cover the clause in get where we get from the free list instead of creating
|
||||
# an item on get
|
||||
gotten = self.pool.get()
|
||||
self.assertEqual(gotten, 1)
|
||||
|
||||
|
||||
class TestOrderAsStack(TestCase):
|
||||
mode = 'static'
|
||||
|
||||
def setUp(self):
|
||||
self.pool = IntPool(max_size=3, order_as_stack=True)
|
||||
|
||||
@ -204,6 +211,7 @@ class RaisePool(pools.Pool):
|
||||
|
||||
class TestCreateRaises(TestCase):
|
||||
mode = 'static'
|
||||
|
||||
def setUp(self):
|
||||
self.pool = RaisePool(max_size=3)
|
||||
|
||||
@ -222,4 +230,3 @@ class TestTookTooLong(Exception):
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
@ -6,6 +6,7 @@ warnings.simplefilter('ignore', DeprecationWarning)
|
||||
from eventlet import processes, api
|
||||
warnings.simplefilter('default', DeprecationWarning)
|
||||
|
||||
|
||||
class TestEchoPool(LimitedTestCase):
|
||||
def setUp(self):
|
||||
super(TestEchoPool, self).setUp()
|
||||
|
@ -1,6 +1,7 @@
|
||||
from tests import LimitedTestCase, main
|
||||
import eventlet
|
||||
from eventlet import event
|
||||
from eventlet import event, hubs, queue
|
||||
from tests import LimitedTestCase, main
|
||||
|
||||
|
||||
def do_bail(q):
|
||||
eventlet.Timeout(0, RuntimeError())
|
||||
@ -10,6 +11,7 @@ def do_bail(q):
|
||||
except RuntimeError:
|
||||
return 'timed out'
|
||||
|
||||
|
||||
class TestQueue(LimitedTestCase):
|
||||
def test_send_first(self):
|
||||
q = eventlet.Queue()
|
||||
@ -18,6 +20,7 @@ class TestQueue(LimitedTestCase):
|
||||
|
||||
def test_send_last(self):
|
||||
q = eventlet.Queue()
|
||||
|
||||
def waiter(q):
|
||||
self.assertEqual(q.get(), 'hi2')
|
||||
|
||||
@ -51,6 +54,7 @@ class TestQueue(LimitedTestCase):
|
||||
|
||||
def test_zero_max_size(self):
|
||||
q = eventlet.Queue(0)
|
||||
|
||||
def sender(evt, q):
|
||||
q.put('hi')
|
||||
evt.send('done')
|
||||
@ -64,12 +68,13 @@ class TestQueue(LimitedTestCase):
|
||||
eventlet.sleep(0)
|
||||
assert not evt.ready()
|
||||
gt2 = eventlet.spawn(receiver, q)
|
||||
self.assertEqual(gt2.wait(),'hi')
|
||||
self.assertEqual(evt.wait(),'done')
|
||||
self.assertEqual(gt2.wait(), 'hi')
|
||||
self.assertEqual(evt.wait(), 'done')
|
||||
gt.wait()
|
||||
|
||||
def test_resize_up(self):
|
||||
q = eventlet.Queue(0)
|
||||
|
||||
def sender(evt, q):
|
||||
q.put('hi')
|
||||
evt.send('done')
|
||||
@ -84,7 +89,6 @@ class TestQueue(LimitedTestCase):
|
||||
gt.wait()
|
||||
|
||||
def test_resize_down(self):
|
||||
size = 5
|
||||
q = eventlet.Queue(5)
|
||||
|
||||
for i in range(5):
|
||||
@ -97,6 +101,7 @@ class TestQueue(LimitedTestCase):
|
||||
|
||||
def test_resize_to_Unlimited(self):
|
||||
q = eventlet.Queue(0)
|
||||
|
||||
def sender(evt, q):
|
||||
q.put('hi')
|
||||
evt.send('done')
|
||||
@ -115,10 +120,9 @@ class TestQueue(LimitedTestCase):
|
||||
q = eventlet.Queue()
|
||||
|
||||
sendings = ['1', '2', '3', '4']
|
||||
gts = [eventlet.spawn(q.get)
|
||||
for x in sendings]
|
||||
gts = [eventlet.spawn(q.get) for x in sendings]
|
||||
|
||||
eventlet.sleep(0.01) # get 'em all waiting
|
||||
eventlet.sleep(0.01) # get 'em all waiting
|
||||
|
||||
q.put(sendings[0])
|
||||
q.put(sendings[1])
|
||||
@ -180,11 +184,12 @@ class TestQueue(LimitedTestCase):
|
||||
def test_channel_send(self):
|
||||
channel = eventlet.Queue(0)
|
||||
events = []
|
||||
|
||||
def another_greenlet():
|
||||
events.append(channel.get())
|
||||
events.append(channel.get())
|
||||
|
||||
gt = eventlet.spawn(another_greenlet)
|
||||
eventlet.spawn(another_greenlet)
|
||||
|
||||
events.append('sending')
|
||||
channel.put('hello')
|
||||
@ -194,7 +199,6 @@ class TestQueue(LimitedTestCase):
|
||||
|
||||
self.assertEqual(['sending', 'hello', 'sent hello', 'world', 'sent world'], events)
|
||||
|
||||
|
||||
def test_channel_wait(self):
|
||||
channel = eventlet.Queue(0)
|
||||
events = []
|
||||
@ -206,7 +210,7 @@ class TestQueue(LimitedTestCase):
|
||||
channel.put('world')
|
||||
events.append('sent world')
|
||||
|
||||
gt = eventlet.spawn(another_greenlet)
|
||||
eventlet.spawn(another_greenlet)
|
||||
|
||||
events.append('waiting')
|
||||
events.append(channel.get())
|
||||
@ -233,16 +237,14 @@ class TestQueue(LimitedTestCase):
|
||||
self.assertEqual(c.getting(), 0)
|
||||
# NOTE: we don't guarantee that waiters are served in order
|
||||
results = sorted([w1.wait(), w2.wait(), w3.wait()])
|
||||
self.assertEqual(results, [1,2,3])
|
||||
self.assertEqual(results, [1, 2, 3])
|
||||
|
||||
def test_channel_sender_timing_out(self):
|
||||
from eventlet import queue
|
||||
c = eventlet.Queue(0)
|
||||
self.assertRaises(queue.Full, c.put, "hi", timeout=0.001)
|
||||
self.assertRaises(queue.Empty, c.get_nowait)
|
||||
|
||||
def test_task_done(self):
|
||||
from eventlet import queue, debug
|
||||
channel = queue.Queue(0)
|
||||
X = object()
|
||||
gt = eventlet.spawn(channel.put, X)
|
||||
@ -267,7 +269,6 @@ def store_result(result, func, *args):
|
||||
|
||||
class TestNoWait(LimitedTestCase):
|
||||
def test_put_nowait_simple(self):
|
||||
from eventlet import hubs,queue
|
||||
hub = hubs.get_hub()
|
||||
result = []
|
||||
q = eventlet.Queue(1)
|
||||
@ -275,12 +276,11 @@ class TestNoWait(LimitedTestCase):
|
||||
hub.schedule_call_global(0, store_result, result, q.put_nowait, 3)
|
||||
eventlet.sleep(0)
|
||||
eventlet.sleep(0)
|
||||
assert len(result)==2, result
|
||||
assert result[0]==None, result
|
||||
assert len(result) == 2, result
|
||||
assert result[0] is None, result
|
||||
assert isinstance(result[1], queue.Full), result
|
||||
|
||||
def test_get_nowait_simple(self):
|
||||
from eventlet import hubs,queue
|
||||
hub = hubs.get_hub()
|
||||
result = []
|
||||
q = queue.Queue(1)
|
||||
@ -288,13 +288,12 @@ class TestNoWait(LimitedTestCase):
|
||||
hub.schedule_call_global(0, store_result, result, q.get_nowait)
|
||||
hub.schedule_call_global(0, store_result, result, q.get_nowait)
|
||||
eventlet.sleep(0)
|
||||
assert len(result)==2, result
|
||||
assert result[0]==4, result
|
||||
assert len(result) == 2, result
|
||||
assert result[0] == 4, result
|
||||
assert isinstance(result[1], queue.Empty), result
|
||||
|
||||
# get_nowait must work from the mainloop
|
||||
def test_get_nowait_unlock(self):
|
||||
from eventlet import hubs,queue
|
||||
hub = hubs.get_hub()
|
||||
result = []
|
||||
q = queue.Queue(0)
|
||||
@ -310,17 +309,16 @@ class TestNoWait(LimitedTestCase):
|
||||
assert q.full(), q
|
||||
assert result == [5], result
|
||||
# TODO add ready to greenthread
|
||||
#assert p.ready(), p
|
||||
# assert p.ready(), p
|
||||
assert p.dead, p
|
||||
assert q.empty(), q
|
||||
|
||||
# put_nowait must work from the mainloop
|
||||
def test_put_nowait_unlock(self):
|
||||
from eventlet import hubs,queue
|
||||
hub = hubs.get_hub()
|
||||
result = []
|
||||
q = queue.Queue(0)
|
||||
p = eventlet.spawn(q.get)
|
||||
eventlet.spawn(q.get)
|
||||
assert q.empty(), q
|
||||
assert q.full(), q
|
||||
eventlet.sleep(0)
|
||||
@ -328,7 +326,7 @@ class TestNoWait(LimitedTestCase):
|
||||
assert q.full(), q
|
||||
hub.schedule_call_global(0, store_result, result, q.put_nowait, 10)
|
||||
# TODO ready method on greenthread
|
||||
#assert not p.ready(), p
|
||||
# assert not p.ready(), p
|
||||
eventlet.sleep(0)
|
||||
assert result == [None], result
|
||||
# TODO ready method
|
||||
@ -337,5 +335,5 @@ class TestNoWait(LimitedTestCase):
|
||||
assert q.empty(), q
|
||||
|
||||
|
||||
if __name__=='__main__':
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
@ -6,6 +6,7 @@ Many of these tests make connections to external servers, and all.py tries to sk
|
||||
from eventlet import debug
|
||||
debug.hub_prevent_multiple_readers(False)
|
||||
|
||||
|
||||
def restart_hub():
|
||||
from eventlet import hubs
|
||||
hub = hubs.get_hub()
|
||||
@ -15,6 +16,7 @@ def restart_hub():
|
||||
hub.abort()
|
||||
hubs.use_hub(hub_shortname)
|
||||
|
||||
|
||||
def assimilate_patched(name):
|
||||
try:
|
||||
modobj = __import__(name, globals(), locals(), ['test_main'])
|
||||
@ -26,6 +28,7 @@ def assimilate_patched(name):
|
||||
method_name = name + "_test_main"
|
||||
try:
|
||||
test_method = modobj.test_main
|
||||
|
||||
def test_main():
|
||||
restart_hub()
|
||||
test_method()
|
||||
@ -34,7 +37,7 @@ def assimilate_patched(name):
|
||||
test_main.__name__ = name + '.test_main'
|
||||
except AttributeError:
|
||||
print("No test_main for %s, assuming it tests on import" % name)
|
||||
|
||||
|
||||
import all_modules
|
||||
|
||||
for m in all_modules.get_modules():
|
||||
|
@ -10,20 +10,20 @@ def get_modules():
|
||||
'test_queue',
|
||||
'test_socket_ssl',
|
||||
'test_socketserver',
|
||||
# 'test_subprocess',
|
||||
# 'test_subprocess',
|
||||
'test_thread',
|
||||
'test_threading',
|
||||
'test_threading_local',
|
||||
'test_urllib',
|
||||
'test_urllib2_localnet']
|
||||
|
||||
|
||||
network_modules = [
|
||||
'test_httpservers',
|
||||
'test_socket',
|
||||
'test_ssl',
|
||||
'test_timeout',
|
||||
'test_urllib2']
|
||||
|
||||
|
||||
# quick and dirty way of testing whether we can access
|
||||
# remote hosts; any tests that try internet connections
|
||||
# will fail if we cannot
|
||||
@ -36,6 +36,5 @@ def get_modules():
|
||||
test_modules = test_modules + network_modules
|
||||
except socket.error as e:
|
||||
print("Skipping network tests")
|
||||
|
||||
|
||||
return test_modules
|
||||
|
||||
|
@ -3,6 +3,7 @@ eventlet.sleep(0)
|
||||
from eventlet import patcher
|
||||
patcher.monkey_patch()
|
||||
|
||||
|
||||
def assimilate_real(name):
|
||||
print("Assimilating", name)
|
||||
try:
|
||||
|
@ -1,9 +1,10 @@
|
||||
from eventlet import patcher
|
||||
from eventlet.green import SimpleHTTPServer
|
||||
|
||||
patcher.inject('test.test_SimpleHTTPServer',
|
||||
patcher.inject(
|
||||
'test.test_SimpleHTTPServer',
|
||||
globals(),
|
||||
('SimpleHTTPServer', SimpleHTTPServer))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_main()
|
||||
test_main()
|
||||
|
@ -6,7 +6,8 @@ from eventlet.green import thread
|
||||
from eventlet.green import threading
|
||||
from eventlet.green import time
|
||||
|
||||
patcher.inject("test.test_asynchat",
|
||||
patcher.inject(
|
||||
"test.test_asynchat",
|
||||
globals(),
|
||||
('asyncore', asyncore),
|
||||
('asynchat', asynchat),
|
||||
@ -14,6 +15,6 @@ patcher.inject("test.test_asynchat",
|
||||
('thread', thread),
|
||||
('threading', threading),
|
||||
('time', time))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_main()
|
||||
test_main()
|
||||
|
@ -7,6 +7,7 @@ from eventlet.green import time
|
||||
|
||||
patcher.inject("test.test_asyncore", globals())
|
||||
|
||||
|
||||
def new_closeall_check(self, usedefault):
|
||||
# Check that close_all() closes everything in a given map
|
||||
|
||||
@ -38,7 +39,7 @@ def new_closeall_check(self, usedefault):
|
||||
|
||||
for c in l:
|
||||
self.assertEqual(c.socket.closed, True)
|
||||
|
||||
|
||||
HelperFunctionTests.closeall_check = new_closeall_check
|
||||
|
||||
try:
|
||||
|
@ -11,6 +11,6 @@ try:
|
||||
TestTLS_FTPClass.test_data_connection = lambda *a, **kw: None
|
||||
except (AttributeError, NameError):
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_main()
|
||||
|
@ -2,10 +2,11 @@ from eventlet import patcher
|
||||
from eventlet.green import httplib
|
||||
from eventlet.green import socket
|
||||
|
||||
patcher.inject('test.test_httplib',
|
||||
patcher.inject(
|
||||
'test.test_httplib',
|
||||
globals(),
|
||||
('httplib', httplib),
|
||||
('socket', socket))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_main()
|
||||
test_main()
|
||||
|
@ -7,7 +7,8 @@ from eventlet.green import urllib
|
||||
from eventlet.green import httplib
|
||||
from eventlet.green import threading
|
||||
|
||||
patcher.inject('test.test_httpservers',
|
||||
patcher.inject(
|
||||
'test.test_httpservers',
|
||||
globals(),
|
||||
('BaseHTTPServer', BaseHTTPServer),
|
||||
('SimpleHTTPServer', SimpleHTTPServer),
|
||||
|
@ -1,7 +1,8 @@
|
||||
from eventlet import patcher
|
||||
from eventlet.green import os
|
||||
|
||||
patcher.inject('test.test_os',
|
||||
patcher.inject(
|
||||
'test.test_os',
|
||||
globals(),
|
||||
('os', os))
|
||||
|
||||
|
@ -3,7 +3,8 @@ from eventlet.green import Queue
|
||||
from eventlet.green import threading
|
||||
from eventlet.green import time
|
||||
|
||||
patcher.inject('test.test_queue',
|
||||
patcher.inject(
|
||||
'test.test_queue',
|
||||
globals(),
|
||||
('Queue', Queue),
|
||||
('threading', threading),
|
||||
|
@ -2,7 +2,8 @@ from eventlet import patcher
|
||||
from eventlet.green import select
|
||||
|
||||
|
||||
patcher.inject('test.test_select',
|
||||
patcher.inject(
|
||||
'test.test_select',
|
||||
globals(),
|
||||
('select', select))
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user