Commit d6c1c498 authored by Denis Bilenko's avatar Denis Bilenko

add documentation

parent a53ebcfc
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
-rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
./fixindex.py
rm -f _build/html/_static/jquery.js
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The txt pages are in $(BUILDDIR)/text."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/gevent.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/gevent.qhc"
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
"run these through (pdf)latex."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
@import url("default.css");
body.homepage {
background-color: #ffffff;
margin: 40px 230px 20px 230px;
}
div.body h1,
div.body h2,
div.body h3,
div.body h4,
div.body h5,
div.body h6 {
background-color: #ffffff;
}
em {
font-style: normal;
}
<table class="contentstable" width=50%><tr>
<td width="50%">
<p class="biglink"><a class="biglink" href="{{ pathto("contents") }}">{{ _('Contents') }}</a><br>
<span class="linkdescr">{{ _('lists all sections and subsections') }}</span></p>
<p class="biglink"><a class="biglink" href="{{ pathto("search") }}">{{ _('Search Page') }}</a><br>
<span class="linkdescr">{{ _('search this documentation') }}</span></p>
</td><td width="50%">
<p class="biglink"><a class="biglink" href="{{ pathto("genindex") }}">{{ _('Index') }}</a><br>
<span class="linkdescr">{{ _('all functions, classes, terms') }}</span></p>
<p class="biglink"><a class="biglink" href="{{ pathto("modindex") }}">{{ _('Module Index') }}</a><br>
<span class="linkdescr">{{ _('quick access to all modules') }}</span></p>
</td></tr>
</table>
{%- block doctype -%}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
{%- endblock %}
{%- set reldelim1 = reldelim1 is not defined and ' &raquo;' or reldelim1 %}
{%- set reldelim2 = reldelim2 is not defined and ' |' or reldelim2 %}
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
{{ metatags }}
<title>{{ title|striptags }}</title>
<link rel="stylesheet" href="{{ pathto('_static/', 1) }}index.css" type="text/css" />
{%- block extrahead %} {% endblock %}
</head>
<body class="homepage">
<div class="document">
<div class="body">
{{ body }}
</div>
</div>
</body>
</html>
../changelog.rst
\ No newline at end of file
# -*- coding: utf-8 -*-
#
# gevent documentation build configuration file, created by
# sphinx-quickstart on Thu Oct 1 09:30:02 2009.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys, os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.append(os.path.abspath('.'))
# -- General configuration -----------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.coverage', 'sphinx.ext.intersphinx', 'mysphinxext']
intersphinx_mapping = {'http://docs.python.org/dev': None}
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8'
# The master toctree document.
master_doc = 'contents'
# General information about the project.
project = u'gevent'
copyright = u'2009, gevent contributors'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
from gevent import __version__
version = __version__
# The full version, including alpha/beta/rc tags.
release = version
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of documents that shouldn't be included in the build.
#unused_docs = []
# List of directories, relative to source directory, that shouldn't be searched
# for source files.
exclude_trees = ['_build']
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = ['gevent.']
# -- Options for HTML output ---------------------------------------------------
# The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'.
html_theme = 'default'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#if html_theme == 'default':
# html_theme_options = {'rightsidebar' : True}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
html_short_title = 'Documentation'
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
html_additional_pages = {'contentstable': 'contentstable.html'}
# If false, no module index is generated.
html_use_modindex = True
# If false, no index is generated.
html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = ''
# Output file base name for HTML help builder.
htmlhelp_basename = 'geventdoc'
# -- Options for LaTeX output --------------------------------------------------
# The paper size ('letter' or 'a4').
#latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt').
#latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'gevent.tex', u'gevent Documentation',
u'gevent contributors', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# Additional stuff for the LaTeX preamble.
#latex_preamble = ''
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_use_modindex = True
###############################################################################
# prevent some stuff from showing up in docs
import gevent.queue
import gevent.http
del gevent.queue.JoinableQueue.put # it's already covered in the parent
del gevent.http.HTTPServer.spawn # it's a parameter, not a method
del gevent.Greenlet.throw
# order the methods in the class documentation the same way they are ordered in the source code
from sphinx.ext import autodoc
from sphinx.ext.autodoc import ClassDocumenter
class MyClassDocumenter(ClassDocumenter):
def get_object_members(self, want_all):
members_check_module, members = super(MyClassDocumenter, self).get_object_members(want_all)
def key((name, obj)):
try:
return obj.im_func.func_code.co_firstlineno
except AttributeError:
return 0
members.sort(key=key)
return members_check_module, members
autodoc.ClassDocumenter = MyClassDocumenter
# overload StandaloneHTMLBuilder to take custom_page_templates into account
custom_page_templates = {'index': 'index.html'}
from sphinx.builders.html import StandaloneHTMLBuilder
class MyStandaloneHTMLBuilder(StandaloneHTMLBuilder):
def handle_page(self, pagename, addctx, templatename='page.html',
outfilename=None, event_arg=None):
templatename = custom_page_templates.get(pagename, templatename)
return super(MyStandaloneHTMLBuilder, self).handle_page(pagename=pagename, addctx=addctx,
templatename=templatename, outfilename=outfilename,
event_arg=event_arg)
from sphinx.builders import html
html.StandaloneHTMLBuilder = MyStandaloneHTMLBuilder
# link to jquery.js hosted at ajax.googleapis.com
index = html.StandaloneHTMLBuilder.script_files.index('_static/jquery.js')
html.StandaloneHTMLBuilder.script_files[index] = ('http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js')
# don't add permalinks on index.html
disable_permalinks = ['index']
disable_permalinks = [os.path.abspath(x + source_suffix) for x in disable_permalinks]
from sphinx.writers.html import HTMLTranslator
orig_depart_title = HTMLTranslator.depart_title
def HTMLTranslator_depart_title(self, node):
if node.source in disable_permalinks:
stored_add_permalinks = self.add_permalinks
self.add_permalinks = False
else:
stored_add_permalinks = None
try:
return orig_depart_title(self, node)
finally:
if stored_add_permalinks is not None:
self.add_permalinks = stored_add_permalinks
HTMLTranslator.depart_title = HTMLTranslator_depart_title
gevent documentation contents
=============================
.. toctree::
intro
reference
changelog
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
#!/usr/bin/python
import os, re
index_name = '_build/html/index.html'
contentstable_name = '_build/html/contentstable.html'
if os.path.exists(contentstable_name):
# replace 'insert-contenstable.html' with contestable.html
index = open(index_name).read()
contentstable = open(contentstable_name).read()
index = index.replace('INSERT-contentstable.html', contentstable)
open(index_name, 'w').write(index)
os.unlink(contentstable_name)
# protect email
email_re = re.compile('<a .*?mailto.*?</a>')
def repl(m):
source = m.group(0)
result = "<script type=\"text/javascript\">document.write('"
while source:
piece, source = source[:5], source[5:]
result += piece + "'+'"
return result + "')</script><noscript><small>enable javascript to see the email</small></noscript>"
newindex, n = email_re.subn(repl, index)
if not n:
print 'no email found'
else:
assert n == 1, (n, newindex)
open(index_name, 'w').write(newindex)
Low-level wrappers around libevent (gevent.core module)
=======================================================
.. automodule:: gevent.core
events
------
.. autoclass:: event(evtype, handle, callback[, arg])
:members:
:undoc-members:
.. autoclass:: read_event
:members:
:undoc-members:
.. autoclass:: write_event
:members:
:undoc-members:
.. autoclass:: timer
:members:
:undoc-members:
.. autoclass:: signal
:members:
:undoc-members:
.. autoclass:: active_event
:members:
:undoc-members:
event loop
----------
.. autofunction:: init
.. autofunction:: dispatch
.. autofunction:: loop
.. autofunction:: get_version
.. autofunction:: get_method
.. autofunction:: get_header_version
evdns
-----
.. autofunction:: dns_init
.. autofunction:: dns_shutdown
.. autofunction:: dns_resolve_ipv4
.. autofunction:: dns_resolve_ipv6
.. autofunction:: dns_resolve_reverse
.. autofunction:: dns_resolve_reverse_ipv6
evbuffer
--------
.. autoclass:: buffer
:members:
:undoc-members:
evhttp
------
.. autoclass:: http_request
:members:
:undoc-members:
.. autoclass:: http_connection
:members:
:undoc-members:
.. autoclass:: http
:members:
:undoc-members:
Synchronization primitives (gevent.event module)
================================================
.. module:: gevent.event
.. autoclass:: gevent.event.Event
:members: set, clear, wait, rawlink, unlink
.. method:: is_set()
isSet()
Return true if and only if the internal flag is true.
.. autoclass:: gevent.event.AsyncResult
:members:
:undoc-members:
.. attribute:: value
Holds the value passed to :meth:`set` if :meth:`set` was called. Otherwise ``None``.
HTTP server based on libevent-http (gevent.http module)
=======================================================
.. automodule:: gevent.http
:members:
:undoc-members:
:mod:`gevent.hub`
=================
.. module:: gevent.hub
.. autoclass:: Hub
:members:
:undoc-members:
.. autoexception:: DispatchExit
.. autofunction:: get_hub
.. autoclass:: Waiter
Monkey patching (gevent.monkey module)
======================================
.. automodule:: gevent.monkey
:members:
:undoc-members:
Managing greenlets in a group
=============================
.. automodule:: gevent.pool
:members:
:undoc-members:
Pure Python WSGI server (gevent.pywsgi module)
==============================================
.. automodule:: gevent.pywsgi
:members:
:undoc-members:
Synchronized queues (gevent.queue module)
=========================================
.. automodule:: gevent.queue
:members:
:undoc-members:
.. exception:: Full
An alias for :class:`Queue.Full`
.. exception:: Empty
An alias for :class:`Queue.Empty`
Example of how to wait for enqueued tasks to be completed::
def worker():
while True:
item = q.get()
try:
do_work(item)
finally:
q.task_done()
q = JoinableQueue()
for i in range(num_worker_threads):
gevent.spawn(worker)
for item in source():
q.put(item)
q.join() # block until all tasks are done
:mod:`gevent.rawgreenlet`
=========================
.. automodule:: gevent.rawgreenlet
:members:
:undoc-members:
Basic utilities (The gevent top level package)
==============================================
.. module:: gevent
The most common functions and classes are available in the :mod:`gevent` top level package.
Greenlet objects
----------------
:class:`Greenlet` is a light-weight cooperatively-scheduled execution unit.
To start a new greenlet, pass the target function and its arguments to :class:`Greenlet` constructor and call :meth:`start`:
>>> g = Greenlet(myfunction, 'arg1', 'arg2', kwarg1=1)
>>> g.start()
or use classmethod :meth:`spawn` which is a shortcut that does the same:
>>> g = Greenlet.spawn(myfunction, 'arg1', 'arg2', kwarg1=1)
To subclass a :class:`Greenlet`, override its _run() method and call ``Greenlet.__init__(self)`` in __init__:
>>> class MyNoopGreenlet(Greenlet):
...
... def __init__(self, seconds):
... Greenlet.__init__(self)
... self.seconds = seconds
...
... def _run(self):
... gevent.sleep(self.seconds)
It also a good idea to override __str__(): if _run() raises an exception, its string representation will be printed after the traceback it generated.
.. class:: Greenlet
.. attribute:: Greenlet.value
Holds the value returned by the function if the greenlet has finished successfully. Otherwise ``None``.
.. autoattribute:: Greenlet.exception
.. automethod:: Greenlet.ready
.. automethod:: Greenlet.successful
.. automethod:: Greenlet.start
.. automethod:: Greenlet.start_later
.. automethod:: Greenlet.join
.. automethod:: Greenlet.get
.. automethod:: Greenlet.kill(exception=GreenletExit, block=False, timeout=None)
.. automethod:: Greenlet.link(receiver=None)
.. automethod:: Greenlet.link_value(receiver=None)
.. automethod:: Greenlet.link_exception(receiver=None)
.. automethod:: Greenlet.unlink
Being a greenlet__ subclass, :class:`Greenlet` also has ``switch()`` and ``throw()`` methods.
However, these should not be used at application level. Prefer higher-level safe
classes, like :class:`Event <gevent.event.Event>` and :class:`Queue <gevent.queue.Queue>`, instead.
__ http://codespeak.net/py/0.9.2/greenlet.html
.. exception:: GreenletExit
A special exception that kills the greenlet silently.
When a greenlet raises :exc:`GreenletExit` or a subclass, the traceback is not
printed and the greenlet is considered :meth:`successful <Greenlet.successful>`.
The exception instance is available under :attr:`value <Greenlet.value>`
property as if it was returned by the greenlet, not raised.
Spawn helpers
-------------
.. function:: spawn(function, *args, **kwargs)
Create a new :class:`Greenlet` object and schedule it to run ``function(*args, **kwargs)``.
This is an alias for :meth:`Greenlet.spawn`.
.. function:: spawn_later(seconds, function, *args, **kwargs)
Create a new :class:`Greenlet` object and schedule it to run ``function(*args, **kwargs)``
in the future loop iteration *seconds* later.
This is an alias for :meth:`Greenlet.spawn_later`.
.. function:: spawn_raw(function, *args, **kwargs)
Create a new :class:`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.
.. function:: spawn_link(function, *args, **kwargs)
spawn_link_value(function, *args, **kwargs)
spawn_link_exception(function, *args, **kwargs)
This are the shortcuts for::
g = spawn(function, *args, **kwargs)
g.link() # or g.link_value() or g.link_exception()
As :meth:`Greenlet.link` without argument links to the current greenlet, a :class:`gevent.greenlet.LinkedExited`
exception will be raised if the newly spawned greenlet exits. It is not meant as a way of inter-greenlet communication
but more of a way to assert that a background greenlet is running at least as long as the current greenlet.
See :meth:`Greenlet.link`, :meth:`Greenlet.link_value` and :meth:`Greenlet.link_exception` for details.
Useful general functions
------------------------
.. autofunction:: getcurrent
.. autofunction:: sleep
.. autofunction:: kill
.. autofunction:: killall
.. autofunction:: joinall
.. autofunction:: signal
.. autofunction:: fork
.. autofunction:: shutdown
.. autofunction:: reinit
Timeouts
--------
.. autoclass:: Timeout
:members:
:undoc-members:
.. autofunction:: with_timeout
Cooperative socket module (gevent.socket module)
================================================
.. automodule:: gevent.socket
:members:
:undoc-members:
Random utilities
================
gevent.select module
--------------------
.. automodule:: gevent.select
:members:
Python helpers (gevent.util module)
-----------------------------------
.. automodule:: gevent.util
:members:
:undoc-members:
WSGI server based on libevent-http (gevent.wsgi module)
=======================================================
.. automodule:: gevent.wsgi
:members:
:undoc-members:
gevent_
=======
gevent_ is a coroutine_-based Python_ networking library that uses greenlet_ to provide
a high-level synchronous API on top of libevent_ event loop.
Features include:
* `convenient API around greenlets`__
* familiar synchronization primitives (:mod:`gevent.event`, :mod:`gevent.queue`)
* :doc:`socket module that cooperates <gevent.socket>`
* :doc:`WSGI server on top of libevent-http <gevent.wsgi>`
* DNS requests done through libevent-dns
* :ref:`Monkey patching utility to get pure Python modules to cooperate <monkey-patching>`
__ gevent.html#gevent.Greenlet
.. _gevent: http://gevent.org
.. _coroutine: http://en.wikipedia.org/wiki/Coroutine
.. _Python: http://www.python.org
.. _greenlet: http://codespeak.net/py/0.9.2/greenlet.html
.. _libevent: http://monkey.org/~provos/libevent/
examples
--------
Browse ``examples/`` folder at bitbucket_ or `google code`_.
.. _bitbucket: http://bitbucket.org/denis/gevent/src/tip/examples/
.. _google code: http://code.google.com/p/gevent/source/browse/#hg/examples
documentation
-------------
INSERT-contentstable.html
get gevent
----------
The latest release (|version|) is available on the `Python Package Index.`_
.. _Python Package Index.: http://pypi.python.org/pypi/gevent
The current development version is available in a Mercurial repository:
* at bitbucket: http://bitbucket.org/denis/gevent/
* on google code: http://code.google.com/p/gevent/
installation
------------
Install the dependencies:
* greenlet: http://pypi.python.org/pypi/greenlet (it can be installed with ``easy_install greenlet``)
* libevent 1.4.x: http://monkey.org/~provos/libevent/
gevent runs on Python 2.4 and higher.
similar projects
----------------
* `Eventlet <http://eventlet.net/>`_
* `Concurrence <http://opensource.hyves.org/concurrence/>`_
* `StacklessSocket <http://code.google.com/p/stacklessexamples/wiki/StacklessNetworking>`_
feedback
--------
Use `Issue Tracker on Google Code`__ for the bug reports.
Contact me directly at Denis.Bilenko@gmail.com.
__ http://code.google.com/p/gevent/issues/list
Introduction
============
The following example shows how to run tasks concurrently.
>>> import gevent
>>> from gevent import socket
>>> urls = ['www.google.com', 'www.example.com', 'www.python.org']
>>> jobs = [gevent.spawn(socket.gethostbyname, url) for url in urls]
>>> gevent.joinall(jobs, timeout=2)
>>> [job.value for job in jobs]
['74.125.79.106', '208.77.188.166', '82.94.164.162']
After the jobs have been spawned, :func:`gevent.joinall` waits for them to complete,
no longer than 2 seconds though. The results are then collected by checking
:attr:`gevent.Greenlet.value` property. The :func:`gevent.socket.gethostbyname` function
has the same interface as the standard :func:`socket.gethostbyname` but it does not block
the whole interpreter and thus lets the other greenlets to proceed with their requests as well.
If there was an error during execution it won't escape greenlet's boundaries.
An unhandled error results in a stacktrace being printed complemented by
failed function signature and arguments:
>>> gevent.spawn(lambda : 1/0).join() # join() waits for the greenlet to complete
Traceback (most recent call last):
...
ZeroDivisionError: integer division or modulo by zero
<Greenlet at 0x7f2ec3a4e490: <function <lambda> at 0x7f2ec3aa8398>> failed with ZeroDivisionError
.. _monkey-patching:
Monkey patching
---------------
The example above used :mod:`gevent.socket` for socket operations. If the standard :mod:`socket`
module was used it would took it 3 times longer to complete because the DNS requests would
be sequential. Using the standard socket module inside greenlets makes gevent rather
pointless, so what about module and packages that are built on top of :mod:`socket`?
That's what monkey patching for. The functions in :mod:`gevent.monkey` carefully
replace functions and classes in the standard :mod:`socket` module with their cooperative
counterparts. That way even the modules that are unaware of gevent can benefit from running
in multi-greenlet environment.
>>> from gevent import monkey; monkey.patch_socket()
>>> import urllib2 # it's usable from multiple greenlets now
See `examples/concurrent_download.py`__
__ http://bitbucket.org/denis/gevent/src/tip/examples/concurrent_download.py
Usage notes
-----------
Note, that greenlets are cooperatively scheduled. This means that a greenlet
must give up control or all other greenlets won't get a chance to execute.
This typically is not an issue for I/O bound app, but one should be aware
of that if doing something CPU intensive or that otherwise does blocking I/O
bypassing libevent loop.
.. currentmodule:: gevent.hub
Unlike other network libraries and similar to eventlet_, gevent starts
the event loop implicitly in a dedicated greenlet. There's no ``reactor`` that
you must ``run()`` or ``dispatch()`` function to call. When a function from
gevent API wants to block, it obtains the :class:`Hub` - a greenlet
that runs the event loop - and switches to it. If there's no :class:`Hub`
instance yet, one is created on the fly.
.. currentmodule:: gevent
The blocking gevent API does not work in the :class:`Hub <hub.Hub>` greenlet. Typically
it's not a problem as most of the library takes care not to run the user-supplied
callback in the :class:`Hub <hub.Hub>`. The exception is :meth:`Greenlet.rawlink`
and :meth:`Event.rawlink <event.Event.rawlink>` methods as well as everything
in the :mod:`gevent.core` module.
.. _eventlet: http://eventlet.net
@ECHO OFF
REM Command file for Sphinx documentation
set SPHINXBUILD=sphinx-build
set BUILDDIR=_build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. changes to make an overview over all changed/added/deprecated items
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
goto end
)
if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\gevent.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\gevent.ghc
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)
:end
from sphinx.ext.autodoc import cut_lines
from sphinx.ext import intersphinx
from docutils import nodes
noisy = False
message_cache = set()
def missing_reference(app, env, node, contnode):
"""Search the index for missing references.
For example, resolve :class:`Event` to :class:`Event <gevent.event.Event>`"""
# XXX methods and functions resolved by this function miss their ()
if intersphinx.missing_reference(app, env, node, contnode) is not None:
# is there a better way to give intersphinx a bigger priority?
return
env = app.builder.env
type = node['reftype']
target = node['reftarget']
modname = node['modname']
classname = node['classname']
if modname and classname:
return
def new_reference(refuri, reftitle):
newnode = nodes.reference('', '')
newnode['refuri'] = refuri
newnode['reftitle'] = reftitle
newnode['class'] = 'external-xref'
newnode.append(contnode)
msg = 'Resolved missing-reference: :%5s:`%s` -> %s' % (type, target, refuri)
if msg not in message_cache:
print msg
message_cache.add(msg)
return newnode
#print [type, target, modname, classname]
for docname, items in env.indexentries.iteritems():
if noisy:
print docname
for (i_type, i_string, i_target, i_aliasname) in items:
if noisy:
print '---', [i_type, i_string, i_target, i_aliasname]
if i_aliasname.endswith(target):
stripped_aliasname = i_aliasname[len(docname):]
if stripped_aliasname:
assert stripped_aliasname[0] == '.', repr(stripped_aliasname)
stripped_aliasname = stripped_aliasname[1:]
if stripped_aliasname == target:
if noisy:
print '--- found %s %s in %s' % (type, target, i_aliasname)
return new_reference(docname + '.html#' + i_aliasname, i_aliasname)
if type == 'mod':
modules = [x for x in env.indexentries.keys() if x.startswith('gevent.')]
target = 'gevent.' + target
if target in modules:
return new_reference(target + '.html', target)
def setup(app):
app.connect('missing-reference', missing_reference)
app.connect('autodoc-process-docstring', cut_lines(2, what=['module']))
API reference
-------------
.. toctree::
gevent
gevent.event
gevent.queue
gevent.socket
gevent.monkey
gevent.http
gevent.wsgi
gevent.pool
gevent.util
gevent.core
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