-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()
Greenlet
GreenletExit
core
The 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: