Thanks for the hint.
Can I still leave the @jit decorator in the code using the importlib.util.find_spec?
My topic is how to leave the numba code unchanged (even the decorators) with minimum effort.
In most cases I prefer not to import extra libraries if possible.
I tried to cover 4 different decorators:
@jit with no arguments
@jit(*args) with arbitrary positional arguments
@jit(**kwargs) with arbitrary keyword arguments
@jit(*args, **kwargs) with arbitrary mixture of positional and keyword arguments
I guess it depends, to an extent, on your use-case(s).
One option is to tuck the find_spec into the decorator itself:
def try_njit(*args, **kwargs):
if find_spec("numba") is not None:
from numba import njit
if args and callable(args[0]):
return njit(args[0])
return njit(*args, **kwargs)
if args and callable(args[0]):
return args[0]
return lambda _: _
Another is something like this:
import importlib
from importlib.util import find_spec
def _void_njit(*args, **kws):
if args and callable(args[0]):
return args[0]
return lambda _: _
try_njit = find_spec("numba") and importlib.import_module("numba").njit or _void_njit
or along the lines thereof.
Nothing wrong per se with your try / except approach, but I’d probably catch ModuleNotFoundError rather than the generic Exception.