diff --git a/pluggy/__init__.py b/pluggy/__init__.py index c60c384c..1de08823 100644 --- a/pluggy/__init__.py +++ b/pluggy/__init__.py @@ -1,15 +1,12 @@ -import sys import inspect import warnings -from .callers import _MultiCall, HookCallError, _raise_wrapfail +from .callers import _MultiCall, HookCallError, _raise_wrapfail, _Result __version__ = '0.5.0' __all__ = ["PluginManager", "PluginValidationError", "HookCallError", "HookspecMarker", "HookimplMarker"] -_py3 = sys.version_info > (3, 0) - class PluginValidationError(Exception): """ plugin failed validation. """ @@ -83,7 +80,7 @@ def __call__(self, function=None, hookwrapper=False, optionalhook=False, If hookwrapper is True the hook implementations needs to execute exactly one "yield". The code before the yield is run early before any non-hookwrapper function is run. The code after the yield is run after all non-hookwrapper - function have run. The yield receives an ``_CallOutcome`` object representing + function have run. The yield receives a ``_Result`` object representing the exception or result outcome of the inner calls (including other hookwrapper calls). @@ -172,14 +169,14 @@ def get(self, name): def _wrapped_call(wrap_controller, func): """ Wrap calling to a function with a generator which needs to yield exactly once. The yield point will trigger calling the wrapped function - and return its _CallOutcome to the yield point. The generator then needs + and return its ``_Result`` to the yield point. The generator then needs to finish (raise StopIteration) in order for the wrapped call to complete. """ try: next(wrap_controller) # first yield except StopIteration: _raise_wrapfail(wrap_controller, "did not yield") - call_outcome = _CallOutcome(func) + call_outcome = _Result(func) try: wrap_controller.send(call_outcome) _raise_wrapfail(wrap_controller, "has second yield") @@ -188,39 +185,6 @@ def _wrapped_call(wrap_controller, func): return call_outcome.get_result() -class _CallOutcome(object): - """ Outcome of a function call, either an exception or a proper result. - Calling the ``get_result`` method will return the result or reraise - the exception raised when the function was called. """ - excinfo = None - - def __init__(self, func): - try: - self.result = func() - except BaseException: - self.excinfo = sys.exc_info() - - def force_result(self, result): - self.result = result - self.excinfo = None - - def get_result(self): - if self.excinfo is None: - return self.result - else: - ex = self.excinfo - if _py3: - raise ex[1].with_traceback(ex[2]) - _reraise(*ex) # noqa - - -if not _py3: - exec(""" -def _reraise(cls, val, tb): - raise cls, val, tb -""") - - class _TracedHookExecution(object): def __init__(self, pluginmanager, before, after): self.pluginmanager = pluginmanager @@ -232,7 +196,7 @@ def __init__(self, pluginmanager, before, after): def __call__(self, hook, hook_impls, kwargs): self.before(hook.name, hook_impls, kwargs) - outcome = _CallOutcome(lambda: self.oldcall(hook, hook_impls, kwargs)) + outcome = _Result.from_call(lambda: self.oldcall(hook, hook_impls, kwargs)) self.after(outcome, hook.name, hook_impls, kwargs) return outcome.get_result() @@ -481,7 +445,7 @@ def add_hookcall_monitoring(self, before, after): of HookImpl instances and the keyword arguments for the hook call. ``after(outcome, hook_name, hook_impls, kwargs)`` receives the - same arguments as ``before`` but also a :py:class:`_CallOutcome`` object + same arguments as ``before`` but also a :py:class:`_Result`` object which represents the result of the overall hook call. """ return _TracedHookExecution(self, before, after).undo diff --git a/pluggy/callers.py b/pluggy/callers.py index c7eb0111..abe36e78 100644 --- a/pluggy/callers.py +++ b/pluggy/callers.py @@ -24,11 +24,21 @@ class HookCallError(Exception): """ Hook was called wrongly. """ -class Result(object): +class _Result(object): def __init__(self, result, excinfo): self.result = result self.excinfo = excinfo + @classmethod + def from_call(cls, func): + result = excinfo = None + try: + result = func() + except BaseException: + excinfo = sys.exc_info() + + return cls(result, excinfo) + def force_result(self, result): self.result = result self.excinfo = None @@ -86,7 +96,7 @@ def execute(self): except BaseException: excinfo = sys.exc_info() finally: - outcome = Result(results, excinfo) + outcome = _Result(results, excinfo) # run all wrapper post-yield blocks for gen in reversed(teardowns):