ModuleNotFoundError when installing a package with entry points using pipx

228 Views Asked by At

I'm writing a python package that I would like to distribute as a standalone terminal app. The structure of the project folder is the following:

energy-monitor/
  config/
  doc/
  tests/
  energymonitor/
    __init__.py -> (empty)
    main.py -> def main()
    data/
    ..other packages..
  project.toml

I'm using setuptools to generate a .tar.gz archive, some relevant parts of the project.toml file are:

[build-system]
requires = ["setuptools>=68.0"]
build-backend = "setuptools.build_meta"

[project]
name = "energy-monitor"
version = "0.0.1"

...

[tool.setuptools.packages.find]
where = ["energymonitor"]

[tool.setuptools.package-data]
data = ["data/*"]

[project.scripts]
energy-monitor = "energymonitor.main:main"

I generate the .tar.gz and the .whl files with the command python -m build, then I run pipx install path/to/energy-monitor.tar.gz. The installation is succesful, but when calling energy-monitor from the command line I get:

Traceback (most recent call last):
  File "/home/mattia/.local/bin/energy-monitor", line 5, in <module>
    from energymonitor.main import main
ModuleNotFoundError: No module named 'energymonitor'

Why is this happening? I was not able to find any helpful solution online. It's the first that I build a python package so sorry if the issue is trivial.

  • python version: 3.11.3
2

There are 2 best solutions below

0
On BEST ANSWER

From setuptools' docs, I'd take it that the where value in [tool.setuptools.packages.find] is the search path your packages should be found inside. You gave it the package folder directly, which should probably be done like this:

[tool.setuptools]
packages = ["energymonitor"]

As a result, the energymonitor package never actually ended up in your build, which you can easily verify by unpacking it.

2
On

The package name is "energy-monitor", but the module name is "energymonitor". This causes the "ModuleNotFoundError" when you try to run the installed package.

[tool.setuptools.packages.find] where = ["energy_monitor"] << Package Name

from energy_monitor.main import main << How it should look like