repomatic.pyproject module

Utilities for reading and interpreting pyproject.toml metadata.

Provides standalone functions for extracting project name and source paths from pyproject.toml. These functions have no dependency on the Metadata singleton and can be used independently.

repomatic.pyproject.read_pyproject_toml(project_root=None)[source]

Parse pyproject.toml from project_root.

Parses are cached per file identity (absolute path, mtime, size), since a single CLI invocation reads the same document many times over: treat the result as read-only.

Parameters:

project_root (Path | None) – Directory holding pyproject.toml. Defaults to the current working directory.

Return type:

dict[str, Any]

Returns:

Parsed contents, or an empty dict when the file is missing or cannot be decoded.

repomatic.pyproject.derive_source_paths(pyproject_data=None)[source]

Derive source code directory name from [project.name].

Converts the project name to its importable form by replacing hyphens with underscores, the universal Python convention that all build backends (setuptools, hatchling, flit, uv) follow by default. For example, name = "extra-platforms" yields ["extra_platforms"].

Parameters:

pyproject_data (dict[str, Any] | None) – Pre-parsed pyproject.toml dict. If None, reads from the current working directory.

Return type:

list[str]

Returns:

Single-element list with the source directory name, or an empty list if no project name is defined.

repomatic.pyproject.resolve_source_paths(config, pyproject_data=None)[source]

Resolve workflow source paths from config or auto-derivation.

Parameters:
  • config (Config) – Loaded Config instance from [tool.repomatic].

  • pyproject_data (dict[str, Any] | None) – Pre-parsed pyproject.toml dict for derivation.

Return type:

list[str] | None

Returns:

List of source directory names, or None when no source paths can be determined (paths should be stripped entirely).

repomatic.pyproject.get_project_name(pyproject_data=None)[source]

Read the project name from pyproject.toml.

Parameters:

pyproject_data (dict[str, Any] | None) – Pre-parsed dict. If None, reads from CWD.

Return type:

str | None

repomatic.pyproject.is_python_project(project_root=None, pyproject_data=None)[source]

Detect whether project_root hosts a Python project.

Returns True when the pyproject.toml parses cleanly through pyproject_metadata.StandardMetadata.from_pyproject: it must declare a PEP 621 [project] table that respects the standard. A pyproject.toml that only carries third-party [tool.*] sections does not qualify, so repositories that merely lean on the file for tool configuration (linters, formatters, [tool.repomatic] itself) are correctly classified as non-Python.

Parameters:
  • project_root (Path | None) – Directory to probe. Ignored when pyproject_data is supplied; otherwise defaults to the current working directory.

  • pyproject_data (dict[str, Any] | None) – Pre-parsed pyproject.toml. Pass this when the caller has already parsed the file (e.g., the Metadata singleton).

Return type:

bool

Returns:

True when the [project] table satisfies PEP 621.

repomatic.pyproject.is_python_package(project_root=None, pyproject_data=None)[source]

Detect whether project_root builds a distributable Python package.

Strictly narrower than is_python_project(): every package is a Python project, but not every Python project is a package. A uv virtual project declares a PEP 621 [project] table purely to carry dependencies, and opts out of being built or installed with [tool.uv] package = false. Blogs, docs sites and dotfiles repos that lean on uv for dependency management all look like this.

The distinction matters because the two traits gate different things. A virtual project still has dependencies to lock, a uv.lock to sync and tests to cover, so it wants everything scoped to PYTHON_ONLY. It has nothing to publish, tag or write release notes for, so it wants nothing scoped to PACKAGE_ONLY.

Note

Only uv’s opt-out is recognized. Poetry’s [tool.poetry] package-mode equivalent is deliberately ignored: repomatic dropped Poetry support in 4.0.0 and expects standard pyproject.toml conventions.

Parameters:
  • project_root (Path | None) – Directory to probe. Ignored when pyproject_data is supplied; otherwise defaults to the current working directory.

  • pyproject_data (dict[str, Any] | None) – Pre-parsed pyproject.toml. Pass this when the caller has already parsed the file.

Return type:

bool

Returns:

True for a PEP 621 project that is not a uv virtual project.