Getting Started with Hatch for Python Projects
Introduction
Beyond the code itself, straightforward tooling is one of the most important elements of the software development lifecycle. Dynamically typed languages such as Python make it easy to write code first and ask structural questions later, but when building for sustainability or designing for distribution, project management capabilities are essential. The Python ecosystem includes numerous options for linting, testing, and packaging, which can be combined using various strategies. Hatch is a relatively recent addition to the landscape of Python project tooling, but it combines an intuitive command-line interface with standardized declarative configuration, providing a solid framework for building libraries and applications.
Getting Started
The Hatch installation instructions outline the steps required to get started on popular operating systems.
In addition to platform-specific packages, pipx supports installing Hatch regardless of operating system.
pipx install hatch
Installing with pipx makes the hatch
command available for project creation and subsequent lifecycle operations.
Project Management with Hatch
Hatch provides a common set of commands for creating, building, testing, and publishing Python projects. Each command has a distinct set of options that apply to the invoked operation.
New Project Creation
With sensible defaults and configurable templates, Hatch can create a new project with a single command.
hatch new hello-world
The hatch new
command creates a directory corresponding to the project name specified, and prints the structure of the
new project.
hello-world
├── src
│ └── hello_world
│ ├── __about__.py
│ └── __init__.py
├── tests
│ └── __init__.py
├── LICENSE.txt
├── README.md
└── pyproject.toml
The default configuration creates the project using the
src layout strategy, which places the
project package name under the base src
directory.
Hatch project templates create a package directory based on the project name, including __about__.py
containing the
project version and __init__.py
as the project module initializer.
The tests
directory contains a module initializer, but no additional files.
The project license defaults to MIT, following the license of Hatch itself.
Project Configuration
The generated pyproject.toml contains important default settings for project lifecycle operations. The TOML structure of the project configuration enables both readability and programmatic parsing using an intuitive structure consisting of hierarchical sections with specific properties.
The default configuration includes several properties that should be changed to reflect correct ownership and reference
information. The [project]
section includes an authors
property that should be adjusted to indicate the name and
email address of one or more developers.
[project]
authors = [
{ name = "U.N. Owen", email = "void@some.where" }
]
Setting a value for the description
property under the [project]
section provides a helpful summary beyond the
project name itself.
The [project.urls]
section includes several links that default to GitHub, which should be changed or removed based on
the actual location of the project repository.
Additional settings provide reasonable defaults, but should be evaluated and adjusted depending on Python version requirements.
Building
Building project artifacts is a core capability. The default build command creates both a source distribution and a packaged binary distribution, according to the Python wheel format.
hatch build
The build command generates distribution archives in the dist
directory for subsequent review or publishing.
The --target
option supports selective building of one or more formats, including sdist
and wheel
as well as
other formats provided through a Hatch plugin. The default Hatch build command is equivalent to running with the
following targets:
hatch build -t sdist -t wheel
Testing
Automated testing is essential to building maintainable software. Hatch supports
testing using the test
command.
hatch test
The standard Hatch configuration includes pytest for assertions and test invocation. Test files
should be created in the tests
directory.
The Coverage.py project provides code coverage measurement, which Hatch also
includes in the default configuration. Running the test
command with --cover
enables coverage reporting as part of
the testing process.
hatch test --cover
Linting
Static analysis, also known as linting, is a first-class feature of Hatch using the fmt
command. The default behavior
includes both error checking and reformatting.
hatch fmt
Adding the --check
option runs error checking without automated fixes. Running the format command with checking
enabled supports configuration with continuous integration workflows that enforce standard coding conventions.
hatch fmt --check
Hatch uses Ruff for linting with reasonable default settings, providing high performance support for hundreds of configurable rules.
Hinting
Although Python is a dynamically typed language at the core, it also supports optional static typing using hinting as described in PEP 484.
The mypy project is a common implementation of Python type hinting, which Hatch supports
in the default configuration. The Hatch run
command supports invoking tools defined in the project configuration, such
as checking for correct type hinting.
hatch run types:check
The run
command takes an environment and argument, corresponding to a tool section in pyproject.toml
with the same
environment and argument properties.
[tool.hatch.envs.types.scripts]
check = "mypy --install-types --non-interactive {args:src/hello_world tests}"
Versioning
Versioning numbering is an important part of the software development lifecycle, particularly as a means to communicate the relative significance of changes from one version to another. The Semantic Versioning specification is one common strategy. The Python PEP 440 specification defines specific rules for public version identifiers to provide a consistent vocabulary for different types of releases.
The Hatch version
command enables semantic changes to version information stored in __about__.py
under the project
package directory. Running the version
command without any arguments prints the current version number.
hatch version
Running the version
command with a specific number updates the version to the value provided.
hatch version 1.0.0
Running the version
command with one or more
supported version segments performs an incremental update to
the segment specified.
hatch version minor
With a current version of 1.0.0
, running the command with the minor
argument sets the version to 1.1.0
.
Conclusion
Incorporating a number of best practices, Hatch provides the essential features for building robust projects in Python. Hatch has a growing community of users across major industries, highlighting significant adoption since the release of version 1.0.0 in 2022. With support for migrating existing projects, Hatch presents a compelling solution for both old and new Python projects.