This is a pre-production deployment of Warehouse, however changes made here WILL affect the production instance of PyPI.
Latest Version Dependencies status unknown Test status unknown Test coverage unknown
Project Description
author:Alberto Berti
contact:alberto@metapensiero.it
license:GNU General Public License version 3 or later

Handle coroutines from synchronous functions or methods (like special methods)

Goal

This package helps handling such cases when there is a side effect that is coded as a coroutine and the code block that needs it cannot be run as a coroutine.

The case is e. g. when a coroutine is called from an external package or a Python special method.

This package will give you the tools to ensure that even if the computation is not immediate, the execution of the coroutine(s) is guaranteed to happen in the context of the coroutine that is calling the special method.

A package that works in tandem with this is metapensiero.signal

Installation

To install the package execute the following command:

$ pip install metapensiero.asyncio.transaction

Usage

Given a scenario where a coroutine is called from the __setattr___ method, this is how to deal with the situation:

import asyncio
from metapensiero.async import transaction

@asyncio.coroutine
def publish(value):
   # do something async

class Example:

    def __setattr__(self, name, value):
        trans = transaction.get()
        trans.add(publish(value))
        super().__setattr__(name, value)

@asyncio.coroutine
def external_coro():
    inst = Example()
    trans = transaction.begin()
    inst.foo = 'bar'
    yield from trans.end()

In python 3.5, the external_coro can be written as:

async def external_coro():
    inst = Example()
    async with transaction.begin():
        inst.foo = 'bar'

So by taking advantage of the new __aenter__ and __aexit__ methods and awaitable classes.

The coroutines will be scheduled in the order they have been created.

At a certain point, you may want to ensure that all the remaining coroutines are executed you may use the coroutine transaction.wait_all(), doing so will end all the remaining open transactions.

When your code add a coro to the transaction it can also pass a callback as the cback keyword parameter, so it will be called when the stashed coro completes (or is cancelled). This way you can use the return value of the coro like:

import asyncio
from metapensiero.asyncio import transaction

results = []

@asyncio.coroutine
def stashed_coro():
    nonlocal results
    results.append('called stashed_coro')
    return 'result from stashed coro'

class A:

    def __init__(self):
        tran = transaction.get()
        c = stashed_coro()
        tran.add(c, cback=self._init)

    def _init(self, stashed_task):
        nonlocal results
        results.append(stashed_task.result())

@asyncio.coroutine
def external_coro():
    tran = transaction.begin()
    # in py3.5
    # async with tran:
    #     a = A()
    a = A()
    yield from tran.end()

yield from asyncio.gather(
    external_coro()
)

assert len(results) == 2
assert results == ['called stashed_coro', 'result from stashed coro']

Testing

To run the tests you should run the following at the package root:

python setup.py test

Build status

Changes

0.1 (2015-12-15)

  • Adaptation from the rocky sources.
  • First draft documentation.

0.2 (2015-12-16)

  • Document some details about testing.
  • Add some checks on end().

0.3 (2015-12-26)

  • Fix packaging.

0.4 (2015-12-27)

  • Documentation fixes.

0.5 (2016-01-22)

  • Fix behavior when transaction.begin() is called from code not already running in a task.

0.6 (2016-01-27)

  • support a callback function when adding coros to the transaction.

0.7 (2016-02-18)

  • Add a wait() method to suspend the current task while the coros complete without closing the current transaction.
Release History

Release History

0.7

This version

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

0.6

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

Download Files

Download Files

TODO: Brief introduction on what you do with files - including link to relevant help section.

File Name & Checksum SHA256 Checksum Help Version File Type Upload Date
metapensiero.asyncio.transaction-0.7.tar.gz (6.1 kB) Copy SHA256 Checksum SHA256 Source Feb 18, 2016

Supported By

WebFaction WebFaction Technical Writing Elastic Elastic Search Pingdom Pingdom Monitoring Dyn Dyn DNS Sentry Sentry Error Logging CloudAMQP CloudAMQP RabbitMQ Heroku Heroku PaaS Kabu Creative Kabu Creative UX & Design Fastly Fastly CDN DigiCert DigiCert EV Certificate Rackspace Rackspace Cloud Servers DreamHost DreamHost Log Hosting