reframe-hpc / reframe

A powerful Python framework for writing and running portable regression tests and benchmarks for HPC systems.
https://reframe-hpc.readthedocs.org
BSD 3-Clause "New" or "Revised" License
214 stars 102 forks source link

Import error when loading a test with a relative import #3076

Closed vkarak closed 7 months ago

vkarak commented 9 months ago

Here is a simple reproducer:

Directory structure

.
├── mylib
│   ├── mylibtest.py
│   └── util
│       └── __init__.py
└── mytest.py

File contents

import os
import reframe as rfm

if os.getenv('USE_RFM_IMPORT', '0') == '0':
    from .util import MY_VAR
else:
    from reframe.utility import import_from_module
    MY_VAR = import_from_module('.util', 'MY_VAR')

@rfm.simple_test
class my_lib_test(rfm.RegressionTest):
    valid_systems = ['*']
    valid_prog_environs = ['*']
MY_VAR = 1
import reframe as rfm
from mylib.mylibtest import my_lib_test

@rfm.simple_test
class my_test(my_lib_test):
    valid_systems = ['*']
    valid_prog_environs = ['*']

Running and errors

# This works
reframe -c mytest.py -l

# This crashes
reframe -c mylib/mylibtest.py -l
ERROR: run session stopped: import error: attempted relative import with no known parent package
ERROR: Traceback (most recent call last):
  File "/Users/karakasv/local/reframe/reframe/frontend/cli.py", line 1018, in main
    checks_found = loader.load_all(force=True)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/karakasv/local/reframe/reframe/core/logging.py", line 1012, in _fn
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
  File "/Users/karakasv/local/reframe/reframe/frontend/loader.py", line 248, in load_all
    checks += self.load_from_file(d, force)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/karakasv/local/reframe/reframe/frontend/loader.py", line 199, in load_from_file
    util.import_module_from_file(filename, force)
  File "/Users/karakasv/local/reframe/reframe/utility/__init__.py", line 107, in import_module_from_file
    return _do_import_module_from_file(filename, module_name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/karakasv/local/reframe/reframe/utility/__init__.py", line 69, in _do_import_module_from_file
    spec.loader.exec_module(module)
  File "<frozen importlib._bootstrap_external>", line 940, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/Users/karakasv/Repositories/misc/rfm-support/issue-new/mylib/mylibtest.py", line 5, in <module>
    from .util import MY_VAR
ImportError: attempted relative import with no known parent package

Enabling the reframe import mechanism, the situation is inversed:

export USE_RFM_IMPORT=1

# Loading fails with warning
reframe -c mytest.py -l
WARNING: skipping test file '/Users/karakasv/Repositories/misc/rfm-support/issue-new/mytest.py': file not found error: [Errno 2] No such file or directory: '/Users/karakasv/Repositories/misc/rfm-support/issue-new/util.py' (rerun with '-v' for more information)
# This works fine
reframe -c mylib/mylibtest.py -l