Skip to main content

Hatch build hook plugin that writes the project name to a file

Project description

hatch-project-name

CI/CD CI - Test CD - Build
Package PyPI - Version PyPI - Python Version
Meta Hatch project uv Ruff types - Mypy License - MIT

This provides a build hook plugin for Hatch that writes the project name defined in pyproject.toml to a file.

Table of Contents

Configuration

The build hook plugin name is project-name.

  • pyproject.toml

    [project]
    name = "my-project"
    
    [tool.hatch.build.hooks.project-name]
    dependencies = ["hatch-project-name"]
    name-file = "src/my_project/_name.py"
    
  • hatch.toml

    [project]
    name = "my-project"
    
    [build.hooks.project-name]
    dependencies = ["hatch-project-name"]
    name-file = "src/my_project/_name.py"
    

Building the project will generate the file

  • _name.py

    project_name = __project_name__ = distribution_name = __distribution_name__ = "my-project"
    

[!NOTE] This file is generated and should not be committed to version control. Remember to add it to your .gitignore. The plugin will automatically include it in your project’s built sdists and wheels.

Build hook options

Option Type Default Description
name-file str REQUIRED The relative path to the Python file that gets updated with the project name.

Editable installs

The name file is only updated upon install or build. Thus the name in an editable install (Hatch's dev mode) will be incorrect if the name is changed in pyproject.toml and the project is not rebuilt.

Rationale

The Hatch project name is a required field defined in the [project] table in pyproject.toml:

[project]
name = "my-project"

The [project] table specifies the project’s core metadata. The name project metadata field corresponds to the distribution package Name.

A distribution package is a piece of software that you can install. Most of the time, this is synonymous with “project”. When you type pip install pkg, or when you write dependencies = ["pkg"] in your pyproject.toml, pkg is the name of a distribution package. [...]

Most of the time, a distribution package provides one single import package (or non-package module), with a matching name. For example, pip install numpy lets you import numpy.

However, this is only a convention. PyPI and other package indices do not enforce any relationship between the name of a distribution package and the import packages it provides. [...]

Source: Distribution package vs. import package

The project/distribution name might be needed in code for various reasons. One might be that you are using the importlib.metadata standard library module to access project metadata. For instance:

from importlib import metadata

distribution_name = "my-project"
version = metadata.version(distribution_name)

Or you might simply want to log the name.

import logging

logger = logging.getLogger()

project_name = "my-project"
logger.info(f"Project name: {project_name}")

The Python standard library does not provide a standardized function to programmatically access the current project/distribution name that works without limitations. This is because, as quoted above, no relationship is enforced between the name of a distribution package and the importable import packages it provides. You can of course just hardcode the project/distribution name as in the examples above, but this is not ideal since it is preferable to maintain pyproject.toml as the single source of truth for your project metadata.

The following method (originally posted here) is the best you can achieve with the standard library importlib.metadata module, but it has important limitations.

Say one top-level module or import package name in your project is my_tool. Then you can do:

from importlib import metadata

def get_project_name() -> str:
    pkg_name = "my_tool"
    pkg_to_dists = metadata.packages_distributions()
    return pkg_to_dists[pkg_name][0]

This uses importlib.metadata.packages_distributions() to map one of the top-level names to the project/distribution name.

This method has the following limitations:

  1. It does not work for namespace packages as the top-level namespace will map to potentially multiple distributions.
  2. It does not work with an editable install (unless you are using setuptools, see more details here and here). The main reason is that importlib.metadata "operates on third-party distribution packages installed into Python’s site-packages directory".

Alternatively, Hatch provides a CLI command hatch project metadata name that outputs the project name. However, this is cumbersome to use in Python code as you need to use something like subprocess.run to invoke the command in a working directory that contains the project source code. It additonally requires that Hatch is installed.

An even better alternative then is to generate a file containing the project name on-the-fly and include it in the distribution—and this is exactly what the hatch-project-name build hook does! Since the file is generated, you should exclude it from version control. This maintains pyproject.toml as the source of truth for the project name. Furthermore, Python project templates built with tools like cookiecutter and Copier will not need to parameterize the project name in Python source files.

License

hatch-project-name is distributed under the terms of the MIT license.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hatch_project_name-1.0.0a7.tar.gz (5.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hatch_project_name-1.0.0a7-py3-none-any.whl (6.7 kB view details)

Uploaded Python 3

File details

Details for the file hatch_project_name-1.0.0a7.tar.gz.

File metadata

  • Download URL: hatch_project_name-1.0.0a7.tar.gz
  • Upload date:
  • Size: 5.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.28.1

File hashes

Hashes for hatch_project_name-1.0.0a7.tar.gz
Algorithm Hash digest
SHA256 39562ea0151f47ba4f77a35d35127867373b11ddbb4d29b187c29df0738db0e2
MD5 7ff4d0f1fc271ca2d20c6c93c31ceb2f
BLAKE2b-256 b7c36139072ad528a36ddd02f35e2c09a98e5ae9453ac0933ca3c369cba3406b

See more details on using hashes here.

File details

Details for the file hatch_project_name-1.0.0a7-py3-none-any.whl.

File metadata

File hashes

Hashes for hatch_project_name-1.0.0a7-py3-none-any.whl
Algorithm Hash digest
SHA256 81e088e36d157faf502a83a593eec341226ea9e7553e6dba587a86c593db58d6
MD5 73821b78283ebd0e9210bc75d91455d6
BLAKE2b-256 19e9b5f2e901402e53fed577ef9dd1396a6ff609db8f422606e15844cc48d7bb

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page