Source code for pyams_utils.context

#
# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#

"""PyAMS_utils.context module

This module provides a "context" selector which can be used as Pyramid's subscriber
predicate. Matching argument can be a class or an interface: for subscriber to be actually called,
subscriber's argument should inherit from it (if it's a class) or implement it (if it's an
interface).
"""

import sys
from contextlib import contextmanager
from io import StringIO


__docformat__ = 'restructuredtext'


[docs]@contextmanager def capture(func, *args, **kwargs): """Context manager used to capture standard output""" out, sys.stdout = sys.stdout, StringIO() try: func(*args, **kwargs) sys.stdout.seek(0) yield sys.stdout.read() finally: sys.stdout = out
[docs]@contextmanager def capture_stderr(func, *args, **kwargs): """Context manager used to capture error output""" err, sys.stderr = sys.stderr, StringIO() try: func(*args, **kwargs) sys.stderr.seek(0) yield sys.stderr.read() finally: sys.stderr = err
[docs]class ContextSelector: # pylint: disable=too-few-public-methods """Interface based context selector This selector can be used as a predicate to define a class or an interface that the context must inherit from or implement for the subscriber to be called:: .. code-block:: python from zope.lifecycleevent.interfaces import IObjectModifiedEvent from pyams_site.interfaces import ISiteRoot @subscriber(IObjectModifiedEvent, context_selector=ISiteRoot) def siteroot_modified_event_handler(event): '''This is an event handler for an ISiteRoot object modification event''' """ def __init__(self, ifaces, config): # pylint: disable=unused-argument if not isinstance(ifaces, (list, tuple, set)): ifaces = (ifaces,) self.interfaces = ifaces
[docs] def text(self): """Return selector """ return 'context_selector = %s' % str(self.interfaces)
phash = text def __call__(self, event): for intf in self.interfaces: try: if intf.providedBy(event.object): return True except (AttributeError, TypeError): if isinstance(event.object, intf): return True return False