pythonimportpython-importpython-importlib

Import a script from a parent's subdir, with a filename and dirname starting with digits


I know the usual Python import system, packages, __init__.py, the __import__ function (see In python, how to import filename starts with a number), etc. I know the classic How do I import other Python files? answers.

Disclaimer: I know the following is not a common file-structure, but sometimes you have to quickly deal with legacy code, without refactoring it.

|
|- 1 UTILS
|     |-  123myscript.py
|- 2 TESTS
|     |-  test.py

When running test.py, how can I import 123myscript.py, without mangling with the sys.path.append?

Is it possible with importlib? I haven't been able to do it with:

importlib.import_module("../1 UTILS/123myscript.py", package=None)

Solution

  • A pragmatic answer is given in the related question to which Andrio Skur's comment provides a link. Indeed it uses importlib.

    Adapted to your case, this could look as follows. Here, I assume

    Then, a successful import of 123myscript.py in test.py would be, for example:

    # Contents of `2 TESTS/test.py`
    import importlib.util
    from pathlib import Path
    
    location = Path(__file__).parents[1] / "1 UTILS" / "123myscript.py"
    
    spec = importlib.util.spec_from_file_location(location.stem, location)
    # ^ Instead of `location.stem` (thus "123myscript"), you can use an arbitrary name
    myscript = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(myscript)
    assert myscript.do_something() == 42
    

    Note that I don't know whether there are any dependencies in 123myscript.py, which might make the setup more complicated.