How to distribute a Python package where import name is different than project name using Hatch?

401 Views Asked by At

I am trying to package my project in order to upload it in PyPI. I have the following directory structure:

.
├── docs
├── LICENSE
├── pyproject.toml
├── README.md
├── src
│   ├── package_name
│   │   ├── __init__.py
│   │   ├── data.json
│   │   ├── __main__.py
│   │   ├── utils.py
└── tests

My package is in under src named src/package_name.

The pyproject.toml has the following lines:

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "project_name"
version = "0.0.1"
authors = [{name = "Foo Bar"}]
license = {text = "GPL-3.0-only"}
description = "A small example package"
readme = "README.md"
requires-python = ">=3.10"
classifiers = [
    "Programming Language :: Python :: 3",
    "License :: OSI Approved :: MIT License",
    "Operating System :: POSIX :: Linux",
]

[project.urls]
Homepage = "https://example.com"

I want a user to be able to perform the installation as:

pip install project_name

but use the code as:

>>> from package_name import x

Is there any way to achieve this with Hatch? I have read the Build-instructions but can't find how.

Note

I have tried the following:

python3 -m build
python3 -m twine upload --repository testpypi dist/*
pip install --upgrade -i https://test.pypi.org/simple/ project_name

The problem is when I type:

>>> import package_name
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'package_name'

I searched into path/to/site-packages but only path/to/site-packages/project_name-0.0.1.dist-info is there. Any ideas?

Tried to solve my problem based on this Tutorial.

The reason I used Hatch is because it was presented in the tutorial. Αn alternative solution (using also pyproject.toml with different backend) is also appreciated.

Edit

I have updated the directory structure as proposed in the comments.

1

There are 1 best solutions below

0
ado sar On BEST ANSWER

I found the solution to my problem by simply switching to setuptools as backend and modifying the pyproject.toml as following:

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

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

[tool.setuptools.dynamic]
version = {attr = "package_name.__version__"}

[project]
name = "package_name"
dynamic = ["version"]

authors = [{name = "Foo Bar"}]
license = {text = "GPL-3.0-only"}
description = "A small example package"
readme = "README.md"
requires-python = ">=3.10"

classifiers = [
    "Programming Language :: Python :: 3",
    "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
    "Operating System :: POSIX :: Linux",
]

[project.urls]
Homepage = "https://example.com""

My solution is based on the setuptools Documentation.