-O or PYTHONOPTIMIZE. Previously these would go
undetected if optimizations were enabled, potentially leading to
erratic, difficult to debug behaviour.AttributeError from gevent.monkey.patch_builtins on
Python 2 when the future library is also installed. Reported by
Carlos Sanchez.DistutilsModuleError or ImportError if the CFFI
module backing gevent.core needs to be compiled when the hub is
initialized (due to a missing or invalid __pycache__ directory).
Now, the module will be automtically compiled when gevent is
imported (this may produce compiler output on stdout). Reported in
issue #619 by Thinh Nguyen and issue #631 by Andy Freeland, with
contributions by Jay Oster and Matt Dupre.gevent.socket.socket:sendall
with large inputs. bench_sendall.py now performs about as well on
PyPy as it does on CPython, an improvement of 10x (from ~60MB/s to
~630MB/s). See this pypy bug for details.TypeError when calling gevent.socket.wait.
Reported in #635 by lanstin.gevent.socket.socket:sendto properly respects the socket’s
blocking status (meaning it can raise EWOULDBLOCK now in cases it
wouldn’t have before). Reported in pull request #634 by Mike Kaplinskiy.threaded resolver are no longer always printed to stderr
since they are usually out of the programmer’s control and caught
explicitly. (Programming errors like TypeError are still
printed.) Reported in issue #617 by Jay Oster and Carlos Sanchez.TypeError from gevent.idle(). Reported in
issue #639 by chilun2008.imap_unordered methods of a pool support a maxsize
parameter to limit the number of results buffered waiting for the
consumer. Reported in issue #638 by Sylvain Zimmer.gevent.queue.Queue now consistently orders multiple
blocked waiting put and get callers in the order they
arrived. Previously, due to an implementation quirk this was often
roughly the case under CPython, but not under PyPy. Now they both
behave the same.gevent.queue.Queue now supports the len() function.c-ares resolver under
PyPy. Note that its performance characteristics are probably
sub-optimal.gevent.monkey.patch_builtins could cause PyPy
to crash. Reported in issue #618 by Jay Oster.gevent.kill raises the correct exception in the target greenlet.
Reported in issue #623 by Jonathan Kamens.readable and writable methods to FileObjectPosix;
this fixes e.g., help() on Python 3 when monkey-patched.setup.py can be run from a directory containing spaces. Reported
in issue #319 by Ivan Smirnov.setup.py can build with newer versions of clang on OS X. They
enforce the distinction between CFLAGS and CPPFLAGS.gevent.lock.Semaphore is atomic on PyPy, just like it is on
CPython. This comes at a small performance cost.successful value to
False when killing a greenlet before it ran with a non-default
exception. Fixed in pull request #608 by Heungsub Lee.os.waitpid to become unreliable
due to the use of signals on POSIX platforms. This was especially
noticeable when using gevent.subprocess in combination with
multiprocessing. Now, the monkey-patched os module provides
a waitpid function that seeks to ameliorate this. Reported in
issue #600 by champax and issue #452 by Łukasz Kawczyński.select.poll, provide a
gevent-friendly gevent.select.poll and corresponding
monkey-patch. Implemented in pull request #604 by Eddi Linder.gevent.thread.allocate_lock (and so a monkey-patched standard
library allocate_lock) more closely matches the behaviour of the
builtin: an unlocked lock cannot be released, and attempting to do
so throws the correct exception (thread.error on Python 2,
RuntimeError on Python 3). Previously, over-releasing a lock was
silently ignored. Reported in issue #308 by Jędrzej Nowak.gevent.fileobject.FileObjectThread uses the threadpool to close
the underling file-like object. Reported in issue #201 by
vitaly-krugl.gevent.pywsgi handler is handled more robustly, resulting in
“HTTP 400 bad request” responses instead of a 500 error or, in the
worst case, a server-side hang. Reported in issue #229 by Björn
Lindqvist.threading module before using
gevent.monkey.patch_all() no longer causes Python 3.4 to fail to
get the repr of the main thread, and other CPython platforms to
return an unjoinable DummyThread. (Note that this is not
recommended.) Reported in issue #153.io package to implement
FileObjectPosix. This unifies the code with the Python 3
implementation, and fixes problems with using seek(). See
issue #151.gevent.spawn, spawn_raw and spawn_later, as well as the
Greenlet constructor, immediately produce useful TypeErrors
if asked to run something that cannot be run. Previously, the
spawned greenlet would die with an uncaught TypeError the first
time it was switched to. Reported in issue #119 by stephan.gevent.threadpool.ThreadPool.apply no longer
raises a LoopExit error (using ThreadPool.spawn and then
get on the result still could; you must be careful to use the
correct hub). Reported in issue #131 by 8mayday.threading module is monkey-patched, the module-level
lock in the logging module is made greenlet-aware, as are the
instance locks of any configured handlers. This makes it safer to
import modules that use the standard pattern of creating a
module-level Logger instance before monkey-patching. Configuring
logging with a basic configuration and then monkey-patching is
also safer (but not configurations that involve such things as the
SocketHandler).threading.RLock under Python 3.RuntimeError
from importlib. Reported in issue #615 by Daniel Mizyrycki.
(The same thing could happen under Python 2 if a threading.RLock
was held around the monkey-patching call; this is less likely but
not impossible with import hooks.)pywsgi.WSGIServer accept a
logging.Logger instance for its log and (new) error_log
parameters. Take care that the system is fully monkey-patched very
early in the process’s lifetime if attempting this, and note that
non-file handlers have not been tested. Fixes issue #106.gevent.threadpool.ThreadPool.imap and imap_unordered now
accept multiple iterables.ThreadPool or Group mapping/application functions should now
have the original traceback.gevent.threadpool.ThreadPool.apply now raises any exception
raised by the called function, the same as
gevent.pool.Group/Pool and the builtin apply function.
This obsoletes the undocumented apply_e function. Original PR
issue #556 by Robert Estelle.selectors module from patch_all and
patch_select on Python 3.4. See issue #591.gevent.monkey module
allow knowing what was patched. Discussed in issue #135 and
implemented in pull request #325 by Nathan Hoad.gevent.socket.socket.sendall supports arbitrary objects that
implement the buffer protocol (such as ctypes structures), just like
native sockets. Reported in issue #466 by tzickel.onerror attribute present in CFFI 1.2.0
for better signal handling under PyPy. Thanks to Armin Rigo and Omer
Katz. (See https://bitbucket.org/cffi/cffi/issue/152/handling-errors-from-signal-handlers-in)gevent.subprocess module is closer in behaviour to the
standard library under Python 3, at least on POSIX. The
pass_fds, restore_signals, and start_new_session
arguments are now unimplemented, as are the timeout parameters
to various functions. Under Python 2, the previously undocumented timeout
parameter to Popen.communicate raises an exception like its
Python 3 counterpart.gevent.subprocess
module no longer leaks file descriptors. Reported in pull request #374 by 陈小玉.echoserver.py no longer binds to the standard X11
TCP port. Reported in issue #485 by minusf.gevent.iwait no longer throws LoopExit if the caller
switches greenlets between return values. Reported and initial patch
in pull request #467 by Alexey Borzenkov.multiprocessing.Process.
Previously the child process would hang indefinitely. Reported in
issue #230 by Lx Yu.gevent.killall accepts an arbitrary iterable for the greenlets
to kill. Reported in issue #404 by Martin Bachwerk; seen in
combination with older versions of simple-requests.gevent.local.local objects are now eligible for garbage
collection as soon as the greenlet finishes running, matching the
behaviour of the built-in threading.local (when implemented
natively). Reported in issue #387 by AusIV.gevent.kill or
gevent.greenlet.Greenlet.kill) before it is actually started and
switched to now prevents the greenlet from ever running, instead of
raising an exception when it is later switched to. See issue #330
reported by Jonathan Kamens.Add support for Python 3.3 and 3.4. Many people have contributed to this effort, including but not limited to Fantix King, hashstat, Elizabeth Myers, jander, Luke Woydziak, and others. See issue #38.
Add support for PyPy. See issue #248. Note that for best results, you’ll need a very recent PyPy build including CFFI 1.2.0.
Drop support for Python 2.5. Python 2.5 users can continue to use gevent 1.0.x.
Fix gevent.greenlet.joinall to not ignore count when
raise_error is False. See pull request #512 by Ivan Diao.
Fix subprocess.Popen to not ignore the bufsize argument. Note
that this changes the (platform dependent) default, typically from
buffered to unbuffered. See pull request #542 by Romuald Brunet.
Upgraded c-ares to 1.10.0. See pull request #579 by Omer Katz.
Caution
The c-ares configure script is now more strict about the
contents of environment variables such as CFLAGS and LDFLAGS
and they may have to be modified (for example, CFLAGS is no
longer allowed to include -I directives, which must instead be
placed in CPPFLAGS).
Add a count argument to gevent.greenlet.wait. See pull request #482 by
wiggin15.
Add a timeout argument to gevent.queue.JoinableQueue.wait
which now returns whether all items were waited for or not.
gevent.queue.JoinableQueue treats items passed to
__init__ as unfinished tasks, the same as if they were put.
Initial pull request #554 by DuLLSoN.
gevent.pywsgi no longer prints debugging information for the
normal conditions of a premature client disconnect. See issue #136,
fixed in pull request #377 by Paul Collier.
(Experimental.) Waiting on or getting results from greenlets that raised exceptions now usually raises the original traceback. This should assist things like Sentry to track the original problem. See issue #450 and issue #528 by Rodolfo and Eddi Linder and issue #240 by Erik Allik.
Upgrade to libev 4.20. See pull request #590 by Peter Renström.
Fix gevent.baseserver.BaseServer to be printable when its
handle function is an instancemethod of itself. See pull request #501 by Joe
Jevnik.
Make the acquire method of gevent.lock.DummySemaphore always
return True, supporting its use-case as an “infinite” or unbounded
semaphore providing no exclusion, and allowing the idiom if
sem.acquire(): .... See pull request #544 by Mouad Benchchaoui.
Patch subprocess by default in gevent.monkey.patch_all. See
issue #446.
gevent.pool.Group.imap and imap_unordered now accept
multiple iterables like itertools.imap. issue #565 reported by
Thomas Steinacher.
Compatibility note: gevent.baseserver.BaseServer and
its subclass gevent.server.StreamServer now deterministically
close the client socket when the request handler returns.
Previously, the socket was left at the mercies of the garbage
collector; under CPython 2.x this meant when the last reference went
away, which was usually, but not necessarily, when the request
handler returned, but under PyPy it was some arbitrary point in the
future and under CPython 3.x a ResourceWarning could be generated.
This was undocumented behaviour, and the client socket could be kept
open after the request handler returned either accidentally or intentionally.
Compatibility note: pywsgi now ensures that headers can be
encoded in latin-1 (ISO-8859-1). This improves adherence to the HTTP
standard (and is necessary under Python 3). Under certain
conditions, previous versions could have allowed non-ISO-8859-1
headers to be sent, but their interpretation by a conforming
recipient is unknown; now, a UnicodeError will be raised. See issue #614.
monkey:
socket:
pywsgi:
subprocess:
resolver_ares:
os:
hub:
core:
Misc:
Major and backward-incompatible changes:
core:
Misc:
Examples:
Developer utilities:
Backward-incompatible changes:
Release highlights:
misc: - gevent.joinall() method now accepts optional ‘count’ keyword. - gevent.fork() only calls reinit() in the child process now. - gevent.run() now returns False when exiting because of timeout or event (previous None). - Hub got a new method: destroy(). - Hub got a new property: threadpool.
ares.pyx: - Fixed issue #104: made ares_host_result pickable. Thanks to Shaun Cutts.
pywsgi: - Removed unused deprecated ‘wfile’ property from WSGIHandler - Fixed issue #92: raise IOError on truncated POST requests. - Fixed issue #93: do not sent multiple “100 continue” responses
core: - Fixed issue #97: the timer watcher now calls ev_now_update() in start() and again() unless ‘update’ keyword is passed and set to False. - add set_syserr_cb() function; it’s used by gevent internally. - gevent now installs syserr callback using libev’s set_syserr_cb. This callback is called when libev encounters an error it cannot recover from. The default action is to print a message and abort. With the callback installed, a SystemError() is now raised in the main greenlet. - renamed ‘backend_fd’ property to ‘fileno()’ method. (not available if you build gevent against system libev) - added ‘asynccnt’ property (not available if you build gevent against system libev) - made loop.__repr__ output a bit more compact - the watchers check the arguments for validness now (previously invalid argument would crash libev). - The ‘async’ watcher now has send() method; - fixed time() function - libev has been upgraded to latest CVS version. - libev has been patched to use send()/recv() for evpipe on windows when libev_vfd.h is in effect
resolver_ares: - Slightly improved compatibility with stdlib’s socket in some error cases.
socket: - Fixed close() method not to reference any globals - Fixed issue #115: _dummy gets unexpected Timeout arg - Removed _fileobject used for python 2.4 compatibility in socket.py - Fixed issue #94: fallback to buffer if memoryview fails in _get_memory on python 2.7
monkey: - Removed patch_httplib() - Fixed issue #112: threading._sleep is not patched. Thanks to David LaBissoniere. - Added get_unpatched() function. However, it is slightly broken at the moment.
backdoor: - make ‘locals()’ not spew out __builtin__.__dict__ in backdoor - add optional banner argument to BackdoorServer
servers: - add server.DatagramServer; - StreamServer: ‘ssl_enabled’ is now a read-only property - servers no longer have ‘kill’ method; it has been renamed to ‘close’. - listeners can now be configured as strings, e.g. ‘:80’ or 80 - modify baseserver.BaseServer in such a way that makes it a good base class for both StreamServer and DatagramServer - BaseServer no longer accepts ‘backlog’ parameter. It is now done by StreamServer. - BaseServer implements start_accepting() and stop_accepting() methods - BaseServer now implements “temporarily stop accepting” strategy - BaseServer now has _do_read method which does everything except for actually calling accept()/recvfrom() - pre_start() method is renamed to init_socket() - renamed _stopped_event to _stop_event - ‘started’ is now a read-only property (which actually reports state of _stop_event) - post_stop() method is removed - close() now sets _stop_event(), thus setting ‘started’ to False, thus causing serve_forever() to exit - _tcp_listener() function is moved from baseserver.py to server.py - added ‘fatal_errors’ class attribute which is a tuple of all errnos that should kill the server
coros: - Semaphore: add _start_notify() method - Semaphore: avoid copying list of links; rawlink() no longer schedules notification
Added ‘ref’ property to all watchers. Settings it to False make watcher call ev_unref/ev_ref appropriately so that this watcher does not prevent loop.run()/hub.join()/run() from exiting. Made resolver_ares.Resolver use ‘ref’ property for internal watcher.
In all servers, method “kill” was renamed to “close”. The old name is available as deprecated alias.
Added a few properties to the loop: backend_fd, fdchangecnt, timercnt.
Upgraded c-ares to 1.7.5+patch.
Fixed getaddrinfo to return results in the order (::1, IPv4, IPv6).
Fixed getaddrinfo() to handle integer of string type. Thanks to kconor.
Fixed gethostbyname() to handle ‘’ (empty string).
Fixed getaddrinfo() to convert UnicodeEncodeError into error(‘Int or String expected’).
Fixed getaddrinfo() to uses the lowest 16 bits of passed port integer similar to built-in _socket.
Fixed getnameinfo() to call getaddrinfo() to process arguments similar to built-in _socket.
Fixed gethostbyaddr() to use getaddrinfo() to process arguments.
version_info is now a 5-tuple.
Added handle_system_error() method to Hub (used internally).
Fixed Hub’s run() method to never exit. This prevent inappropriate switches into parent greenlet.
Fixed Hub.join() to return True if Hub was already dead.
Added ‘event’ argument to Hub.join().
Added run() function to gevent top level package.
Fixed Greenlet.start() to exit silently if greenlet was already started rather than raising AssertionError.
Fixed Greenlet.start() not to schedule another switch if greenlet is already dead.
Fixed gevent.signal() to spawn Greenlet instead of raw greenlet. Also it’ll switch into the new greenlet immediately instead of scheduling additional callback.
Do monkey patch create_connection() as gevent’s version works better with gevent.socket.socket than the standard create_connection.
pywsgi: make sure we don’t try to read more requests if socket operation failed with EPIPE
pywsgi: if we failed to send the reply, change ‘status’ to socket error so that the logs mention the error.
Fixed a bug in gevent.queue.Channel class. (Thanks to Alexey Borzenkov)
Backward-incompatible changes:
DeprecationError. Use gevent.queue.Channel if you need a channel.Greenlet.link(), Greenlet.link_value() and Greenlet.link_exception().gevent.core has been rewritten and the interface is not compatible.SystemExit and SystemError now kill the whole process instead of printing a traceback.util.lazy_property property.gevent.dns module.Group.Release highlights:
gevent.core module now wraps libev’s API and is not compatible with gevent 0.x.signal works now as expected.Channel class to gevent.queue module. It is equivalent to Queue(0) in gevent 0.x, which is deprecated now.peek() to Queue class.idle() function which blocks until the event loop is idle.Hub.join().gevent.ares C extension which wraps c-ares and provides asynchronous DNS resolver.gevent.resolver_ares module provides synchronous API on top of gevent.ares.The gevent.socket module:
DNS functions now use c-ares library rather than libevent-dns. This fixes a number of problems with name resolving:
gevent.fork() (os.fork is monkeypatched with it if monkey.patch_all() was called).
DNS resolver no longer ignores /etc/resolv.conf and /etc/hosts.
The following functions were added to socket module - gethostbyname_ex - getnameinfo - gethostbyaddr - getfqdn
Removed undocumented bind_and_listen and tcp_listener
The Hub object:
join() method which waits until the event loop exits or optional timeout expires.wait() method which waits until a watcher has got an event.handle_error() method which is called by all of gevent in case of unhandled exception.print_exception() method which is called by handle_error to print the exception traceback.The Greenlet objects:
The mod:gevent.pool module:
map() and imap() methods now start yielding the results as soon as possible.imap_unordered() no longer swallows an exception raised while iterating its argument.Miscellaneous:
WSGIServer now sets max_accept to 1 if wsgi.multiprocessing is set to True.monkey.patch_module() function that monkey patches module using __implements__ list provided by gevent module.
All of gevent modules that replace stdlib module now have __implements__ attribute.Queue(None).full() returns False now (previously it returned True).__copy__ method to gevent.local.local class that implements copy semantics compatible with built-in threading.local. Patch by Galfy Pundee.StreamServer class to catch EWOULDBLOCK rather than EAGAIN. This fixes lots of spurious tracebacks on Windows where these two constants are not the same. Patch by Alexey Borzenkov.fork() now calls event_reinit only in the child process; otherwise the process could hang when using libevent2. Patch by Alexander Boudkar.TypeError that occurred when environ["wsgi.input"].read function was called with an integer argument.monkey.patch_thread() now patches threading too, even if it’s already imported. Patch by Shaun Lindsay.joinall() and killall() functions used to hang if their argument contained duplicate greenlets.pywsgi.WSGIServer reported “Connection reset by peer” if the client did not close the connection gracefully after the last request. Such errors are now ignored.wsgi.WSGIServer add REQUEST_URI to environ. Patch by Andreas Blixt.httplib with gevent.httplib used to break HTTPSConnection. Patch by Nick Barkas.create_connection now raises proper exception when getaddrinfo fails.BaseServer.__repr__() method, BaseServer.server_host and BaseServer.server_port attributes to handle the case of AF_UNIX addresses properly. Previously they assumed address is always a tuple.pywsgi.WSGIServer to handle AF_UNIX listeners. The server now sets environ["SERVER_NAME"] and environ["SERVER_PORT"] to empty string in such case.StreamServer (and thus pywsgi.WSGIServer) accept up to 100 connections per one readiness notification. This behaviour is controlled by StreamServer.max_accept class attribute.gevent.httplib that rendered it unusable.getaddrinfo by calling resolve_ipv4 and resolve_ipv6 concurrently rather than sequentially in AF_UNSPEC case.gevent.httplib – experimental support for libevent-http client (issue #9). Thanks to Tommie Gannert, Örjan Persson.gevent.wsgi with libevent2 (issue #62).pywsgi not to use chunked transfer encoding in case of 304 and 204 responses as it creates a non-empty message body which is against RFC and causes some browsers to fail. Patch by Nicholas Piël.socket.getaddrinfo() to handle AF_UNSPEC properly and resolve service names (issue #56). Thanks to Elizabeth Jennifer Myers.socket.getaddrinfo() to handle international domain names.sys.exc_info set. Leaking is prevented by not preserving traceback at all and only keeping the value of the exception. Thanks to Ned Rockson.ssl.SSLSocket.unwrap() to shutdown SSLSocket properly, without raising SSLError(read operation timeout).TypeError inside Hub on Python 2.4.gevent.pywsgi to make subclassing easier.WSGIServer to explicitly close the socket after the last request. Patch by Ralf Schmitt.pywsgi.WSGIHandler not to add CONTENT_TYPE to the environ dict when there’s no Content-Type header in the request. Previously a default text/plain was added in such case.imap_unordered to Pool class. Unlike previous “dummy” implementation this one starts yielding the results as soon as they are ready.Queue. The main use case is the implementation of Pool.imap_unordered().BaseServer.started property: it is now set to True after start until stop or kill. Previously it could become False for short period of times, because StreamServer could stop accepting for a while in presence of errors and StreamServer.started was defined as “whether the server is currently accepting”.wsgi.WSGIServer to reply with 500 error immediatelly if the application raises an error (issue #58). Thanks to Jon Aslund.monkey.patch_httplib() function which is disabled by default.monkey.patch_all() (defaults to False).write method to core.buffer.OverflowError that could happen in core.event.__str__().http_request.get_input_headers() return header names in lower case.StreamServer to accept ciphers as an SSL argument.build_exc --cython= option to setup.py. Patch by Ralf Schmitt.local to raise AttributeError if __dict__ attribute is set or deleted.Release highlights:
monkey to patch socket.create_connection.gevent.ssl module to fully match the functionality of ssl on Python 2.7.Group.join() to handle raise_error=True properly, it used to raise TypeError (issue #36). Thanks to by David Hain.gevent.wsgi and gevent.pywsgi to join multiple Cookie headers (issue #40).select to recognize long arguments in addition to int.Semaphore.acquire() to return False when timeout expires instead of raising AssertionError (issue #39). Patch by Erik Näslund.JoinableQueue.join() to return immediatelly if queue is already empty (issue #45). Patch by Dmitry Chechik.gevent.sslold module.gevent.socket module:
socket.shutdown() method to interrupt read/write operations on socket.NameError in socket.connect_ex() method. Patch by Alexey Borzenkov.create_connection() function.gevent.socket import all public items from stdlib socket that do not do I/O.gevent.ssl module:
makefile() method on an SSL object would prevent the underlying socket from being closed until all objects get truely destroyed (Python issue #5238).getpeername() in SSLSocket.__init__, only silence exceptions caused by the “socket not connected” condition.SSLSocket.send and SSLSocket.recv methods to match the behavior of stdlib ssl better.ssl.SSLObject to delete events used by other greenlets when closing the instance (issue #34).Miscellaneous:
BaseServer accept long values as pool argument in addition to int.http._requests attribute public.OperationalError.webproxy.py example to be runnable under external WSGI server.test__exc_info.py.xtest_pep8.py.BackdoorServer close the connection on SystemExit and simplified the code.Pool raise ValueError when initialized with size=0.setup.py --libevent to configure and make libevent if it’s not built already.setup.py to use setuptools if present and add dependency on greenlet.Release highlights:
gevent.server module with StreamServer class for easy implementing of TCP and SSL servers.gevent.baseserver module with BaseServer class.gevent.pywsgi based on gevent.server. Contributed by Ralf Schmitt.gevent.local module. Fixed issue #24. Thanks to Ted Suzman.gevent.wsgi module.exc_info.socket.sendall() to use buffer object to prevent string copies.gevent.wsgi and gevent.pywsgi much more similar to each other.Backward-incompatible changes:
Greenlet.kill() method and other kill* methods.http.HTTPServer to match the interface of other servers.Pool‘s spawn() method to block until there’s a free slot.backdoor.backdoor_server() function.socket module:socket_bind_and_listen()set_reuse_addr()connect_tcp()tcp_server()socket.fd property.core.event.add() and socket.wait_read() and similar. Use None from now on, which is compatible with the previous versions.backdoor.BackdoorServer from StreamServer rather than from Greenlet. This adds lots of new features and removes a few old ones.balance property from Semaphore.start(), set_cb() and set_gencb() from core.http.set_closecb() from core.http_connection. It is now used internally to detach the requests of the closed connections.rawgreenlet module.util.lazy_property().GreenletSet to Group. The old name is currently available as an alias.gevent.socket module:
getfqdn() from socket module.sys.platform to detect Windows rather than platform module.getaddrinfo() used to handle the case when socktype or proto were equal to 0. Thanks to Randall Leeds.gevent.coros module:
RLock class.DummySemaphore class.BoundedSemaphore class to behave like threading.BoundedSemaphore behaves.gevent.event module:
Event.wait() return internal flag instead of None.AsyncResult.wait() return its value instead of None.ready() method as an alias for is_set().gevent.wsgi module:
wsgi.buffer_proxy.gevent.pywsgi module:
server and not to depend on BaseHTTPServer.wsgi module.
Removed server() function, add Server class, added WSGIServer class.HttpProtocol to WSGIHandler.readline().gevent.core module:
event class.read_event, write_event and readwrite_event.flags_str property to event. It is used by __str__ and __repr__.buffer:detach() method.readline() and readlines() methods.http_request:detach() to detach input and output buffers too.input_buffer and output_buffer store and reuse the buffer object they create.__str__() and meth:__repr__ to include spaces where needed.http class no longer has set_cb() and set_gencb(). Instead its contructor accepts handle which will be called on each request.gevent.http and gevent.wsgi modules:
HTTPServer use "Connection: close" header by default.HTTPServer now derives from baseserver.BaseServer. Thus its start() method no longer accepts socket to listen on, it must be passed to the contructor.Pool instance. While the pool is full, the server replies with 503 error.http_request which will send 500 reply when deallocated if the user hasn’t send any.Miscellaneous:
gevent.thread to use Greenlet instead of raw greenlets. This means monkey patched thread will become Greenlet too.started property to Greenlet.gevent.baseserver module. All servers in gevent package are now derived from BaseServer.sleep() now raises IOError if passed a negative argument.USE_LIBEVENT_? is no longer needed to build gevent.core.backdoor when a client typed quit().greenlet failed with ImportError, keep the original error message,
because sometimes the error originates in setuptools.select.select() to return all the file descriptors signalled, not just the first one.thread (and thus monkey patched threads) to spawn Greenlet instances, rather than raw greenlets.Examples:
StreamServer.Thanks to Ralf Schmitt for pywsgi, a number of fixes for wsgi, help with
baseserver and server modules, improving setup.py and various other patches and suggestions.
Thanks to Uriel Katz for pywsgi patches.
build/lib.../gevent/core.so to gevent/core.so.gevent.socket: Improved compatibility with stdlib’s socket:socket to raise timeout("timed out") rather than simply timeout._GLOBAL_DEFAULT_TIMEOUT from standard socket module instead of creating a new object.Release highlights:
gevent.ssl module.socket.recv(), socket.send() and similar methods.dns - with synchronous wrappers around libevent’s DNS API.core.readwrite_event and socket.wait_readwrite() functions.wsgi module with the WSGI spec.pywsgi module.gevent.wsgi module:
env["REMOTE_PORT"] into a string.wsgi.input object iterable.gevent.core module:
IOError if they failed.core.dns_err_to_string().gevent.socket module:
gethostbyname() and getaddrinfo() to call the stdlib if the passed hostname has no dots.getaddrinfo() to filter the results using socktype and proto arguments.getnameinfo() as it didn’t quite match the stdlib interface.
Use dns.resolve_reverse() for reverse resolutions.socket.connect_ex() to use cooperative gethostbyname().socket.dup() not to call underlying socket’s dup() (which is not available
on Windows) but to use Python’s reference counting similar to how the stdlib’s socket
implements dup()socket‘s constructor. Passing the socket instance
as first argument is no longer supported.socket.connect() to ignore WSAEINVAL on Windows.socket.connect() to use wait_readwrite() instead of wait_write().socket.connect() to consult SO_ERROR.socket.send() and socket.sendall() to support flags argument.socket_bind_and_listen() to socket.bind_and_listen(). The old name
is still available as a deprecated alias._sock property.socket into gevent.socket.
(Thanks to Matt Goodall for the original patch).wrap_ssl() to ssl(). (the old name is still available but deprecated)connect_tcp() and tcp_server().sslerror to socket.__all__.GreenSocket alias for socket class.socket.ssl() into gevent.oldssl module.
It’s imported into gevent.socket if importing gevent.ssl fails.Miscellaneous:
select to clean up properly if event creation fails.select to raise select.error instead of IOError.select.select() to what they are called in the stdlib.getLinkedCompleted() from gevent.greenlet.#warning directives from libevent.h. They are not supported by vc90.coros.Waiter now stores the value if no one’s waiting for it.testrunner.py script that replaces a bunch of small scripts that were used before.is_secure attribute from sockets and ssl objects.Greenlet not to print a traceback when a not-yet-started greenlet is killed.BackdoorServer class to backdoor. Removed backdoor() function and deprecated backdoor_server() function.__getattr__ from socket class.monkey.patch_socket() not to fail if socket.ssl() is not present in gevent.socket.monkey.patch_ssl().monkey.patch_all().test package directly and run them in monkey patched environment.wsgi to unquote environ['PATH_INFO'] before passing to application.SERVER_SOFTWARE variable to wsgi environ.JoinableQueue.task_done() that caused ValueError to be raised incorrectly here.gevent.socket not to fail with ImportError if Python was not built with ssl support.select.select() function. Passing non-empty list of write descriptors used to cause this function to fail.Contributed by Ludvig Ericson:
wsgi‘s start_response to recognize exc_info argument.joinall(), Greenlet.join(), pool.Pool.join(): if timeout has expired
it used to raise Timeout; now it returns silently.signal() to run the signal handler in a new greenlet; it was run in the Hub greenlet before.Timeout.start_new(): if passed a Timeout instance, it now calls its start
method before returning it.gevent.monkey to patch threading.local properly.Queue.empty() and Queue.full() to be compatible
with the standard Queue. It tried to take into account the greenlets currently blocking on
get/put which
was not useful and hard to reason about. Now it simply compares qsize to maxsize,
which what the standard Queue does too.Event to behave exactly like the standard threading.Event:Event.set() does not accept a parameter anymore; it’s now either set or not.Event.get method is gone.Event.set(); Event.clear() used to be a no-op; now it properly wakes up all the waiters.AsyncResult behaves exactly like before, but it does not inherit from Event anymore
and does miss clear() method.socket.wait_reader()/socket.wait_writer() to socket.wait_read()/socket.wait_write().gevent.socket.GreenSocket to gevent.socket.socket. GreenSocket is still available
as an alias but will be removed in the future.gevent.core now includes wrappers for evbuffer, evdns, evhttp.gevent.wsgi to gevent.pywsgi.gevent.http module based on libevent-http wrappers.gevent.wsgi module based on gevent.http.gevent.core and DNS functions to gevent.socket module. Contributed by Jason Toffaletti..setup.py to select a libevent library to compile against. Check them out with setup.py -h.__all__ to many modules that missed it.Changed Timeout API in a backward-incompatible way:
Timeout.__init__() does not start the timer immediately anymore;
Timeout.start() must be called explicitly.
A shortcut - Timeout.start_new() - is provided that creates and starts
a Timeout.
Added gevent.Greenlet class which is a subclass of greenlet that adds a few
useful methods join/get/kill/link.
spawn() now returns Greenlet instance. The old spawn, which returns py.magic.greenlet
instance, can be still accessed as spawn_raw().
Note
The implementation of Greenlet is an improvement on proc module, with these bugs fixed:
getcurrent() useless and using
Procs as keys in dict impossible.Greenlet executes each link in a new greenlet by default, unless
it is set up with Greenlet.rawlink method.Greenlet, override its _run
and __init__ methods.Added pool.Pool class with the methods compatible to the standard multiprocessing.pool:
apply, map and others.
It also has spawn method which is always async and returns a
Greenlet instance.
Added gevent.event module with 2 classes: Event and AsyncResult.
Event is a drop-in replacement for threading.Event, supporting
set/wait/get methods. AsyncResult
is an extension of Event that supports exception passing via set_exception method.
Added queue.JoinableQueue class with task_done
and join methods.
Renamed core.read and core.write classes to core.read_event and core.write_event.
gevent.pywsgi: pulled Mike Barton’s eventlet patches that fix double content-length issue.
Fixed setup.py to search more places for system libevent installation.
This fixes 64bit CentOS 5.3 installation issues, hopefully covers other platforms
as well.
The following items were added to the gevent top level package:
spawn_link()spawn_link_value()spawn_link_exception()spawn_raw()joinall()killall()GreenletGreenletExitcoreThe following items were marked as deprecated:
wrap_errors helper was moved to util module)Internally, gevent.greenlet was split into a number of modules:
gevent.hub provides Hub class and basic utilities, like sleep();
Hub is now a subclass of greenlet.gevent.timeout provides Timeout and with_timeout();gevent.greenlet provides Greenlet class and helpers like joinall() and killall().gevent.rawgreenlet contains the old “polling” versions of
joinall and killall (they do not need link
functionality and work with any greenlet by polling their status and sleeping in a loop)Thanks to Jason Toffaletti for reporting the installation issue and providing a test case for WSGI double content-length header bug.
gevent.queue module and made it 2.4-compatible.
LifoQueue and PriorityQueue are implemented as well.
gevent.queue will deprecate both coros.Queue and coros.Channel.Timeout to raise itself by default. TimeoutError is gone.
Silent timeout is now created by passing False instead of None.gevent.select.select() where it could silent the wrong timeout.spawn() and spawn_later() now avoid creating a closure and this decreases spawning
time by 50%.kill‘s and killall‘s wait argument was renamed to block. The polling is now
implemented by greenlet.join and greenlet.joinall functions and it become more
responsive, with gradual increase of sleep time.proc.RunningProcSet to proc.ProcSet.shutdown() function, which blocks until libevent has finished dispatching the events.event_add and event_del in core.pyx are now checked properly
and IOError is raised if they have failed.gevent.socket‘s implementation and fixed SSL bug reported on eventletdev
by Cesar Alaniz as well as failures in test_socket_ssl.py.GreenSocket.makeGreenFile; Use socket.socket.makefile() that returns _fileobject
and is available on both GreenSocket and GreenSSL.
The gevent.socket is still a work in progress.core.active_event class that takes advantage of libevent’s event_active function.
core.active_event(func) schedules func to be run in this event loop iteration as opposed
to core.timer(0, ...) which schedules an event to be run in the next iteration.
active_event is now used throughout the library wherever core.timer(0, ....) was previously used.
This results in spawn() being at least 20% faster compared to release 0.9.1 and twice as fast compared to
eventlet. (The results are obtained with bench_spawn.py script in greentest/ directory)kill() and killall() functions. If set to True, it makes the
function block until the greenlet(s) is actually dead. By default, kill() and killall() are asynchronous,
i.e. they don’t unschedule the current greenlet.gevent.core.event: fd, events,
events_str and flags. It also has __enter__
and __exit__ now, so it can be used as a context
manager. event‘s callback signature has changed from (event, fd, evtype) to (event, evtype).Hub‘s mainloop to never return successfully as this will screw up main greenlet’s switch() call.
Instead of returning it raises DispatchExit.reinit() function - wrapper for libevent’s event_reinit.
This function is a must have at least for daemons, as it fixes epoll and some others eventloops to work after fork.spawn_link[exception/value] to proc.RunningProcSet.setup.py not to depend on setuptools.gevent.timeout. Use gevent.Timeout.Hub to recover silently after event_dispatch() failures (I’ve seen this
happen after fork even though event_reinit() is called as necessary). The end result is that fork()
now works more reliably, as detected by test_socketserver.py - it used to fail occasionally, now it does not.gevent/__init__.py was moved to gevent/greenlet.py.
gevent/__init__.py imports some of it back but not everything.gevent.timeout to gevent.Timeout. The old name is available as an alias.queue.Queue.
Added test_queue.py from standard tests to check how good is queue.Queue a replacement
for a standard Queue (not good at all, timeouts in queue.Queue.put() don’t work yet)monkey now patches ssl module when on 2.6 (very limited support).GreenSocket now wraps a socket object from _socket module rather
than from socket.Started as eventlet 0.8.11 fork, with the intention to support only libevent as a backend. Compared to eventlet, this version has a much simpler API and implementation and a few severe bugs fixed, namely
read() and write() on the same fd do not cancel one another.GreenSocket.close method does not hang as it could with eventlet.There’s a test in my repo of eventlet that reproduces both of them: http://bitbucket.org/denis/eventlet/src/tip/greentest/test__socket.py
Besides having less bugs and less code to care about the goals of the fork are: