Commit ff1fc0fa authored by Jason Madden's avatar Jason Madden

More doc love.

parent 39ffc09b
[pep8]
ignore=E702,E265,E402,E731,E266,E261,W503,E129
max_line_length=160
exclude=.tox,.git,build,2.6,2.7,2.7pypy,3.3,test_support.py,test_queue.py,patched_tests_setup.py,test_threading_2.py,lock_tests.py,_sslgte279.py,3.4
exclude=.eggs,.tox,.git,build,2.6,2.7,2.7pypy,3.3,test_support.py,test_queue.py,patched_tests_setup.py,test_threading_2.py,lock_tests.py,_sslgte279.py,3.4
:mod:`gevent` -- basic utilities
================================
==================================
:mod:`gevent` -- basic utilities
==================================
.. module:: gevent
......@@ -7,9 +8,10 @@ The most common functions and classes are available in the :mod:`gevent` top lev
.. autodata:: __version__
.. autodata:: version_info
Greenlet objects
----------------
================
:class:`Greenlet` is a light-weight cooperatively-scheduled execution unit.
......@@ -28,7 +30,7 @@ idea to override :meth:`__str__`: if :meth:`_run` raises an exception,
its string representation will be printed after the traceback it
generated.
.. note:: You SHOULD NOT attempt to override the ``run()`` method.
.. important:: You *SHOULD NOT* attempt to override the ``run()`` method.
.. class:: Greenlet
......@@ -36,7 +38,13 @@ generated.
.. attribute:: Greenlet.value
Holds the value returned by the function if the greenlet has finished successfully. Otherwise ``None``.
Holds the value returned by the function if the greenlet has
finished successfully. Until then, or if it finished in error, ``None``.
.. tip:: Recall that a greenlet killed with the default
:class:`GreenletExit` is considered to have finished
successfully, and the ``GreenletExit`` exception will be
its value.
.. autoattribute:: Greenlet.exception
......@@ -50,28 +58,41 @@ generated.
.. automethod:: Greenlet.link(callback)
.. automethod:: Greenlet.link_value(callback)
.. automethod:: Greenlet.link_exception(callback)
.. automethod:: Greenlet.rawlink
.. automethod:: Greenlet.unlink
Boolean Contexts
----------------
Greenlet objects have a boolean value (``__nonzero__`` or ``__bool__``) which is true if it's active: started but not dead yet.
Greenlet objects have a boolean value (``__nonzero__`` or
``__bool__``) which is true if it's active: started but not dead yet.
It's possible to use it like this::
g = gevent.spawn(...)
while g:
# do something while g is alive
>>> g = gevent.spawn(...)
>>> while g:
# do something while g is alive
The Greenlet's ``__nonzero__`` is an improvement on greenlet's
``__nonzero__``. The greenlet's `__nonzero__` returns False if greenlet has
not been switched to yet or already dead. While the latter is OK, the
``__nonzero__``. The greenlet's :meth:`__nonzero__
<greenlet.greenlet.__nonzero__>` returns False if greenlet has not
been switched to yet or is already dead. While the latter is OK, the
former is not good, because a just spawned Greenlet has not been
switched to yet and thus would evaluate to False.
Being a greenlet__ subclass, :class:`Greenlet` also has ``switch()`` and ``throw()`` methods.
However, these should not be used at the application level. Prefer higher-level safe
classes, like :class:`Event <gevent.event.Event>` and :class:`Queue <gevent.queue.Queue>`, instead.
Raw greenlet Methods
--------------------
Being a greenlet__ subclass, :class:`Greenlet` also has `switch()
<switching>`_ and `throw() <throw>`_ methods. However, these should
not be used at the application level as they can very easily lead to
greenlets that are forever unscheduled. Prefer higher-level safe
classes, like :class:`Event <gevent.event.Event>` and :class:`Queue
<gevent.queue.Queue>`, instead.
__ http://greenlet.readthedocs.org/en/latest/#instantiation
.. _switching: https://greenlet.readthedocs.org/en/latest/#switching
.. _throw: https://greenlet.readthedocs.org/en/latest/#methods-and-attributes-of-greenlets
.. exception:: GreenletExit
......@@ -83,17 +104,15 @@ __ http://greenlet.readthedocs.org/en/latest/#instantiation
property as if it was returned by the greenlet, not raised.
Spawn helpers
-------------
=============
.. autofunction:: spawn(function, *args, **kwargs)
.. autofunction:: spawn_later(seconds, function, *args, **kwargs)
.. autofunction:: spawn_raw
Useful general functions
------------------------
========================
.. function:: getcurrent()
......@@ -117,7 +136,7 @@ Useful general functions
Timeouts
--------
========
.. autoclass:: Timeout
:members:
......@@ -127,7 +146,7 @@ Timeouts
Waiting
-------
=======
.. autofunction:: wait
......
......@@ -135,10 +135,9 @@ reduce the cases of undocumented or non-standard behaviour.
the HTTP specification, and their interpretation by the recipient is
unknown. Now, a UnicodeError will be raised.
Most applications that adhered to the WSGI PEP, `PEP 3333`_ will not
Most applications that adhered to the WSGI PEP, :pep:`3333`, will not
need to make any changes. See :issue:`614` for more discussion.
.. _`PEP 3333`: https://www.python.org/dev/peps/pep-3333/
- Under Python 2, the previously undocumented ``timeout`` parameter to
:meth:`Popen.wait <gevent.subprocess.Popen.wait>` (a gevent extension
......
......@@ -8,7 +8,15 @@ See http://www.gevent.org/ for the documentation.
from __future__ import absolute_import
version_info = (1, 1, 'a3', 'dev', 0)
from collections import namedtuple
_version_info = namedtuple('version_info',
('major', 'minor', 'micro', 'releaselevel', 'serial'))
#: The programatic version identifier. The fields have (roughly) the
#: same meaning as :data:`sys.version_info`
version_info = _version_info(1, 1, 0, 'alpha', '3')
#: The human-readable PEP 440 version identifier
__version__ = '1.1a3.dev0'
......
......@@ -254,7 +254,7 @@ class Greenlet(greenlet):
"""Return true if and only if the greenlet has finished execution successfully,
that is, without raising an error.
.. note:: A greenlet that has been killed with the default :class:`GreenletExit` exception
.. tip:: A greenlet that has been killed with the default :class:`GreenletExit` exception
is considered successful. That is, ``GreenletExit`` is not considered an error.
"""
return self._exc_info and self._exc_info[1] is None
......@@ -359,8 +359,8 @@ class Greenlet(greenlet):
The arguments are passed to :meth:`Greenlet.__init__`.
.. versionchanged:: 1.1a3
If a callable argument (the first argument or the ``run`` keyword )
is given to this method (and not a subclass),
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),
it is verified to be callable. Previously, the spawned greenlet would have failed
when it started running.
"""
......@@ -515,9 +515,11 @@ class Greenlet(greenlet):
return
def rawlink(self, callback):
"""Register a callable to be executed when the greenlet finishes the execution.
"""Register a callable to be executed when the greenlet finishes execution.
WARNING: the callable will be called in the HUB greenlet.
The *callback* will be called with this instance as an argument.
.. caution:: The callable will be called in the HUB greenlet.
"""
if not callable(callback):
raise TypeError('Expected callable: %r' % (callback, ))
......@@ -541,11 +543,11 @@ class Greenlet(greenlet):
pass
def link_value(self, callback, SpawnedLink=SuccessSpawnedLink):
"""Like :meth:`link` but *callback* is only notified when the greenlet has completed successfully"""
"""Like :meth:`link` but *callback* is only notified when the greenlet has completed successfully."""
self.link(callback, SpawnedLink=SpawnedLink)
def link_exception(self, callback, SpawnedLink=FailureSpawnedLink):
"""Like :meth:`link` but *callback* is only notified when the greenlet dies because of unhandled exception"""
"""Like :meth:`link` but *callback* is only notified when the greenlet dies because of an unhandled exception."""
self.link(callback, SpawnedLink=SpawnedLink)
def _notify_links(self):
......
......@@ -67,8 +67,10 @@ def spawn_raw(function, *args):
"""
Create a new :class:`greenlet.greenlet` object and schedule it to run ``function(*args, **kwargs)``.
As this returns a raw greenlet, it does not have all the useful methods that
:class:`gevent.Greenlet` has and should only be used as an optimization.
This returns a raw greenlet which does not have all the useful methods that
:class:`gevent.Greenlet` has. Typically, applications should prefer :func:`gevent.spawn`,
but this method may occasionally be useful as an optimization if there are many greenlets
involved.
.. versionchanged:: 1.1a3
Verify that ``function`` is callable, raising a TypeError if not. Previously,
......@@ -83,12 +85,22 @@ def spawn_raw(function, *args):
def sleep(seconds=0, ref=True):
"""Put the current greenlet to sleep for at least *seconds*.
"""
Put the current greenlet to sleep for at least *seconds*.
*seconds* may be specified as an integer, or a float if fractional
seconds are desired.
*seconds* may be specified as an integer, or a float if fractional seconds
are desired.
.. tip:: In the current implementation, a value of 0 (the default)
means to yield execution to any other runnable greenlets, but
this greenlet may be scheduled again before the event loop
cycles (in an extreme case, a greenlet that repeatedly sleeps
with 0 can prevent greenlets that are ready to do I/O from
being scheduled for some (small) period of time); a value greater than
0, on the other hand, will delay running this greenlet until
the next iteration of the loop.
If *ref* is false, the greenlet running sleep() will not prevent gevent.wait()
If *ref* is False, the greenlet running ``sleep()`` will not prevent :func:`gevent.wait`
from exiting.
"""
hub = get_hub()
......@@ -137,6 +149,15 @@ def kill(greenlet, exception=GreenletExit):
class signal(object):
"""
Call the *handler* with the *args* and *kwargs* when the process
receives the signal *signalnum*.
The *handler* will be run in a new greenlet when the signal is delivered.
This returns an object with the useful method ``cancel``, which, when called,
will prevent future deliveries of *signalnum* from calling *handler*.
"""
greenlet_class = None
......@@ -727,12 +748,15 @@ class _MultipleWaiter(Waiter):
def iwait(objects, timeout=None, count=None):
"""
Yield objects as they are ready, until all (or `count`) are ready or `timeout` expired.
Iteratively yield objects as they are ready, until all (or `count`) are ready
or `timeout` expired.
:param objects: A sequence (supporting :func:`len`) containing objects
implementing the wait protocol (rawlink() and unlink()).
:param count: If not `None`, then a number specifying the maximum number
of objects to wait for.
.. seealso:: :func:`wait`
"""
# QQQ would be nice to support iterable here that can be generated slowly (why?)
if objects is None:
......@@ -773,7 +797,7 @@ def wait(objects=None, timeout=None, count=None):
"""
Wait for ``objects`` to become ready or for event loop to finish.
If ``objects`` is provided, it must be an list containing objects
If ``objects`` is provided, it must be a list containing objects
implementing the wait protocol (rawlink() and unlink() methods):
- :class:`gevent.Greenlet` instance
......@@ -782,7 +806,7 @@ def wait(objects=None, timeout=None, count=None):
- :class:`gevent.subprocess.Popen` instance
If ``objects`` is ``None`` (the default), ``wait()`` blocks until
all event loops have nothing to do (or until ``timeout`` passes):
the current event loop has nothing to do (or until ``timeout`` passes):
- all greenlets have finished
- all servers were stopped
......@@ -800,6 +824,8 @@ def wait(objects=None, timeout=None, count=None):
Returns the list of ready objects, in the order in which they were
ready.
.. seealso:: :func:`iwait`
"""
if objects is None:
return get_hub().join(timeout=timeout)
......
# Copyright (c) 2009-2010 Denis Bilenko. See LICENSE for details.
"""Timeouts.
"""
Timeouts.
Many functions in :mod:`gevent` have a *timeout* argument that allows
to limit function's execution time. When that is not enough, the :class:`Timeout`
class and :func:`with_timeout` function in this module add timeouts
to arbitrary code.
limiting the time the function will block. When that is not available,
the :class:`Timeout` class and :func:`with_timeout` function in this
module add timeouts to arbitrary code.
.. warning::
......@@ -20,7 +21,8 @@ __all__ = ['Timeout',
class Timeout(BaseException):
"""Raise *exception* in the current greenlet after given time period::
"""
Raise *exception* in the current greenlet after given time period::
timeout = Timeout(seconds, exception)
timeout.start()
......@@ -29,6 +31,11 @@ class Timeout(BaseException):
finally:
timeout.cancel()
.. note:: If the code that the timeout was protecting finishes
executing before the timeout elapses, be sure to ``cancel`` the timeout
so it is not unexpectedly raised in the future. Even if it is raised, it is a best
practice to cancel it. This ``try/finally`` construct is a recommended pattern.
When *exception* is omitted or ``None``, the :class:`Timeout` instance itself is raised:
>>> import gevent
......@@ -38,16 +45,17 @@ class Timeout(BaseException):
...
Timeout: 0.1 seconds
For Python 2.5 and newer ``with`` statement can be used::
To simplify starting and canceling timeouts, the ``with`` statement can be used::
with gevent.Timeout(seconds, exception) as timeout:
pass # ... code block ...
This is equivalent to try/finally block above with one additional feature:
if *exception* is ``False``, the timeout is still raised, but context manager
This is equivalent to the try/finally block above with one additional feature:
if *exception* is ``False``, the timeout is still raised, but the context manager
suppresses it, so the code outside the with-block won't see it.
This is handy for adding a timeout to the functions that don't support *timeout* parameter themselves::
This is handy for adding a timeout to the functions that don't
support a *timeout* parameter themselves::
data = None
with gevent.Timeout(5, False):
......@@ -57,12 +65,14 @@ class Timeout(BaseException):
else:
... # a line was read within 5 seconds
Note that, if ``readline()`` above catches and doesn't re-raise :class:`BaseException`
(for example, with ``except:``), then your timeout is screwed.
.. caution:: If ``readline()`` above catches and doesn't re-raise :class:`BaseException`
(for example, with a bare ``except:``), then your timeout will fail to function and control
won't be returned to you when you expect.
When catching timeouts, keep in mind that the one you catch maybe not the
one you have set; if you going to silent a timeout, always check that it's
the one you need::
When catching timeouts, keep in mind that the one you catch may
not be the one you have set (a calling function may have set its
own timeout); if you going to silence a timeout, always check that
it's the instance you need::
timeout = Timeout(1)
timeout.start()
......@@ -71,6 +81,11 @@ class Timeout(BaseException):
except Timeout as t:
if t is not timeout:
raise # not my timeout
If the *seconds* argument is not given or is ``None`` (e.g.,
``Timeout()``), then the timeout will never expire and never raise
*exception*. This is convenient for creating functions which take
an optional timeout parameter of their own.
"""
def __init__(self, seconds=None, exception=None, ref=True, priority=-1):
......@@ -95,7 +110,8 @@ class Timeout(BaseException):
This is a shortcut, the exact action depends on *timeout*'s type:
* If *timeout* is a :class:`Timeout`, then call its :meth:`start` method.
* If *timeout* is a :class:`Timeout`, then call its :meth:`start` method
if it's not already begun.
* Otherwise, create a new :class:`Timeout` instance, passing (*timeout*, *exception*) as
arguments, then call its :meth:`start` method.
......
......@@ -344,6 +344,7 @@ if run_make and os.path.exists("Makefile"):
else:
setup_requires = []
def run_setup(ext_modules, run_make):
if run_make:
if isinstance(run_make, str):
......
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