xoutil.context - Simple execution contexts

A context manager for execution context flags.

xoutil.context.context

alias of Context

class xoutil.context.Context(*args, **kwargs)[source]

An execution context manager with parameters (or flags).

Use as:

>>> SOME_CONTEXT = object()
>>> from xoutil.context import context
>>> with context(SOME_CONTEXT):
...     if context[SOME_CONTEXT]:
...         print('In context SOME_CONTEXT')
In context SOME_CONTEXT

Note the difference creating the context and checking it: for entering a context you should use ` context(name)`` for testing whether some piece of code is being executed inside a context you should use context[name]; you may also use the syntax name in context.

When an existing context is re-enter, the former one is reused. Nevertheless, the data stored in each context is local to each level.

For example:

>>> with context('A', b=1) as a1:
...   with context('A', b=2) as a2:
...       print(a1 is a2)
...       print(a2['b'])
...   print(a1['b'])
True
2
1

For data access, a mapping interface is provided for all contexts. If a data slot is deleted at some level, upper level is used to read values. Each new written value is stored in current level without affecting upper levels.

For example:

>>> with context('A', b=1) as a1:
...   with context('A', b=2) as a2:
...       del a2['b']
...       print(a2['b'])
1

It is an error to reuse a context directly like in:

>>> with context('A', b=1) as a1:   
...   with a1:
...       pass
Traceback (most recent call last):
...
RuntimeError: Entering the same context level twice! ...

Note

About thread-locals and contexts.

The context uses internally a thread-local instance to keep context stacks in different threads from seeing each other.

If, when this module is imported, greenlet is imported already, greenlet isolation is also warranted (which implies thread isolation).

If you use collaborative multi-tasking based in other framework other than greenlet, you must ensure to monkey patch the threading.local class so that isolation is kept.

In future releases of xoutil, we plan to provide a way to inject a “process” identity manager so that other frameworks be easily integrated.

Changed in version 1.7.1: Changed the test about greenlet. Instead of testing for greenlet to be importable, test it is imported already.

Changed in version 1.6.9: Added direct greenlet isolation and removed the need for gevent.local.

New in version 1.6.8: Uses gevent.local if available to isolate greenlets.