Commit 4780e09c authored by Jason Madden's avatar Jason Madden

Update changelog with more links; add more/update/fix ..versionXXX in docstrings.

parent 39eb5eaf
This diff is collapsed.
...@@ -25,4 +25,8 @@ ...@@ -25,4 +25,8 @@
.. note:: As implemented, attempting to use .. note:: As implemented, attempting to use
:meth:`Threadpool.appy` from inside another function that :meth:`Threadpool.appy` from inside another function that
was itself spawned in a threadpool (any threadpool) will was itself spawned in a threadpool (any threadpool) will
cause the function to be run immediatesly. cause the function to be run immediately.
.. versionchanged:: 1.1a2
Now raises any exception raised by *func* instead of
dropping it.
...@@ -979,6 +979,10 @@ dl.glossary dt { ...@@ -979,6 +979,10 @@ dl.glossary dt {
margin: 0; margin: 0;
} }
th.field-name {
vertical-align: top;
}
.refcount { .refcount {
color: #060; color: #060;
} }
......
...@@ -163,6 +163,7 @@ include: ...@@ -163,6 +163,7 @@ include:
- Almost anywhere that gevent raises an exception from one greenlet to - Almost anywhere that gevent raises an exception from one greenlet to
another (e.g., :meth:`Greenlet.get <gevent.Greenlet.get>`), another (e.g., :meth:`Greenlet.get <gevent.Greenlet.get>`),
the original traceback is preserved and raised. the original traceback is preserved and raised.
- Various logging/debugging outputs have been cleaned up.
- The WSGI server found in :mod:`gevent.pywsgi` is more robust against - The WSGI server found in :mod:`gevent.pywsgi` is more robust against
errors in either the client or the WSGI application, fixing several errors in either the client or the WSGI application, fixing several
hangs or HTTP protocol violations. It also supports new hangs or HTTP protocol violations. It also supports new
......
...@@ -275,9 +275,15 @@ class FileObjectPosix(object): ...@@ -275,9 +275,15 @@ class FileObjectPosix(object):
return self.io.readlines(sizehint) return self.io.readlines(sizehint)
def readable(self): def readable(self):
"""
.. versionadded:: 1.1b2
"""
return self.io.readable() return self.io.readable()
def writable(self): def writable(self):
"""
.. versionadded:: 1.1b2
"""
return self.io.writable() return self.io.writable()
def seek(self, *args, **kwargs): def seek(self, *args, **kwargs):
......
...@@ -110,6 +110,11 @@ class FileObjectThread(object): ...@@ -110,6 +110,11 @@ class FileObjectThread(object):
return self.threadpool.apply(func, args, kwargs) return self.threadpool.apply(func, args, kwargs)
def close(self): def close(self):
"""
.. versionchanged:: 1.1b1
The file object is closed using the threadpool. Note that whether or
not this action is synchronous or asynchronous is not documented.
"""
fobj = self.io fobj = self.io
if fobj is None: if fobj is None:
return return
......
...@@ -127,7 +127,7 @@ class Greenlet(greenlet): ...@@ -127,7 +127,7 @@ class Greenlet(greenlet):
:keyword run: The callable object to run. If not given, this object's :keyword run: The callable object to run. If not given, this object's
`_run` method will be invoked (typically defined by subclasses). `_run` method will be invoked (typically defined by subclasses).
.. versionchanged:: 1.1a3 .. versionchanged:: 1.1b1
The ``run`` argument to the constructor is now verified to be a callable The ``run`` argument to the constructor is now verified to be a callable
object. Previously, passing a non-callable object would fail after the greenlet object. Previously, passing a non-callable object would fail after the greenlet
was spawned. was spawned.
...@@ -357,6 +357,10 @@ class Greenlet(greenlet): ...@@ -357,6 +357,10 @@ class Greenlet(greenlet):
This can be used as ``gevent.spawn`` or ``Greenlet.spawn``. This can be used as ``gevent.spawn`` or ``Greenlet.spawn``.
The arguments are passed to :meth:`Greenlet.__init__`. The arguments are passed to :meth:`Greenlet.__init__`.
.. versionchanged:: 1.1b1
If a *function* is given that is not callable, immediately raise a :exc:`TypeError`
instead of spawning a greenlet that will raise an uncaught TypeError.
""" """
g = cls(*args, **kwargs) g = cls(*args, **kwargs)
g.start() g.start()
...@@ -371,7 +375,7 @@ class Greenlet(greenlet): ...@@ -371,7 +375,7 @@ class Greenlet(greenlet):
The arguments are passed to :meth:`Greenlet.__init__`. The arguments are passed to :meth:`Greenlet.__init__`.
.. versionchanged:: 1.1a3 .. versionchanged:: 1.1b1
If an argument that's meant to be a function (the first argument in *args*, or the ``run`` keyword ) If an argument that's meant to be a function (the first argument in *args*, or the ``run`` keyword )
is given to this classmethod (and not a classmethod of a subclass), is given to this classmethod (and not a classmethod of a subclass),
it is verified to be callable. Previously, the spawned greenlet would have failed it is verified to be callable. Previously, the spawned greenlet would have failed
...@@ -655,7 +659,7 @@ def killall(greenlets, exception=GreenletExit, block=True, timeout=None): ...@@ -655,7 +659,7 @@ def killall(greenlets, exception=GreenletExit, block=True, timeout=None):
""" """
Forceably terminate all the ``greenlets`` by causing them to raise ``exception``. Forceably terminate all the ``greenlets`` by causing them to raise ``exception``.
:param greenlets: A bounded iterable of the non-None greenlets to terminate. :param greenlets: A **bounded** iterable of the non-None greenlets to terminate.
*All* the items in this iterable must be greenlets that belong to the same thread. *All* the items in this iterable must be greenlets that belong to the same thread.
:keyword exception: The exception to raise in the greenlets. By default this is :keyword exception: The exception to raise in the greenlets. By default this is
:class:`GreenletExit`. :class:`GreenletExit`.
...@@ -667,8 +671,12 @@ def killall(greenlets, exception=GreenletExit, block=True, timeout=None): ...@@ -667,8 +671,12 @@ def killall(greenlets, exception=GreenletExit, block=True, timeout=None):
the exception asynchronously. the exception asynchronously.
:keyword float timeout: A time in seconds to wait for greenlets to die. If given, it is :keyword float timeout: A time in seconds to wait for greenlets to die. If given, it is
only honored when ``block`` is True. only honored when ``block`` is True.
:raises Timeout: If blocking and a timeout is given that elapses before :raise Timeout: If blocking and a timeout is given that elapses before
all the greenlets are dead. all the greenlets are dead.
.. versionchanged:: 1.1a2
*greenlets* can be any iterable of greenlets, like an iterator or a set.
Previously it had to be a list or tuple.
""" """
# support non-indexable containers like iterators or set objects # support non-indexable containers like iterators or set objects
greenlets = list(greenlets) greenlets = list(greenlets)
......
...@@ -134,6 +134,10 @@ def spawn_raw(function, *args, **kwargs): ...@@ -134,6 +134,10 @@ def spawn_raw(function, *args, **kwargs):
occasionally be useful as an optimization if there are many occasionally be useful as an optimization if there are many
greenlets involved. greenlets involved.
.. versionchanged:: 1.1b1
If *function* is not callable, immediately raise a :exc:`TypeError`
instead of spawning a greenlet that will raise an uncaught TypeError.
.. versionchanged:: 1.1rc2 .. versionchanged:: 1.1rc2
Accept keyword arguments for ``function`` as previously (incorrectly) Accept keyword arguments for ``function`` as previously (incorrectly)
documented. Note that this may incur an additional expense. documented. Note that this may incur an additional expense.
...@@ -929,6 +933,12 @@ def iwait(objects, timeout=None, count=None): ...@@ -929,6 +933,12 @@ def iwait(objects, timeout=None, count=None):
are available, then this method returns immediately. are available, then this method returns immediately.
.. seealso:: :func:`wait` .. seealso:: :func:`wait`
.. versionchanged:: 1.1a1
Add the *count* parameter.
.. versionchanged:: 1.1a2
No longer raise :exc:`LoopExit` if our caller switches greenlets
in between items yielded by this function.
""" """
# QQQ would be nice to support iterable here that can be generated slowly (why?) # QQQ would be nice to support iterable here that can be generated slowly (why?)
if objects is None: if objects is None:
......
...@@ -127,6 +127,12 @@ affects what we see: ...@@ -127,6 +127,12 @@ affects what we see:
11 11
>>> del mydata >>> del mydata
.. versionchanged:: 1.1a2
Update the implementation to match Python 3.4 instead of Python 2.5.
This results in locals being eligible for garbage collection as soon
as their greenlet exits.
""" """
from copy import copy from copy import copy
...@@ -225,6 +231,9 @@ def _patch(self): ...@@ -225,6 +231,9 @@ def _patch(self):
class local(object): class local(object):
"""
An object whose attributes are greenlet-local.
"""
__slots__ = '_local__impl', '__dict__' __slots__ = '_local__impl', '__dict__'
def __new__(cls, *args, **kw): def __new__(cls, *args, **kw):
......
...@@ -171,8 +171,12 @@ class DummySemaphore(object): ...@@ -171,8 +171,12 @@ class DummySemaphore(object):
pass pass
def acquire(self, blocking=True, timeout=None): def acquire(self, blocking=True, timeout=None):
"""A DummySemaphore can always be acquired immediately so this always """
A DummySemaphore can always be acquired immediately so this always
returns True and ignores its arguments. returns True and ignores its arguments.
.. versionchanged:: 1.1a1
Always return *true*.
""" """
return True return True
......
...@@ -269,6 +269,9 @@ def patch_thread(threading=True, _threading_local=True, Event=False, logging=Tru ...@@ -269,6 +269,9 @@ def patch_thread(threading=True, _threading_local=True, Event=False, logging=Tru
:class:`multiprocessing.Queue` or :class:`multiprocessing.Queue` or
:class:`concurrent.futures.ProcessPoolExecutor` (which uses a :class:`concurrent.futures.ProcessPoolExecutor` (which uses a
``Queue``) will hang the process. ``Queue``) will hang the process.
.. versionchanged:: 1.1b1
Add *logging* and *existing_locks* params.
""" """
# Description of the hang: # Description of the hang:
# There is an incompatibility with patching 'thread' and the 'multiprocessing' module: # There is an incompatibility with patching 'thread' and the 'multiprocessing' module:
......
...@@ -264,7 +264,7 @@ if hasattr(os, 'fork'): ...@@ -264,7 +264,7 @@ if hasattr(os, 'fork'):
Availability: POSIX. Availability: POSIX.
.. versionadded:: 1.1a3 .. versionadded:: 1.1b1
""" """
# XXX Does not handle tracing children # XXX Does not handle tracing children
if pid <= 0: if pid <= 0:
...@@ -329,7 +329,7 @@ if hasattr(os, 'fork'): ...@@ -329,7 +329,7 @@ if hasattr(os, 'fork'):
Pass the builtin :func:`os.fork` function if you do not need to Pass the builtin :func:`os.fork` function if you do not need to
initialize gevent in the child process. initialize gevent in the child process.
.. versionadded:: 1.1a3 .. versionadded:: 1.1b1
.. seealso:: .. seealso::
:func:`gevent.monkey.get_original` To access the builtin :func:`os.fork`. :func:`gevent.monkey.get_original` To access the builtin :func:`os.fork`.
""" """
......
...@@ -365,6 +365,8 @@ class GroupMappingMixin(object): ...@@ -365,6 +365,8 @@ class GroupMappingMixin(object):
.. versionchanged:: 1.1b3 .. versionchanged:: 1.1b3
Added the *maxsize* keyword parameter. Added the *maxsize* keyword parameter.
.. versionchanged:: 1.1a1
Accept multiple *iterables* to iterate in parallel.
""" """
return self.__imap(IMap, func, *iterables, **kwargs) return self.__imap(IMap, func, *iterables, **kwargs)
......
...@@ -742,7 +742,12 @@ class WSGIHandler(object): ...@@ -742,7 +742,12 @@ class WSGIHandler(object):
self._sendall(towrite) self._sendall(towrite)
def start_response(self, status, headers, exc_info=None): def start_response(self, status, headers, exc_info=None):
# .. versionchanged:: 1.1b5 handle header/status encoding here """
.. versionchanged:: 1.1b5
Pro-actively handle checking the encoding of the status line
and headers during this method. On Python 2, avoid some
extra encodings.
"""
if exc_info: if exc_info:
try: try:
if self.headers_sent: if self.headers_sent:
......
...@@ -59,7 +59,7 @@ class Queue(object): ...@@ -59,7 +59,7 @@ class Queue(object):
size is infinite. size is infinite.
.. versionchanged:: 1.1b3 .. versionchanged:: 1.1b3
Queue's now support :func:`len`; it behaves the same as :meth:`qsize`. Queues now support :func:`len`; it behaves the same as :meth:`qsize`.
.. versionchanged:: 1.1b3 .. versionchanged:: 1.1b3
Multiple greenlets that block on a call to :meth:`put` for a full queue Multiple greenlets that block on a call to :meth:`put` for a full queue
will now be woken up to put their items into the queue in the order in which will now be woken up to put their items into the queue in the order in which
...@@ -404,9 +404,19 @@ class LifoQueue(Queue): ...@@ -404,9 +404,19 @@ class LifoQueue(Queue):
class JoinableQueue(Queue): class JoinableQueue(Queue):
'''A subclass of :class:`Queue` that additionally has :meth:`task_done` and :meth:`join` methods.''' """
A subclass of :class:`Queue` that additionally has
:meth:`task_done` and :meth:`join` methods.
"""
def __init__(self, maxsize=None, items=None, unfinished_tasks=None): def __init__(self, maxsize=None, items=None, unfinished_tasks=None):
"""
.. versionchanged:: 1.1a1
If *unfinished_tasks* is not given, then all the given *items*
(if any) will be considered unfinished.
"""
from gevent.event import Event from gevent.event import Event
Queue.__init__(self, maxsize, items) Queue.__init__(self, maxsize, items)
self._cond = Event() self._cond = Event()
...@@ -454,7 +464,8 @@ class JoinableQueue(Queue): ...@@ -454,7 +464,8 @@ class JoinableQueue(Queue):
self._cond.set() self._cond.set()
def join(self, timeout=None): def join(self, timeout=None):
'''Block until all items in the queue have been gotten and processed. '''
Block until all items in the queue have been gotten and processed.
The count of unfinished tasks goes up whenever an item is added to the queue. The count of unfinished tasks goes up whenever an item is added to the queue.
The count goes down whenever a consumer thread calls :meth:`task_done` to indicate The count goes down whenever a consumer thread calls :meth:`task_done` to indicate
...@@ -465,6 +476,9 @@ class JoinableQueue(Queue): ...@@ -465,6 +476,9 @@ class JoinableQueue(Queue):
for all tasks to finish. for all tasks to finish.
:return: ``True`` if all tasks have finished; if ``timeout`` was given and expired before :return: ``True`` if all tasks have finished; if ``timeout`` was given and expired before
all tasks finished, ``False``. all tasks finished, ``False``.
.. versionchanged:: 1.1a1
Add the *timeout* parameter.
''' '''
return self._cond.wait(timeout=timeout) return self._cond.wait(timeout=timeout)
......
...@@ -66,6 +66,10 @@ def signal(signalnum, handler): ...@@ -66,6 +66,10 @@ def signal(signalnum, handler):
Use of ``SIG_IGN`` and ``SIG_DFL`` may also have race conditions Use of ``SIG_IGN`` and ``SIG_DFL`` may also have race conditions
with libev child watchers and the :mod:`gevent.subprocess` module. with libev child watchers and the :mod:`gevent.subprocess` module.
.. versionchanged:: 1.1rc2
Allow using ``SIG_IGN`` and ``SIG_DFL`` to reset and ignore ``SIGCHLD``.
However, this allows the possibility of a race condition.
""" """
if signalnum != _signal.SIGCHLD: if signalnum != _signal.SIGCHLD:
return _signal_signal(signalnum, handler) return _signal_signal(signalnum, handler)
......
...@@ -347,7 +347,13 @@ class Popen(object): ...@@ -347,7 +347,13 @@ class Popen(object):
cwd=None, env=None, universal_newlines=False, cwd=None, env=None, universal_newlines=False,
startupinfo=None, creationflags=0, threadpool=None, startupinfo=None, creationflags=0, threadpool=None,
**kwargs): **kwargs):
"""Create new Popen instance.""" """Create new Popen instance.
:param kwargs: *Only* allowed under Python 3; under Python 2, any
unrecognized keyword arguments will result in a :exc:`TypeError`.
Under Python 3, keyword arguments can include ``pass_fds``, ``start_new_session``,
and ``restore_signals``.
"""
if not PY3 and kwargs: if not PY3 and kwargs:
raise TypeError("Got unexpected keyword arguments", kwargs) raise TypeError("Got unexpected keyword arguments", kwargs)
...@@ -562,6 +568,13 @@ class Popen(object): ...@@ -562,6 +568,13 @@ class Popen(object):
:keyword timeout: Under Python 2, this is a gevent extension; if :keyword timeout: Under Python 2, this is a gevent extension; if
given and it expires, we will raise :class:`gevent.timeout.Timeout`. given and it expires, we will raise :class:`gevent.timeout.Timeout`.
Under Python 3, this raises the standard :exc:`TimeoutExpired` exception. Under Python 3, this raises the standard :exc:`TimeoutExpired` exception.
.. versionchanged:: 1.1a2
Under Python 2, if the *timeout* elapses, raise the :exc:`gevent.timeout.Timeout`
exception. Previously, we silently returned.
.. versionchanged:: 1.1b5
Honor a *timeout* even if there's no way to communicate with the child
(stdin, stdout, and stderr are not pipes).
""" """
greenlets = [] greenlets = []
if self.stdin: if self.stdin:
...@@ -649,6 +662,7 @@ class Popen(object): ...@@ -649,6 +662,7 @@ class Popen(object):
None if stderr is None else stderr_value or b'') None if stderr is None else stderr_value or b'')
def poll(self): def poll(self):
"""Check if child process has terminated. Set and return :attr:`returncode` attribute."""
return self._internal_poll() return self._internal_poll()
if PY3: if PY3:
...@@ -927,6 +941,7 @@ class Popen(object): ...@@ -927,6 +941,7 @@ class Popen(object):
# #
def rawlink(self, callback): def rawlink(self, callback):
# Not public documented, part of the link protocol
self.result.rawlink(linkproxy(callback, self)) self.result.rawlink(linkproxy(callback, self))
# XXX unlink # XXX unlink
...@@ -1258,7 +1273,7 @@ class Popen(object): ...@@ -1258,7 +1273,7 @@ class Popen(object):
return self.returncode return self.returncode
def wait(self, timeout=None): def wait(self, timeout=None):
"""Wait for child process to terminate. Returns returncode """Wait for child process to terminate. Returns :attr:`returncode`
attribute. attribute.
:keyword timeout: The floating point number of seconds to wait. :keyword timeout: The floating point number of seconds to wait.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment