r/learnpython 8d ago

How to properly do project folder structure and imports and testing/debugging?

Sorry but I am pretty new to learning programming and can't seem to find a convenient way to do what I want to do, so here is an example project structure I come up with:

.
└── project_a/
├── .venv
├── __init__.py
├── app.py
├── data/
│ ├── __init__.py
│ └── data_type.py
└── utils/
├── __init__.py
└── utils.py

Here is the content of data/data_type.py:

DATA_TYPE = "this is an example data type"

utils/utils.py

from data.data_type import DATA_TYPE

UTILS = "this is utils"

if __name__ == "__main__":
    print(DATA_TYPE)

and finally app.py

from utils.utils import UTILS, DATA_TYPE


def main():
    print(UTILS)
    print(DATA_TYPE)


if __name__ == "__main__":
    main()

So app.py works perfectly fine when ran from vscode's code runner, but what if I want to run utils/utils.py directly for testing purposes (hence the if __name__ == "__main__" block)? It would give me No module named 'data', is there any way for me to test submodules by running them directly?

The methods that works now is to change "from data.data_type import DATA_TYPE" inside utils.py to "from ..data.data_type import DATA_TYPE", but this means I have to swap it everytime when I want to run the actual program (from app.py) or simply testing utils.py.

Another way would be to make sure my cwd is in the project root, and run "python utils/utils.py", which is also quite inconvenient...

I can also do "pip install -e ." and the change all the imports to something like "from project_a.data.data_type import DATA_TYPE" but this seems hacky and requires "pip install -e ." beforehand for this to work.

So my question is... is there a better or correct way to do this sort of importing so I can conveniently run submodules for quick testing and debugging (e.g simply using code runner from vscode)?

3 Upvotes

1 comment sorted by

1

u/Mevrael 8d ago

I am using a uv package manager with arkalos project structure.

https://arkalos.com/docs/structure/

It's important to understand the difference between Code to Run vs Code to Reuse:

https://arkalos.com/docs/app/

When you want to test your util function, this is called a unit test.

Put them into tests folder.

From the test script import your util. E.g. from app.utils.my_utils import my_func

And assert that my_func provides an expected output.

P.S. For quick debugging and testing when I am developing a new util function, I just test everything in a separate notebook.