Commit 712b69b4 authored by Jason Madden's avatar Jason Madden

Some minor documentation cleanup for intro and basics. Prepping for some re-org.

parent 35348992
...@@ -243,3 +243,7 @@ import gevent.socket ...@@ -243,3 +243,7 @@ import gevent.socket
for item in gevent.socket.__all__[:]: for item in gevent.socket.__all__[:]:
if getattr(gevent.socket, item) is getattr(socket, item, None): if getattr(gevent.socket, item) is getattr(socket, item, None):
gevent.socket.__all__.remove(item) gevent.socket.__all__.remove(item)
if not hasattr(gevent.socket, '_fileobject'):
# Python 3 building Python 2 docs.
gevent.socket._fileobject = object()
...@@ -13,18 +13,20 @@ Greenlet objects ...@@ -13,18 +13,20 @@ Greenlet objects
:class:`Greenlet` is a light-weight cooperatively-scheduled execution unit. :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`: To start a new greenlet, pass the target function and its arguments to
:class:`Greenlet` constructor and call :meth:`Greenlet.start`:
>>> g = Greenlet(myfunction, 'arg1', 'arg2', kwarg1=1) >>> g = Greenlet(myfunction, 'arg1', 'arg2', kwarg1=1)
>>> g.start() >>> g.start()
or use classmethod :meth:`spawn` which is a shortcut that does the same: or use classmethod :meth:`Greenlet.spawn` which is a shortcut that
does the same:
>>> g = Greenlet.spawn(myfunction, 'arg1', 'arg2', kwarg1=1) >>> g = Greenlet.spawn(myfunction, 'arg1', 'arg2', kwarg1=1)
To subclass a :class:`Greenlet`, override its ``_run()`` method and To subclass a :class:`Greenlet`, override its ``_run()`` method and
call ``Greenlet.__init__(self)`` in :meth:`__init__`: It also a good call ``Greenlet.__init__(self)`` in the subclass ``__init__``. It also a good
idea to override :meth:`__str__`: if :meth:`_run` raises an exception, idea to override :meth:`Greenlet.__str__`: if ``_run`` raises an exception,
its string representation will be printed after the traceback it its string representation will be printed after the traceback it
generated. generated.
...@@ -37,9 +39,11 @@ generated. ...@@ -37,9 +39,11 @@ generated.
.. autoattribute:: Greenlet.exception .. autoattribute:: Greenlet.exception
.. autoattribute:: Greenlet.minimal_ident .. autoattribute:: Greenlet.minimal_ident
.. autoattribute:: Greenlet.name .. autoattribute:: Greenlet.name
.. autoattribute:: Greenlet.dead
.. rubric:: Methods .. rubric:: Methods
.. automethod:: Greenlet.spawn
.. automethod:: Greenlet.ready .. automethod:: Greenlet.ready
.. automethod:: Greenlet.successful .. automethod:: Greenlet.successful
.. automethod:: Greenlet.start .. automethod:: Greenlet.start
...@@ -52,6 +56,7 @@ generated. ...@@ -52,6 +56,7 @@ generated.
.. automethod:: Greenlet.link_exception(callback) .. automethod:: Greenlet.link_exception(callback)
.. automethod:: Greenlet.rawlink .. automethod:: Greenlet.rawlink
.. automethod:: Greenlet.unlink .. automethod:: Greenlet.unlink
.. automethod:: Greenlet.__str__
Boolean Contexts Boolean Contexts
---------------- ----------------
...@@ -65,12 +70,12 @@ It's possible to use it like this:: ...@@ -65,12 +70,12 @@ It's possible to use it like this::
>>> while g: >>> while g:
# do something while g is alive # do something while g is alive
The Greenlet's ``__nonzero__`` is an improvement on greenlet's The Greenlet's boolean value is an improvement on the raw
``__nonzero__``. The greenlet's :meth:`__nonzero__ :class:`greenlet's <greenlet.greenlet>` boolean value. The raw
<greenlet.greenlet.__nonzero__>` returns False if greenlet has not greenlet's boolean value returns False if the greenlet has not been
been switched to yet or is already dead. While the latter is OK, the switched to yet or is already dead. While the latter is OK, the former
former is not good, because a just spawned Greenlet has not been is not good, because a just spawned Greenlet has not been switched to
switched to yet and thus would evaluate to False. yet and thus would evaluate to False.
Raw greenlet Methods Raw greenlet Methods
-------------------- --------------------
...@@ -86,6 +91,10 @@ __ https://greenlet.readthedocs.io/en/latest/#instantiation ...@@ -86,6 +91,10 @@ __ https://greenlet.readthedocs.io/en/latest/#instantiation
.. _switching: https://greenlet.readthedocs.io/en/latest/#switching .. _switching: https://greenlet.readthedocs.io/en/latest/#switching
.. _throw: https://greenlet.readthedocs.io/en/latest/#methods-and-attributes-of-greenlets .. _throw: https://greenlet.readthedocs.io/en/latest/#methods-and-attributes-of-greenlets
.. class:: greenlet.greenlet
The base class from which `Greenlet` descends.
.. exception:: GreenletExit .. exception:: GreenletExit
A special exception that kills the greenlet silently. A special exception that kills the greenlet silently.
...@@ -192,3 +201,6 @@ Configuration ...@@ -192,3 +201,6 @@ Configuration
============= =============
.. autoclass:: gevent._config.Config .. autoclass:: gevent._config.Config
.. LocalWords: Greenlet GreenletExit Greenlet's greenlet's
.. LocalWords: automethod
...@@ -38,6 +38,14 @@ Python 2 and Python 3, respectively. ...@@ -38,6 +38,14 @@ Python 2 and Python 3, respectively.
Their organization is an implementation detail that may change at Their organization is an implementation detail that may change at
any time. any time.
.. autofunction:: gevent.socket.gethostbyname
.. class:: socket
The cooperative socket object. See the version documentation for
specifics.
.. toctree:: .. toctree::
Python 3 interface <gevent._socket3> Python 3 interface <gevent._socket3>
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
:mod:`gevent.ssl` -- Secure Sockets Layer (SSL/TLS) module :mod:`gevent.ssl` -- Secure Sockets Layer (SSL/TLS) module
==================================================================== ====================================================================
.. module:: gevent.ssl
This module provides SSL/TLS operations and some related functions. The This module provides SSL/TLS operations and some related functions. The
API of the functions and classes matches the API of the corresponding API of the functions and classes matches the API of the corresponding
items in the standard :mod:`ssl` module exactly, but the items in the standard :mod:`ssl` module exactly, but the
...@@ -17,6 +19,11 @@ Python 3, Python 2.7.9 and above, and Python 2.7.8 and below, respectively. ...@@ -17,6 +19,11 @@ Python 3, Python 2.7.9 and above, and Python 2.7.8 and below, respectively.
Their organization is an implementation detail that may change at Their organization is an implementation detail that may change at
any time. any time.
.. class:: SSLObject
The gevent-cooperative SSL object. See the version-specific
documentation for details.
.. toctree:: .. toctree::
Python 3 interface <gevent._ssl3> Python 3 interface <gevent._ssl3>
......
...@@ -26,10 +26,11 @@ Installation and Requirements ...@@ -26,10 +26,11 @@ Installation and Requirements
is supported, and versions 3.4, 3.5 and 3.6 of Python 3 are supported. is supported, and versions 3.4, 3.5 and 3.6 of Python 3 are supported.
(Users of older versions of Python 2 need to install gevent 1.0.x (Users of older versions of Python 2 need to install gevent 1.0.x
(2.5), 1.1.x (2.6) or 1.2.x (<=2.7.8); gevent 1.2 can be installed on (2.5), 1.1.x (2.6) or 1.2.x (<=2.7.8); gevent 1.2 can be installed on
Python 3.3.) gevent requires the greenlet__ library. Python 3.3.) gevent requires the greenlet__ library and will install
the `cffi`_ library by default on Windows.
.. note:: Python 3.3 is no longer actively supported in gevent 1.3. .. note:: Python 3.3 is no longer actively supported in gevent 1.2
since it is not supported by the Python developers. However, because it is not supported by the Python developers. However,
it should continue to work with gevent 1.2 with the same it should continue to work with gevent 1.2 with the same
level of support as gevent 1.1. For Python 3.3, version level of support as gevent 1.1. For Python 3.3, version
3.3.5 or newer is required to use the gevent's SSL support 3.3.5 or newer is required to use the gevent's SSL support
...@@ -43,10 +44,10 @@ strongly recommended. On PyPy, there are no external dependencies. ...@@ -43,10 +44,10 @@ strongly recommended. On PyPy, there are no external dependencies.
gevent is tested on Windows, OS X, and Linux, and should run on most gevent is tested on Windows, OS X, and Linux, and should run on most
other Unix-like operating systems (e.g., FreeBSD, Solaris, etc.) other Unix-like operating systems (e.g., FreeBSD, Solaris, etc.)
.. note:: On Windows using the default libev backend, gevent is .. note:: On Windows using the libev backend, gevent is
limited to a maximum of 1024 open sockets due to limited to a maximum of 1024 open sockets due to
`limitations in libev`_. This limitation should not exist `limitations in libev`_. This limitation should not exist
with the libuv backend. with the default libuv backend.
gevent and greenlet can both be installed with `pip`_, e.g., ``pip gevent and greenlet can both be installed with `pip`_, e.g., ``pip
install gevent``. On Windows, OS X, and Linux, both gevent and greenlet are install gevent``. On Windows, OS X, and Linux, both gevent and greenlet are
...@@ -188,7 +189,7 @@ The event loop provided by libev uses the fastest polling mechanism ...@@ -188,7 +189,7 @@ The event loop provided by libev uses the fastest polling mechanism
available on the system by default. Please read the `libev documentation`_ for more available on the system by default. Please read the `libev documentation`_ for more
information. information.
.. 1.3: libuv update needed .. caution:: This section needs to be updated for gevent 1.3 and libuv.
.. As of 1.1 or before, we set the EVFLAG_NOENV so this isn't possible any more. .. As of 1.1 or before, we set the EVFLAG_NOENV so this isn't possible any more.
...@@ -201,13 +202,14 @@ information. ...@@ -201,13 +202,14 @@ information.
.. _`libev documentation`: http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#FUNCTIONS_CONTROLLING_EVENT_LOOPS .. _`libev documentation`: http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#FUNCTIONS_CONTROLLING_EVENT_LOOPS
.. 1.3: libuv update needed
The libev API is available under the :mod:`gevent.core` module. Note that The libev API is available under the :mod:`gevent.core` module. Note
the callbacks supplied to the libev API are run in the :class:`~gevent.hub.Hub` that the callbacks supplied to the libev API are run in the
greenlet and thus cannot use the synchronous gevent API. It is possible to :class:`~gevent.hub.Hub` greenlet and thus cannot use the synchronous
use the asynchronous API there, like :func:`gevent.spawn` and gevent API. It is possible to use the asynchronous API there, like
:meth:`gevent.event.Event.set`. :func:`gevent.spawn` and :meth:`gevent.event.Event.set`.
.. caution:: This section needs to be updated for gevent 1.3 and libuv.
Cooperative multitasking Cooperative multitasking
...@@ -218,10 +220,10 @@ Cooperative multitasking ...@@ -218,10 +220,10 @@ Cooperative multitasking
The greenlets all run in the same OS thread and are scheduled The greenlets all run in the same OS thread and are scheduled
cooperatively. This means that until a particular greenlet gives up cooperatively. This means that until a particular greenlet gives up
control, (by calling a blocking function that will switch to the control, (by calling a blocking function that will switch to the
:class:`~gevent.hub.Hub`), other greenlets won't get a chance to run. This is :class:`~gevent.hub.Hub`), other greenlets won't get a chance to run.
typically not an issue for an I/O bound app, but one should be aware This is typically not an issue for an I/O bound app, but one should be
of this when doing something CPU intensive, or when calling blocking aware of this when doing something CPU intensive, or when calling
I/O functions that bypass the libev event loop. blocking I/O functions that bypass the libev event loop.
.. tip:: Even some apparently cooperative functions, like .. tip:: Even some apparently cooperative functions, like
:func:`gevent.sleep`, can temporarily take priority over :func:`gevent.sleep`, can temporarily take priority over
...@@ -235,8 +237,10 @@ explict), thus traditional synchronization devices like the ...@@ -235,8 +237,10 @@ explict), thus traditional synchronization devices like the
often. Other abstractions from threading and multiprocessing remain often. Other abstractions from threading and multiprocessing remain
useful in the cooperative world: useful in the cooperative world:
- :class:`~event.Event` allows one to wake up a number of greenlets that are calling :meth:`~event.Event.wait` method. - :class:`~event.Event` allows one to wake up a number of greenlets
- :class:`~event.AsyncResult` is similar to :class:`~event.Event` but allows passing a value or an exception to the waiters. that are calling :meth:`~event.Event.wait` method.
- :class:`~event.AsyncResult` is similar to :class:`~event.Event` but
allows passing a value or an exception to the waiters.
- :class:`~queue.Queue` and :class:`~queue.JoinableQueue`. - :class:`~queue.Queue` and :class:`~queue.JoinableQueue`.
...@@ -245,14 +249,18 @@ Lightweight pseudothreads ...@@ -245,14 +249,18 @@ Lightweight pseudothreads
.. currentmodule:: gevent .. currentmodule:: gevent
New greenlets are spawned by creating a :class:`~Greenlet` instance and calling its :meth:`start <gevent.Greenlet.start>` New greenlets are spawned by creating a :class:`~Greenlet` instance
method. (The :func:`gevent.spawn` function is a shortcut that does exactly that). The :meth:`start <gevent.Greenlet.start>` and calling its :meth:`start <gevent.Greenlet.start>` method. (The
method schedules a switch to the greenlet that will happen as soon as the current greenlet gives up control. :func:`gevent.spawn` function is a shortcut that does exactly that).
If there is more than one active greenlet, they will be executed one The :meth:`start <gevent.Greenlet.start>` method schedules a switch to
by one, in an undefined order as they each give up control to the :class:`~gevent.hub.Hub`. the greenlet that will happen as soon as the current greenlet gives up
control. If there is more than one active greenlet, they will be
executed one by one, in an undefined order as they each give up
control to the :class:`~gevent.hub.Hub`.
If there is an error during execution it won't escape the greenlet's boundaries. An unhandled error results If there is an error during execution it won't escape the greenlet's
in a stacktrace being printed, annotated by the failed function's signature and arguments: boundaries. An unhandled error results in a stacktrace being printed,
annotated by the failed function's signature and arguments:
>>> gevent.spawn(lambda : 1/0) >>> gevent.spawn(lambda : 1/0)
>>> gevent.sleep(1) >>> gevent.sleep(1)
...@@ -269,12 +277,12 @@ The traceback is asynchronously printed to ``sys.stderr`` when the greenlet dies ...@@ -269,12 +277,12 @@ The traceback is asynchronously printed to ``sys.stderr`` when the greenlet dies
- :meth:`kill <gevent.Greenlet.kill>` -- interrupts greenlet's execution; - :meth:`kill <gevent.Greenlet.kill>` -- interrupts greenlet's execution;
- :meth:`get <gevent.Greenlet.get>` -- returns the value returned by greenlet or re-raises the exception that killed it. - :meth:`get <gevent.Greenlet.get>` -- returns the value returned by greenlet or re-raises the exception that killed it.
It is possible to customize the string printed after the traceback by subclassing the :class:`~gevent.Greenlet` class It is possible to customize the string printed after the traceback by
and redefining its ``__str__`` method. subclassing the :class:`~gevent.Greenlet` class and redefining its
``__str__`` method.
To subclass a :class:`gevent.Greenlet`, override its To subclass a :class:`gevent.Greenlet`, override its ``_run`` method
:meth:`gevent.Greenlet._run` method and call and call ``Greenlet.__init__(self)`` in ``__init__``::
``Greenlet.__init__(self)`` in ``__init__``::
class MyNoopGreenlet(Greenlet): class MyNoopGreenlet(Greenlet):
...@@ -288,8 +296,9 @@ To subclass a :class:`gevent.Greenlet`, override its ...@@ -288,8 +296,9 @@ To subclass a :class:`gevent.Greenlet`, override its
def __str__(self): def __str__(self):
return 'MyNoopGreenlet(%s)' % self.seconds return 'MyNoopGreenlet(%s)' % self.seconds
Greenlets can be killed synchronously from another greenlet. Killing will resume the sleeping greenlet, but instead Greenlets can be killed synchronously from another greenlet. Killing
of continuing execution, a :exc:`GreenletExit` will be raised. will resume the sleeping greenlet, but instead of continuing
execution, a :exc:`GreenletExit` will be raised.
>>> g = MyNoopGreenlet(4) >>> g = MyNoopGreenlet(4)
>>> g.start() >>> g.start()
...@@ -297,9 +306,12 @@ of continuing execution, a :exc:`GreenletExit` will be raised. ...@@ -297,9 +306,12 @@ of continuing execution, a :exc:`GreenletExit` will be raised.
>>> g.dead >>> g.dead
True True
The :exc:`GreenletExit` exception and its subclasses are handled differently than other exceptions. The :exc:`GreenletExit` exception and its subclasses are handled
Raising :exc:`~GreenletExit` is not considered an exceptional situation, so the traceback is not printed. differently than other exceptions. Raising :exc:`~GreenletExit` is not
The :exc:`~GreenletExit` is returned by :meth:`get <gevent.Greenlet.get>` as if it were returned by the greenlet, not raised. considered an exceptional situation, so the traceback is not printed.
The :exc:`~GreenletExit` is returned by :meth:`get
<gevent.Greenlet.get>` as if it were returned by the greenlet, not
raised.
The :meth:`kill <gevent.Greenlet.kill>` method can accept a custom exception to be raised: The :meth:`kill <gevent.Greenlet.kill>` method can accept a custom exception to be raised:
...@@ -323,24 +335,24 @@ killing will remain blocked forever). ...@@ -323,24 +335,24 @@ killing will remain blocked forever).
<gevent.Greenlet.kill>` is not defined. See that function's <gevent.Greenlet.kill>` is not defined. See that function's
documentation for more details. documentation for more details.
.. caution:: Use care when killing greenlets, especially arbitrary .. caution::
greenlets spawned by a library or otherwise executing Use care when killing greenlets, especially arbitrary
code you are not familiar with. If the code being greenlets spawned by a library or otherwise executing code you are
executed is not prepared to deal with exceptions, object not familiar with. If the code being executed is not prepared to
state may be corrupted. For example, if it has acquired a deal with exceptions, object state may be corrupted. For example,
``Lock`` but *does not* use a ``finally`` block to if it has acquired a ``Lock`` but *does not* use a ``finally``
release it, killing the greenlet at the wrong time could block to release it, killing the greenlet at the wrong time could
result in the lock being permanently locked:: result in the lock being permanently locked::
def func(): def func():
# DON'T DO THIS # DON'T DO THIS
lock.acquire() lock.acquire()
socket.sendall(data) # This could raise many exceptions, including GreenletExit socket.sendall(data) # This could raise many exceptions, including GreenletExit
lock.release() lock.release()
`This document `This document
<http://docs.oracle.com/javase/8/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html>`_ <http://docs.oracle.com/javase/8/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html>`_
describes a similar situation for threads. describes a similar situation for threads.
Timeouts Timeouts
======== ========
...@@ -348,7 +360,7 @@ Timeouts ...@@ -348,7 +360,7 @@ Timeouts
Many functions in the gevent API are synchronous, blocking the current Many functions in the gevent API are synchronous, blocking the current
greenlet until the operation is done. For example, :meth:`kill greenlet until the operation is done. For example, :meth:`kill
<gevent.Greenlet.kill>` waits until the target greenlet is <gevent.Greenlet.kill>` waits until the target greenlet is
:attr:`~gevent.greenlet.Greenlet.dead` before returning [#f1]_. Many of :attr:`~gevent.Greenlet.dead` before returning [#f1]_. Many of
those functions can be made asynchronous by passing the keyword argument those functions can be made asynchronous by passing the keyword argument
``block=False``. ``block=False``.
...@@ -360,9 +372,9 @@ argument, which specifies a limit on how long the function can block ...@@ -360,9 +372,9 @@ argument, which specifies a limit on how long the function can block
The :class:`socket <gevent.socket.socket>` and :class:`SSLObject The :class:`socket <gevent.socket.socket>` and :class:`SSLObject
<gevent.ssl.SSLObject>` instances can also have a timeout, set by the <gevent.ssl.SSLObject>` instances can also have a timeout, set by the
:meth:`settimeout <gevent.socket.socket.settimeout>` method. :meth:`settimeout <socket.socket.settimeout>` method.
When these are not enough, the :class:`~gevent.timeout.Timeout` class can be used to When these are not enough, the :class:`~gevent.Timeout` class can be used to
add timeouts to arbitrary sections of (cooperative, yielding) code. add timeouts to arbitrary sections of (cooperative, yielding) code.
...@@ -383,4 +395,6 @@ __ http://sdiehl.github.io/gevent-tutorial/ ...@@ -383,4 +395,6 @@ __ http://sdiehl.github.io/gevent-tutorial/
.. rubric:: Footnotes .. rubric:: Footnotes
.. [#f1] This was not the case before 0.13.0, :meth:`kill <gevent.greenlet.Greenlet.kill>` method in 0.12.2 and older was asynchronous by default. .. [#f1] This was not the case before 0.13.0, :meth:`kill <gevent.Greenlet.kill>` method in 0.12.2 and older was asynchronous by default.
.. LocalWords: Greenlets
# Wrapper module for _ssl. Written by Bill Janssen. # Wrapper module for _ssl. Written by Bill Janssen.
# Ported to gevent by Denis Bilenko. # Ported to gevent by Denis Bilenko.
"""SSL wrapper for socket objects on Python 2.7.8 and below. """
SSL wrapper for socket objects on Python 2.7.8 and below.
For the documentation, refer to :mod:`ssl` module manual. For the documentation, refer to :mod:`ssl` module manual.
This module implements cooperative SSL socket wrappers. This module implements cooperative SSL socket wrappers.
.. deprecated:: 1.3
This module is not secure. Support for Python versions
with only this level of SSL will be dropped in gevent 1.4.
""" """
from __future__ import absolute_import from __future__ import absolute_import
......
...@@ -367,6 +367,7 @@ class Greenlet(greenlet): ...@@ -367,6 +367,7 @@ class Greenlet(greenlet):
# oops - pypy's .dead relies on __nonzero__ which we overriden above # oops - pypy's .dead relies on __nonzero__ which we overriden above
@property @property
def dead(self): def dead(self):
"Boolean indicating that the greenlet is dead and will not run again."
if self._greenlet__main: if self._greenlet__main:
return False return False
if self.__start_cancelled_by_kill() or self.__started_but_aborted(): if self.__start_cancelled_by_kill() or self.__started_but_aborted():
...@@ -376,6 +377,7 @@ class Greenlet(greenlet): ...@@ -376,6 +377,7 @@ class Greenlet(greenlet):
else: else:
@property @property
def dead(self): def dead(self):
"Boolean indicating that the greenlet is dead and will not run again."
return self.__start_cancelled_by_kill() or self.__started_but_aborted() or greenlet.dead.__get__(self) return self.__start_cancelled_by_kill() or self.__started_but_aborted() or greenlet.dead.__get__(self)
def __never_started_or_killed(self): def __never_started_or_killed(self):
......
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