where first democord is my working directory and the lower ( 2nd ) is the package itself.
Inside my democord/__main__.py :
from .app import App
from .appinfo import AppInfo
class System: ...
And I’m running it as : python democord
This throws an ImportError: attempted relative import with no known parent package. Though I could do from app import App, the app.py also contains some more relative imports. Moreover initially, the package would just be imported and won’t be ran as python democord as well ( just doing this to test something out ).
This can be resolved as well when modifying my app.py :
# democord/app.py
if __name__ == "app":
from appinfo import AppInfo
else:
from .appinfo import AppInfo
though it’s quite " unideal " for me.
So, any idea how I can import from the files without modifying the app.py ( or any other ) file’s imports from relative to absolute ?
I think you just need to use python -m democord. I thought it was due to not being installed but that doesn’t even matter. Python just needs to know that it’s trying to run the package (and it needs to be findable on sys.path).
Looking at the details for the command line, I guess another option is just to remove the relative imports entirely–when running with python democord the local directory will be added to the path, so from app import App should work correctly.
But personally, I would go for a solution that works when the app is installed as a package, so that it is portable. That means using python -m democord and relative imports.
I believe that with the project structure you presented, you should always use python -m democord. I do not know if absolute or relative imports make a difference in this case, I would not think about it if I were you and would always use python -m democord because as far as I know it should always work and it is the correct way.
Of course for intellectual curiosity, you can investigate if absolute vs. relative imports play a role. And of course there is a concrete explanation for the various techniques and behaviors that you can look up if you want to.
My rule of thumb for choosing when to use python -m some_package.some_module or python -m some_directory/some_script.py is whether or not the thing I want to run is also importable or not. In other words: is it part of an importable package or not?
As far as I understood, if I run python some_directory/some_script.py and some_directory/some_script.py imports from something in some_directory (absolute or relative, I do not know nor care) then things are very likely to start breaking.
Note that in this case, Python prepends some_directory to sys.path which is making the assumption that some_directory is not a package. That means that some_directory is not expected to contain an __init__.py and to import some neighbouring module it’d use import neighbour rather than from some_directory import neighbour.
That said, if you do install the package (or just add some_directory’s parent to PYTHONPATH) then you’ll get away with treating some_directory as a package anyway.