This is my project structure
pkg_root
└───venv
└───requirements.txt
└───pyproject.toml
├───src
│ ├───pkg
│ │ ├───__init__.py
│ │ ├───test_main.py
│ │ ├───config
│ │ │ ├───json
│ │ ├───data
│ │ │ ├───input
│ │ │ │ └───data_file
│ │ │ └───output
│ │ │ ├───data_file
│ │ ├───sub_pkg_1
│ │ │ ├───__init__.py
│ │ │ ├───sub_pkg_1_1
│ │ │ │ ├───__init__.py
│ │ │ │ ├───sub_pkg_1_1_a
│ │ │ │ │ └─── __init__.py
│ │ │ │ │ └─── file.py
│ │ │ ├───sub_pkg_1_2
│ │ │ │ └─── __init__.py
│ │ │ │ └─── file.py
│ │ │ ├───sub_pkg_1_3
│ │ │ │ ├───__init__.py
│ │ │ │ ├───sub_pkg_1_3_a
│ │ │ │ │ ├───__init__.py
│ │ │ │ │ ├───file.py
And this is my pyproject.toml
[build-system]
requires = ["setuptools>=67.0.0", "wheel"]
build-backend = "setuptools.build_meta"
[tool.setuptools]
package-dir = {"" = "src"}
[tool.setuptools.packages.find]
where = ["src"]
[project]
name = "pkg"
version = "1.0.0"
dynamic = ["dependencies"]
[tool.setuptools.dynamic]
dependencies = {file = ["requirements.txt"]}
Running pip install .
installs the package in my global Python interpreter in spite of being inside a virtual environment.
I opened an idle
shell and imported my package and wrote the following code and running it gave me an attribute error.
>> import pkg
>> pkg.test_main.generate_data()
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
pkg.test_main.generate_data()
AttributeError: module 'pkg' has no attribute 'test_main'
Running the command print(pkg)
gives the following message
<module 'pkg' from 'path:\\to\\site-packages\\pkg\\__init__.py'>
The desired behaviour is to import subpackages/modules from pkg
, but from what I can understand, pkg
is being treated as an object. Where am I going wrong?
The namespace for the pkg
module only holds what is in the __init__.py
file. I.e. if you add a variable or import a module in __init__.py
it will be added to the pkg
namespace and be available using the dot notation: pkg.<something>
.
In this case, you can either import test_main
in your __init__.py
file:
# __init__.py
from . import test_main
Which now adds test_main
to the pkg
namespace so you can do:
>> import pkg
>> pkg.test_main.generate_data()
Or you can import test_main
directly in your code:
>> import pkg.test_main
>> pkg.test_main.generate_data()