python-pytest-cases icon indicating copy to clipboard operation
python-pytest-cases copied to clipboard

AUTO cases: TypeError due to relative import

Open michele-riva opened this issue 2 years ago • 0 comments
trafficstars

Sorry for the spamming. Here another funny situation. Notice that file names are important.

cases.py

def case():
    return 1

test_something.py

from pytest_cases import fixture, parametrize_with_cases

@fixture
@parametrize_with_cases('arg')
def parametrized(arg):
    return arg

def test(parametrized):
    assert parametrized == 1

Raises a TypeError at collection stage:

_______________________________________ ERROR collecting test_something.py ______________________________________________________
pytest_cases\case_parametrizer_new.py:666: in import_default_cases_module
    cases_module = import_module(cases_module_name1)
Python\Python38\lib\importlib\__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1014: in _gcd_import
    ???
<frozen importlib._bootstrap>:991: in _find_and_load
    ???
<frozen importlib._bootstrap>:973: in _find_and_load_unlocked
    ???
E   ModuleNotFoundError: No module named 'test_something_cases'

During handling of the above exception, another exception occurred:
Python\Python38\lib\site-packages\_pytest\runner.py:341: in from_call
    result: Optional[TResult] = func()
Python\Python38\lib\site-packages\_pytest\runner.py:372: in <lambda>
    call = CallInfo.from_call(lambda: list(collector.collect()), "collect")
Python\Python38\lib\site-packages\_pytest\python.py:531: in collect
    self._inject_setup_module_fixture()
Python\Python38\lib\site-packages\_pytest\python.py:545: in _inject_setup_module_fixture
    self.obj, ("setUpModule", "setup_module")
Python\Python38\lib\site-packages\_pytest\python.py:310: in obj
    self._obj = obj = self._getobj()
Python\Python38\lib\site-packages\_pytest\python.py:528: in _getobj
    return self._importtestmodule()
Python\Python38\lib\site-packages\_pytest\python.py:617: in _importtestmodule
    mod = import_path(self.path, mode=importmode, root=self.config.rootpath)
Python\Python38\lib\site-packages\_pytest\pathlib.py:567: in import_path
    importlib.import_module(module_name)
Python\Python38\lib\importlib\__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1014: in _gcd_import
    ???
<frozen importlib._bootstrap>:991: in _find_and_load
    ???
<frozen importlib._bootstrap>:975: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:671: in _load_unlocked
    ???
Python\Python38\lib\site-packages\_pytest\assertion\rewrite.py:178: in exec_module
    exec(co, module.__dict__)
test_something.py:9: in <module>
    def parametrized(arg):
pytest_cases\common_pytest.py:925: in apply
    return apply_decorator(test_or_fixture_func, container)
pytest_cases\case_parametrizer_new.py:143: in _apply_parametrization
    cases_funs = get_all_cases(f, cases=cases, prefix=prefix, glob=glob, has_tag=has_tag, filter=filter)
pytest_cases\case_parametrizer_new.py:303: in get_all_cases
    c = import_default_cases_module(caller_module_name)
pytest_cases\case_parametrizer_new.py:673: in import_default_cases_module
    cases_module = import_module(cases_module_name2)
Python\Python38\lib\importlib\__init__.py:122: in import_module
    raise TypeError(msg.format(name))
E   TypeError: the 'package' argument is required to perform a relative import for '.cases_something'

This is because the test directory has no __init__.py.

Perhaps stripping off the first '.' here? https://github.com/smarie/python-pytest-cases/blob/ab3b7190d728b18512141b9f5f3a1c3dfc7cedf2/src/pytest_cases/case_parametrizer_new.py#L668-L671

E.g.,

if cases_module_name2.startswith('.'):
    cases_module_name2 = cases_module_name2[1:]

The exception raised points then to the solution.

michele-riva avatar Sep 12 '23 14:09 michele-riva