Sibling package imports
Seven years after
Since I wrote the answer below, modifying sys.path
is still a quick-and-dirty trick that works well for private scripts, but there has been several improvements
- Installing the package (in a virtualenv or not) will give you what you want, though I would suggest using pip to do it rather than using setuptools directly (and using
setup.cfg
to store the metadata) - Using the
-m
flag and running as a package works too (but will turn out a bit awkward if you want to convert your working directory into an installable package). - For the tests, specifically, pytest is able to find the api package in this situation and takes care of the
sys.path
hacks for you
So it really depends on what you want to do. In your case, though, since it seems that your goal is to make a proper package at some point, installing through pip -e
is probably your best bet, even if it is not perfect yet.
Old answer
As already stated elsewhere, the awful truth is that you have to do ugly hacks to allow imports from siblings modules or parents package from a __main__
module. The issue is detailed in PEP 366. PEP 3122 attempted to handle imports in a more rational way but Guido has rejected it one the account of
The only use case seems to be running scripts that happen
to be living inside a module's directory, which I've always seen as an
antipattern.
(here)
Though, I use this pattern on a regular basis with
# Ugly hack to allow absolute import from the root folder
# whatever its name is. Please forgive the heresy.
if __name__ == "__main__" and __package__ is None:
from sys import path
from os.path import dirname as dir
path.append(dir(path[0]))
__package__ = "examples"
import api
Here path[0]
is your running script's parent folder and dir(path[0])
your top level folder.
I have still not been able to use relative imports with this, though, but it does allow absolute imports from the top level (in your example api
's parent folder).
How to import sibling file within a package?
In ui/utils.py
, use a relative import.
from . import utils.file
NameChanger
itself is likely not in your search path (nor does it need to be). But since NameChanger
is a package, the relative import in a module contained in a subpackage of NameChanger
should work.
I originally suggested
from .utils import file
which would only work if utils
really had file
as a module-level attribute, which is generally not the case for a package.
How to import python modules from sibling directory?
Since there are already many answers on SO for this*, I will focus on question (2). About what is a better code organization:
|- setup.py
|- top_pkg_name
|- __init__.py
|- pkg1
|- __init__.py
|- pkg2
|- __init__.py
The (relative) import is done as follows, from inside module_2
:
from ..pkg1 import module1 as m1
Alternatively, you can use absolute imports, which refer to the top package name:
from top_pkg_name.pkg1 import module1 as m1
In such an organization, when you want to run any module as a script, you have to use the -m
flag:
python -m top_pkg_name.pkg1.module1
For question (3), I'm not sure but it looks like the unittest
module adds the folder to path, allowing the imports to happen directly.
*Refer:
- How do I import a Python script from a sibling directory?
- Python import module from sibling folder
Import Sibling Packages with __init__.py doesn't work
Before the import sentence, add the following code
import sys
sys.path.append("./")
which adds the current path to workspace, then you can import module successfully.
Here's my project screenshot with the same folder structure as yours.
[ EDIT ]
I assumed your cwd(current working directory) is under the root_folder, like mine. then the sys.path.append("./") should work.
Now turn to the root_Project, add the following code in launch.json:
"env": {
"PYTHONPATH": "${workspaceFolder}",
},
"cwd": "${workspaceFolder}"
Python extension will search module under root_project, you can directly import the module:
More detailed information please refer to env in debug and Variables.
How to import a Python module from a sibling folder?
This is happening because A
and B
are independent, unrelated, packages as far as Python is concerned.
Create a __init__.py
in the same directory as Driver.py
and everything should work as expected.
Related Topics
How to Understand Closure in a Lambda
Pip Install' Fails For Every Package ("Could Not Find a Version That Satisfies the Requirement")
Finding and Replacing Elements in a List
How to Overcome "Datetime.Datetime Not Json Serializable"
Why Is "1000000000000000 in Range(1000000000000001)" So Fast in Python 3
Reference Template Variable Within Jinja Expression
Pandas Get Rows Which Are Not in Other Dataframe
How to Get Json to Load into an Ordereddict
How to Update a Plot in Matplotlib
How to Implement an Efficient Infinite Generator of Prime Numbers in Python
How to Open a Chrome Profile Through Python
How to Compare Two Lists in Python and Return Matches
What Is an Alternative to Execfile in Python 3
How to Call a Function from Another .Py File