Hi,
I've got this test
import functools
from unittest.mock import Mock
def test_partial(monkeypatch):
monkeypatch.setattr(functools, "partial", Mock())
assert functools.partial.call_count == 1
Running pytest on a clean environment produces:
INTERNALERROR> if isinstance(obj, functools.partial):
INTERNALERROR> TypeError: isinstance() arg 2 must be a type or tuple of types
I'm not sure if this kind of patching is supported.
Note that the error only happens if the assert causes the test to fail, otherwise everything works.
I'm using version 3.4.2
pip list:
attrs (17.4.0)
pip (9.0.1)
pkg-resources (0.0.0)
pluggy (0.6.0)
py (1.5.2)
pytest (3.4.2)
setuptools (38.5.2)
six (1.11.0)
wheel (0.30.0)
OS: Ubuntu 16.04.4 LTS
without a complete traceback we literally have no idea whats happening, please provide a more complete traceback
Thank you for the quick reply. This is the complete trace
============================= test session starts ==============================
platform linux -- Python 3.6.3, pytest-3.4.2, py-1.5.2, pluggy-0.6.0
rootdir: /home/jose/workspace/pytest-test, inifile:
collected 1 item
test_partial.py
INTERNALERROR> Traceback (most recent call last):
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/_pytest/main.py", line 100, in wrap_session
INTERNALERROR> session.exitstatus = doit(config, session) or 0
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/_pytest/main.py", line 138, in _main
INTERNALERROR> config.hook.pytest_runtestloop(session=session)
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/pluggy/__init__.py", line 617, in __call__
INTERNALERROR> return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/pluggy/__init__.py", line 222, in _hookexec
INTERNALERROR> return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/pluggy/__init__.py", line 216, in <lambda>
INTERNALERROR> firstresult=hook.spec_opts.get('firstresult'),
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/pluggy/callers.py", line 201, in _multicall
INTERNALERROR> return outcome.get_result()
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/pluggy/callers.py", line 76, in get_result
INTERNALERROR> raise ex[1].with_traceback(ex[2])
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/pluggy/callers.py", line 180, in _multicall
INTERNALERROR> res = hook_impl.function(*args)
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/_pytest/main.py", line 161, in pytest_runtestloop
INTERNALERROR> item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem)
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/pluggy/__init__.py", line 617, in __call__
INTERNALERROR> return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/pluggy/__init__.py", line 222, in _hookexec
INTERNALERROR> return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/pluggy/__init__.py", line 216, in <lambda>
INTERNALERROR> firstresult=hook.spec_opts.get('firstresult'),
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/pluggy/callers.py", line 201, in _multicall
INTERNALERROR> return outcome.get_result()
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/pluggy/callers.py", line 76, in get_result
INTERNALERROR> raise ex[1].with_traceback(ex[2])
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/pluggy/callers.py", line 180, in _multicall
INTERNALERROR> res = hook_impl.function(*args)
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/_pytest/runner.py", line 62, in pytest_runtest_protocol
INTERNALERROR> runtestprotocol(item, nextitem=nextitem)
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/_pytest/runner.py", line 79, in runtestprotocol
INTERNALERROR> reports.append(call_and_report(item, "call", log))
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/_pytest/runner.py", line 160, in call_and_report
INTERNALERROR> report = hook.pytest_runtest_makereport(item=item, call=call)
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/pluggy/__init__.py", line 617, in __call__
INTERNALERROR> return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/pluggy/__init__.py", line 222, in _hookexec
INTERNALERROR> return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/pluggy/__init__.py", line 216, in <lambda>
INTERNALERROR> firstresult=hook.spec_opts.get('firstresult'),
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/pluggy/callers.py", line 196, in _multicall
INTERNALERROR> gen.send(outcome)
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/_pytest/skipping.py", line 227, in pytest_runtest_makereport
INTERNALERROR> rep = outcome.get_result()
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/pluggy/callers.py", line 76, in get_result
INTERNALERROR> raise ex[1].with_traceback(ex[2])
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/pluggy/callers.py", line 180, in _multicall
INTERNALERROR> res = hook_impl.function(*args)
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/_pytest/runner.py", line 304, in pytest_runtest_makereport
INTERNALERROR> longrepr = item.repr_failure(excinfo)
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/_pytest/python.py", line 598, in repr_failure
INTERNALERROR> return self._repr_failure_py(excinfo, style=style)
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/_pytest/python.py", line 591, in _repr_failure_py
INTERNALERROR> style=style)
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/_pytest/nodes.py", line 266, in _repr_failure_py
INTERNALERROR> self._prunetraceback(excinfo)
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/_pytest/python.py", line 567, in _prunetraceback
INTERNALERROR> code = _pytest._code.Code(get_real_func(self.obj))
INTERNALERROR> File "/home/jose/workspace/pytest-test/.venv/lib/python3.6/site-packages/_pytest/compat.py", line 207, in get_real_func
INTERNALERROR> if isinstance(obj, functools.partial):
INTERNALERROR> TypeError: isinstance() arg 2 must be a type or tuple of types
========================= no tests ran in 0.01 seconds =========================
@JoseKilo thanks for sharing the traceback, now the problem is clear.
Yet another case of users monkeypatching something which is used by pytest's internals and things blowing up horribly... same thing with open and rewrite.py IIRC.
Should we start to always import things using from module import foo instead of import module; module.foo throughout the entire code base?
@nicoddemus i beleive we should make a module that takes references we itnernally use so people can monkeypatch the stdlib any way they want afterwards
@RonnyPfannschmidt I see, but what's the advantage of making a separate module containing all the symbols used instead of importing each symbol directly in their own module? The latter at least linting can catch unused names, using a single module containing only symbols will require us to sprinkle # noqa for all names in that module.
im not asking for a star import, but i#d like to create a location where we can affect the internals in a controlled manner
also all we need is a __all__
i#d like to create a location where we can affect the internals in a controlled manner
You mean we would use something like:
# some module
from _pytest._imports import partial
# _pytest._imports
from functools import partial
?
@nicoddemus i would call the module safeguarded_function and import it named sf
that way we could ensure we can monkeypatch the things we need to
i would call the module safeguarded_function and import it named sf
OK sounds good, this also gives us a place to write a docstring explaining the rationale.
that way we could ensure we can monkeypatch the things we need to
Wait now you lost me, what monkeypatching are you talking about? 馃榿
@nicoddemus well - imagine needing to monkeypatch part of the stdlib for a integration test of pytest -
a module to controll that would be most beneficial and it couldb e integrated into pytester
Oh OK, for integration testing, got it. Thanks!
closing in kind of #3290
Most helpful comment
closing in kind of #3290