Open arnlen opened 11 months ago
$ pytest tests/models/device_test.py
============================================================================================================================= test session starts ==============================================================================================================================
platform darwin -- Python 3.11.5, pytest-7.4.2, pluggy-1.3.0
rootdir: /Users/[...]/my-project
plugins: doubles-1.5.3
collected 1 item
tests/models/device_test.py [100%]
=================================================================================================================================== FAILURES ===================================================================================================================================
_______________________________________________________________________________________________________________ TestDevice.test_when_camera_has_no_ir_projector ________________________________________________________________________________________________________________
func = <instancemethod getIrDrivers at 0x102b0b400>
def getfullargspec(func):
"""Get the names and default values of a callable object's parameters.
A tuple of seven things is returned:
(args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations).
'args' is a list of the parameter names.
'varargs' and 'varkw' are the names of the * and ** parameters or None.
'defaults' is an n-tuple of the default values of the last n parameters.
'kwonlyargs' is a list of keyword-only parameter names.
'kwonlydefaults' is a dictionary mapping names from kwonlyargs to defaults.
'annotations' is a dictionary mapping parameter names to annotations.
Notable differences from inspect.signature():
- the "self" parameter is always reported, even for bound methods
- wrapper chains defined by __wrapped__ *not* unwrapped automatically
"""
try:
# Re: `skip_bound_arg=False`
#
# There is a notable difference in behaviour between getfullargspec
# and Signature: the former always returns 'self' parameter for bound
# methods, whereas the Signature always shows the actual calling
# signature of the passed object.
#
# To simulate this behaviour, we "unbind" bound methods, to trick
# inspect.signature to always return their first parameter ("self",
# usually)
# Re: `follow_wrapper_chains=False`
#
# getfullargspec() historically ignored __wrapped__ attributes,
# so we ensure that remains the case in 3.3+
> sig = _signature_from_callable(func,
follow_wrapper_chains=False,
skip_bound_arg=False,
sigcls=Signature,
eval_str=False)
/usr/local/Cellar/python@3.11/3.11.5/Frameworks/Python.framework/Versions/3.11/lib/python3.11/inspect.py:1369:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/local/Cellar/python@3.11/3.11.5/Frameworks/Python.framework/Versions/3.11/lib/python3.11/inspect.py:2521: in _signature_from_callable
return _signature_from_builtin(sigcls, obj,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = <class 'inspect.Signature'>, func = <instancemethod getIrDrivers at 0x102b0b400>, skip_bound_arg = False
def _signature_from_builtin(cls, func, skip_bound_arg=True):
"""Private helper function to get signature for
builtin callables.
"""
if not _signature_is_builtin(func):
raise TypeError("{!r} is not a Python builtin "
"function".format(func))
s = getattr(func, "__text_signature__", None)
if not s:
> raise ValueError("no signature found for builtin {!r}".format(func))
E ValueError: no signature found for builtin <instancemethod getIrDrivers at 0x102b0b400>
/usr/local/Cellar/python@3.11/3.11.5/Frameworks/Python.framework/Versions/3.11/lib/python3.11/inspect.py:2328: ValueError
The above exception was the direct cause of the following exception:
method = <instancemethod getIrDrivers at 0x102b0b400>, method_name = 'getIrDrivers', args = ['self_or_cls'], kwargs = {}
def _verify_arguments(method, method_name, args, kwargs):
try:
> getcallargs(method, *args, **kwargs)
../../../.venv/lib/python3.11/site-packages/doubles/verification.py:130:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/local/Cellar/python@3.11/3.11.5/Frameworks/Python.framework/Versions/3.11/lib/python3.11/inspect.py:1528: in getcallargs
spec = getfullargspec(func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
func = <instancemethod getIrDrivers at 0x102b0b400>
def getfullargspec(func):
"""Get the names and default values of a callable object's parameters.
A tuple of seven things is returned:
(args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations).
'args' is a list of the parameter names.
'varargs' and 'varkw' are the names of the * and ** parameters or None.
'defaults' is an n-tuple of the default values of the last n parameters.
'kwonlyargs' is a list of keyword-only parameter names.
'kwonlydefaults' is a dictionary mapping names from kwonlyargs to defaults.
'annotations' is a dictionary mapping parameter names to annotations.
Notable differences from inspect.signature():
- the "self" parameter is always reported, even for bound methods
- wrapper chains defined by __wrapped__ *not* unwrapped automatically
"""
try:
# Re: `skip_bound_arg=False`
#
# There is a notable difference in behaviour between getfullargspec
# and Signature: the former always returns 'self' parameter for bound
# methods, whereas the Signature always shows the actual calling
# signature of the passed object.
#
# To simulate this behaviour, we "unbind" bound methods, to trick
# inspect.signature to always return their first parameter ("self",
# usually)
# Re: `follow_wrapper_chains=False`
#
# getfullargspec() historically ignored __wrapped__ attributes,
# so we ensure that remains the case in 3.3+
sig = _signature_from_callable(func,
follow_wrapper_chains=False,
skip_bound_arg=False,
sigcls=Signature,
eval_str=False)
except Exception as ex:
# Most of the times 'signature' will raise ValueError.
# But, it can also raise AttributeError, and, maybe something
# else. So to be fully backwards compatible, we catch all
# possible exceptions here, and reraise a TypeError.
> raise TypeError('unsupported callable') from ex
E TypeError: unsupported callable
/usr/local/Cellar/python@3.11/3.11.5/Frameworks/Python.framework/Versions/3.11/lib/python3.11/inspect.py:1379: TypeError
During handling of the above exception, another exception occurred:
self = <tests.models.device_test.TestDevice object at 0x102a69050>
def test_when_camera_has_no_ir_projector(self):
dai_device = InstanceDouble('depthai.Device')
allow(dai_device).getIrDrivers.and_return([])
> device = Device(dai_device = dai_device, ir_projector_power = 300)
tests/models/device_test.py:12:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
models/device.py:19: in __init__
self.update_ir_projector_power(ir_projector_power)
models/device.py:33: in update_ir_projector_power
if len(self.dai_device.getIrDrivers()) == 0:
../../../.venv/lib/python3.11/site-packages/doubles/proxy_method.py:77: in __call__
expectation.verify_arguments(args, kwargs)
../../../.venv/lib/python3.11/site-packages/doubles/allowance.py:267: in verify_arguments
verify_arguments(self._target, self._method_name, args, kwargs)
../../../.venv/lib/python3.11/site-packages/doubles/verification.py:125: in verify_arguments
_verify_arguments(method, method_name, args, kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
method = <instancemethod getIrDrivers at 0x102b0b400>, method_name = 'getIrDrivers', args = ['self_or_cls'], kwargs = {}
def _verify_arguments(method, method_name, args, kwargs):
try:
getcallargs(method, *args, **kwargs)
except TypeError as e:
if not _is_python_function(method):
> raise VerifyingBuiltinDoubleArgumentError(str(e))
E doubles.exceptions.VerifyingBuiltinDoubleArgumentError: unsupported callable
../../../.venv/lib/python3.11/site-packages/doubles/verification.py:133: VerifyingBuiltinDoubleArgumentError
--------------------------------------------------------------------------------------------------------------------------- Captured stdout teardown ---------------------------------------------------------------------------------------------------------------------------
F
=========================================================================================================================== short test summary info ============================================================================================================================
FAILED tests/models/device_test.py::TestDevice::test_when_camera_has_no_ir_projector - doubles.exceptions.VerifyingBuiltinDoubleArgumentError: unsupported callable
You want to use the context manager within the test.
If you do:
` import depthai as dai
from models.device import Device
from doubles import InstanceDouble, allow, no_builtin_verification
import functools
class TestDevice:
def test_when_camera_has_no_ir_projector(self):
with no_builtin_verification():
allow(functools).reduce
dai_device = InstanceDouble('depthai.Device')
allow(dai_device).getIrDrivers.and_return([])
device = Device(dai_device, 300)
assert device.dai_device == dai_device`
It should work as you're expecting it too.
Context
Every time I try to mock a function from an external library (depthai in my case), I got the following error:
What I tried
In the FAQ, I read this section which explains how to bypass the inspection functionality, by using
with no_builtin_verification()
.This is what I tried, by it doesn't fix the issue.
My code
Setup
Any idea? I'm even sure if I'm using the
with no_builtin_verification()
properly.' 🤔