# HG changeset patch # User Mads Kiilerich # Date 2020-01-31 19:38:09 # Node ID 9948ed9916c4b6b9bdff021eb29cb56764bdb112 # Parent 141066b8a89a2df5c223d73662198ffa7bb6e8b3 py3: work around incompatibility between pytest, py3 inspect, and tg Work around an issue that has been reported on https://github.com/TurboGears/tg2/issues/118 : .../site-packages/_pytest/doctest.py:381: in _mock_aware_unwrap return real_unwrap(obj, stop=_is_mocked) /usr/lib64/python3.7/inspect.py:511: in unwrap while _is_wrapper(func): /usr/lib64/python3.7/inspect.py:505: in _is_wrapper return hasattr(f, '__wrapped__') and not stop(f) .../site-packages/tg/support/objectproxy.py:19: in __getattr__ return getattr(self._current_obj(), attr) .../site-packages/tg/request_local.py:240: in _current_obj return getattr(context, self.name) .../site-packages/tg/support/objectproxy.py:19: in __getattr__ return getattr(self._current_obj(), attr) .../site-packages/tg/support/registry.py:72: in _current_obj 'thread' % self.____name__) E TypeError: No object (name: context) has been registered for this thread pytest's doctest support is (in _mock_aware_unwrap) using py3 inspect. Inside inspect, _is_wrapper will do an innocent looking: hasattr(f, '__wrapped__') But if the code under test has un (unused) import of a tg context (such as tg.request), it is no longer so innocent. tg will throw: TypeError: No object (name: context) has been registered for this thread (which in py2 would have caught by hasattr, but not in py3.) pytest will thus fail already in the "collecting ..." phase. To work around that, use the hack of pushing a tg context in the top level pytest_configure. diff --git a/conftest.py b/conftest.py --- a/conftest.py +++ b/conftest.py @@ -2,10 +2,19 @@ import os import mock import pytest +import tg here = os.path.dirname(__file__) +# HACK: +def pytest_configure(): + # Register global dummy tg.context to avoid "TypeError: No object (name: context) has been registered for this thread" + tg.request_local.context._push_object(tg.util.bunch.Bunch()) + # could be removed again after use with + # tg.request_local.context._pop_object ... but we keep it around forever as + # a reasonable sentinel + def pytest_ignore_collect(path): # ignore all files outside the 'kallithea' directory if not str(path).startswith(os.path.join(here, 'kallithea')):