Describe the bug
I am using the numba.njit
decorator to decorate a function. When I execute pytest
with the typeguard extension, I get an error when this decorated function is called: AttributeError: 'CPUDispatcher' object has no attribute '__globals__'
. Without the typeguard extension my tests work fine. When trying to narrow down the error and trying to reproduce with a minimal working example, I found out that the error only occurs when the decorated function is imported absolutely from a module. When the same function is imported with a relative import there is no error.
To Reproduce
I have three different files: two source files (one for absolute and one for relative import) and one pytest file:
src/my_module/numba_typeguard.py (absolute import)
from typing import TypeVar
import numpy as np
import numpy.typing as npt
from numba import njit
T = TypeVar("T", bound=np.generic)
@njit
def numba_sum(
array: npt.NDArray[T],
) -> T:
return np.sum(array)
tests/numba_typeguard.py (relative import) same function as above but in tests
directory.
from typing import TypeVar
import numpy as np
import numpy.typing as npt
from numba import njit
T = TypeVar("T", bound=np.generic)
@njit
def numba_sum_local(
array: npt.NDArray[T],
) -> T:
return np.sum(array)
tests/test_numba_typeguard.py
import numpy as np
from my_module.numba_typeguard import numba_sum
from .numba_typeguard import numba_sum_local
def test_numba_sum_njit() -> None:
x = np.arange(4)
s = numba_sum(x)
assert s == np.sum(x)
def test_numba_sum() -> None:
x = np.arange(4)
s = numba_sum.py_func(x)
assert s == np.sum(x)
def test_numba_sum_local_njit() -> None:
x = np.arange(4)
s = numba_sum_local(x)
assert s == np.sum(x)
def test_numba_sum_local() -> None:
x = np.arange(4)
s = numba_sum_local.py_func(x)
assert s == np.sum(x)
The following is the error I get:
======================================================================================================================================= FAILURES =======================================================================================================================================
_________________________________________________________________________________________________________________________________ test_numba_sum_njit __________________________________________________________________________________________________________________________________
def test_numba_sum_njit() -> None:
x = np.arange(4)
> s = numba_sum(x)
tests/test_numba_typeguard.py:8:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.nox/typeguard-3-9/lib/python3.9/site-packages/typeguard/__init__.py:1031: in wrapper
memo = _CallMemo(python_func, _localns, args=args, kwargs=kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <typeguard._CallMemo object at 0x7f9db523c880>, func = CPUDispatcher(<function numba_sum at 0x7f9db52fa5e0>)
frame_locals = {'T': ~T, 'TypeVar': <class 'typing.TypeVar'>, '__builtins__': {'ArithmeticError': <class 'ArithmeticError'>, 'Asserti...s/.nox/typeguard-3-9/lib/python3.9/site-packages/my_module/__pycache__/numba_typeguard.cpython-39.pyc', ...}
args = (array([0, 1, 2, 3]),), kwargs = {}, forward_refs_policy = <ForwardRefPolicy.ERROR: 1>
def __init__(self, func: Callable, frame_locals: Optional[Dict[str, Any]] = None,
args: tuple = None, kwargs: Dict[str, Any] = None,
forward_refs_policy=ForwardRefPolicy.ERROR):
> super().__init__(func.__globals__, frame_locals)
E AttributeError: 'CPUDispatcher' object has no attribute '__globals__'
.nox/typeguard-3-9/lib/python3.9/site-packages/typeguard/__init__.py:191: AttributeError
Expected behavior
I expect the error not to depend on relative vs absolute import.
Additional context
As I do not know if this is related to typeguard alone or numba and as I am using the hypermodern python template, I raised also an issue here: 'CPUDispatcher' object has no attribute '__globals__' for numba.njitted function and typeguard test · Issue #1271 · cjolowicz/cookiecutter-hypermodern-python · GitHub and here: AttributeError: 'CPUDispatcher' object has no attribute '__globals__' with numba.njit decorated function · Issue #277 · agronholm/typeguard · GitHub
I tried to remove the py.typed
file in the src/my_module directory, but this did not resolve the error.
I would also be happy, if someone could tell me how to disable typeguard for specific lines of code, similar to the noqa
comment for flake or to put something into a with statement so that typeguard ignores stuff within that with
statement. But for now, I couldn’t find any solution.