Trollius and Tulip¶
Differences between Trollius and Tulip¶
Syntax of coroutines¶
The major difference between Trollius and Tulip is the syntax of coroutines:
| Tulip | Trollius |
|---|---|
yield from ... |
yield From(...) |
yield from [] |
yield From(None) |
return |
raise Return() |
return x |
raise Return(x) |
return x, y |
raise Return(x, y) |
Because of this major difference, it was decided to call the module
trollius instead of asyncio. This choice also allows to use Trollius on
Python 3.4 and later. Changing imports is not enough to use Trollius code with
asyncio: the asyncio event loop explicit rejects coroutines using yield
(instead of yield from).
OSError and socket.error exceptions¶
The OSError exception changed in Python 3.3: there are now subclasses like
ConnectionResetError or BlockingIOError. The exception hierarchy also
changed: socket.error is now an alias to OSError. The asyncio
module is written for Python 3.3 and newer and so is based on these new
exceptions.
On Python 3.2 and older, Trollius wraps OSError, IOError,
socket.error and select.error exceptions on operating system and socket
operations to raise more specific exceptions, subclasses of OSError:
trollius.BlockingIOErrortrollius.BrokenPipeErrortrollius.ChildProcessErrortrollius.ConnectionAbortedErrortrollius.ConnectionRefusedErrortrollius.ConnectionResetErrortrollius.FileNotFoundErrortrollius.InterruptedErrortrollius.PermissionError
On Python 3.3 and newer, these symbols are just aliases to builtin exceptions.
Note
ssl.SSLError exceptions are not wrapped to OSError, even if
ssl.SSLError is a subclass of socket.error.
SSLError¶
On Python 3.2 and older, Trollius wraps ssl.SSLError exceptions to raise
more specific exceptions, subclasses of ssl.SSLError, to mimic the Python
3.3:
trollius.SSLEOFErrortrollius.SSLWantReadErrortrollius.SSLWantWriteError
On Python 3.3 and newer, these symbols are just aliases to exceptions of the
ssl module.
trollius.BACKPORT_SSL_ERRORS constant:
Trueifssl.SSLErrorare wrapped to Trollius exceptions (Python 2 older than 2.7.9, or Python 3 older than 3.3),Falseis trollius SSL exceptions are just aliases.
SSLContext¶
Python 3.3 has a new ssl.SSLContext class: see the documentaton of the
ssl.SSLContext class.
On Python 3.2 and older, Trollius has a basic trollius.SSLContext class to
mimic Python 3.3 API, but it only has a few features:
protocol,certfileandkeyfileattributes- read-only
verify_modeattribute: its value isCERT_NONE load_cert_chain(certfile, keyfile)methodwrap_socket(sock, **kw)method: see thessl.wrap_socket()documentation of your Python version for the keyword parameters
Example of missing features:
- no
optionsattribute - the
verify_modeattriubte cannot be modified - no
set_default_verify_paths()method - no “Server Name Indication” (SNI) support
- etc.
On Python 3.2 and older, the trollius SSL transport does not have the
'compression' extra info.
trollius.BACKPORT_SSL_CONTEXT constant:
Trueiftrollius.SSLContextis the backported class (Python 2 older than 2.7.9, or Python 3 older than 3.3),Falseiftrollius.SSLContextis just an alias tossl.SSLContext.
Other differences¶
- Trollius uses the
TROLLIUSDEBUGenvrionment variable instead of thePYTHONASYNCIODEBUGenvrionment variable.TROLLIUSDEBUGvariable is used even if the Python command line option-Eis used. asyncio.subprocesshas noDEVNULLconstant- Python 2 does not support keyword-only parameters.
- If the
concurrent.futuresmodule is missing,BaseEventLoop.run_in_executor()uses a synchronous executor instead of a pool of threads. It blocks until the function returns. For example, DNS resolutions are blocking in this case. - Trollius has more symbols than Tulip for compatibility with Python older than
3.3:
From: part ofyield From(...)syntaxReturn: part ofraise Return(...)syntax
Write code working on Trollius and Tulip¶
Trollius and Tulip are different, especially for coroutines (yield
From(...) vs yield from ...).
To use asyncio or Trollius on Python 2 and Python 3, add the following code at the top of your file:
try:
# Use builtin asyncio on Python 3.4+, or Tulip on Python 3.3
import asyncio
except ImportError:
# Use Trollius on Python <= 3.2
import trollius as asyncio
It is possible to write code working on both projects using only callbacks. This option is used by the following projects which work on Trollius and Tulip:
- AutobahnPython: WebSocket & WAMP for Python, it works on Trollius (Python 2.6 and 2.7), Tulip (Python 3.3) and Python 3.4 (asyncio), and also on Twisted.
- Pulsar: Event driven concurrent
framework for Python. With pulsar you can write asynchronous servers
performing one or several activities in different threads and/or processes.
Trollius 0.3 requires Pulsar 0.8.2 or later. Pulsar uses the
asynciomodule if available, or importtrollius. - Tornado supports Tulip and Trollius since Tornado 3.2: tornado.platform.asyncio — Bridge between asyncio and Tornado. It tries to import asyncio or fallback on importing trollius.
Another option is to provide functions returning Future objects, so the
caller can decide to use callback using fut.add_done_callback(callback) or
to use coroutines (yield From(fut) for Trollius, or yield from fut for
Tulip). This option is used by the aiodns
project for example.
Since Trollius 0.4, it’s possible to use Tulip and Trollius coroutines in the same process. The only limit is that the event loop must be a Trollius event loop.
Note
The Trollius module was called asyncio in Trollius version 0.2. The
module name changed to trollius to support Python 3.4.