I would like help regarding setuptools
and import
s. I have been unable to run pip install .
and have package
importable by any arbitrary python script like this
import package
Here is an example file structure I have tried to play with
.
├── setup.py
└── src
└── package
├── __init__.py
├── __main__.py
├── package1
│ ├── __init__.py
│ └── module1.py
└── package2
├── __init__.py
└── module2.py
Content of setup.py
import setuptools
setuptools.setup(name="package",
version="1.0.0",
python_requires='>=3.8',
package_dir={"package": "src"},
packages=['package'])
Content of src/package/__init__.py
from . import package1
from . import package2
Content of src/package/__main__.py
import package2
from package2.module2 import function2
if __name__ == '__main__':
function2()
print("Hello from main")
Content of src/package/package1/__init__.py
from . import module1
Content of src/package/package1/module1.py
def function1():
print("Hello from function1")
Content of src/package/package2/__init__.py
from . import module2
Content of src/package/package2/module2.py
import package1
from package1.module1 import function1
def function2():
function1()
print("Hello from function2")
If I run __main__.py
with python3 src/package
the output is
Hello from function1
Hello from function2
Hello from main
It works as I want it from __main__
. Now, I want to install package
so I can import with a simple import package
.
I do this with pip install .
I then create a script in an arbitrary folder with this content
import package
However, I get the error
/bin/python3.10 /home/ubuntu/tmp/test.py Traceback (most recent call last): File "/home/ubuntu/tmp/test.py", line 1, in <module> import package ModuleNotFoundError: No module named 'package'
My goal is to be able to run a script like this from anywhere and not have it error.
import package
function2()
Output would be
Hello from function1
Hello from function2
What lines of code must change for package
to be importable from any script, and why did it not work with the code and filestructure provided above?
CodePudding user response:
Writing {"package": "src"}
means "the src directory is the package", it would work if you had:
└── src
├── __init__.py
├── __main__.py
├── package1
│ ├── __init__.py
│ ├── module1.py
├── package2
│ ├── __init__.py
│ ├── module2.py
But you have package
inside src
so you need to indicate the root folder
for your packages with is the empty string of package_dir
, like:
package_dir={"": "src"}
Then it starts to work:
$ python setup.py bdist_wheel && unzip -l dist/package-1.0.0-py3-none-any.whl
Length Date Time Name
--------- ---------- ----- ----
46 2022-06-14 09:11 package/__init__.py
127 2022-06-14 09:12 package/__main__.py
But you're missing the other package, so you either need to list them all:
packages=["package", "package.package1", "package.package2"]
Or make setuptools
work for you:
packages=setuptools.find_packages(where="src")
In both cases your 3 packages are installed:
Length Date Time Name
--------- ---------- ----- ----
46 2022-06-14 09:11 package/__init__.py
127 2022-06-14 09:12 package/__main__.py
22 2022-06-14 09:12 package/package1/__init__.py
51 2022-06-14 09:12 package/package1/module1.py
22 2022-06-14 09:12 package/package2/__init__.py
122 2022-06-14 09:12 package/package2/module2.py