0

I am trying to better understand importing modules. I read about how to do this from here https://stackoverflow.com/a/14132912/14179793 and I can get it to work using solution 1. There is an additional variable that I need to figure out though.

This is a dummy project I am testing with:

.
├── a_package
│   ├── __init__.py
│   └── lib_a.py
├── b_package
│   ├── __init__.py
│   └── test_script.py
├── main.py
└── src
    └── src_lib
        └── src_lib.py

With this setup I can do:

python -m b_package.test_script
this is lib a function
This is src_lib_function.

test_script.py:

from a_package.lib_a import lib_a_function
from src.src_lib.src_lib import src_lib_function

if __name__ == '__main__':
    lib_a_function()
    src_lib_function()
    pass

The goal is to make b_package/test_script.py executable without using python test_script ie ./test_script

However, adding the shebang at the top #!/usr/bin/env python causes an import error:

$ ./b_package/test_script.py 
Traceback (most recent call last):
  File "./b_package/test_script.py", line 2, in <module>
    from a_package.lib_a import lib_a_function
ModuleNotFoundError: No module named 'a_package'

I assume it is because python is not loading it as a module based off the above mentioned question but I am not sure how to resolve this.

3
  • 1
    A quick and dirty way to make it work is to add the root path of your tree to "sys.path" in your "test_script.py" before the import happens that causes the error. Commented Dec 16, 2021 at 23:38
  • 1
    Do you mind using setuptools for that? If so, I could describe that in answer. Commented Dec 16, 2021 at 23:44
  • @kosciej16 I do not mind. I will say that this is a simplified example for a file structure I am having to work with. In b_package there are actually a large number of scripts that should be callable. Commented Dec 17, 2021 at 14:51

1 Answer 1

2

I ended up using setuptools as suggested by kosciej16 to achieve the desired results.

New project structure:

.
├── a_package
│   ├── __init__.py
│   └── lib_a.py
├── b_package
│   ├── __init__.py
│   └── test_script.py
├── main.py
├── pyproject.toml
├── setup.cfg
└── src
    ├── __init__.py
    └── src_lib
        ├── __init__.py
        └── src_lib.py

setup.cfg:

[metadata]
name = cli_test
version = 0.0.1

[options]
packages = find:

[options.entry_points]
console_scripts =
    test_script = b_package.test_script:main

This allows the user to clone the repo and run pip install . from the top level then they can execute the script by just typing test_script

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.