On this page
PyPI release target that manages version tracking in pyproject.toml and scaffolds CI workflows for OIDC-based publishing to the PyPI index.
#rlsbl.targets.pypi
#rlsbl.targets.pypi
PyPI release target that manages version tracking in pyproject.toml and scaffolds CI workflows for OIDC-based publishing to the PyPI index.
#find_dunder_version_node
def find_dunder_version_node(content: str) -> 'ast.Constant | None'Find an __version__ assignment with a static string literal via AST.
Handles both plain assignments (__version__ = "1.0.0") and typed annotations (__version__: str = "1.0.0"). Returns the ast.Constant node for the string value, or None if not found or the file has a syntax error.
#has_any_dunder_version
def has_any_dunder_version(content: str) -> boolCheck whether the source contains any form of __version__ definition.
Returns True if the content contains any assignment, annotated assignment, or import of __version__ -- regardless of whether the value is a static literal. Returns False on SyntaxError or if no __version__ definition is found.
#PypiTarget
Release target for Python projects (pyproject.toml).
#name
def name(self)#detect
def detect(self, dir_path)Return True if dir_path contains a pyproject.toml with a [project] table.
#read_name
def read_name(self, dir_path, ctx)Read the project name from pyproject.toml.
#read_metadata
def read_metadata(self, dir_path)Read license and description from pyproject.toml.
#publication_probe
def publication_probe(self, dir_path, version, ctx=None)Probe PyPI for a specific version of this package.
#format_version
def format_version(self, version)Translate semver pre-release to PEP 440 format.
1.2.3-alpha.0->1.2.3a01.2.3-beta.1->1.2.3b11.2.3-rc.2->1.2.3rc2- Stable versions pass through unchanged.
#_pep440_to_semver
def _pep440_to_semver(version)Translate PEP 440 pre-release back to semver format.
1.2.3a0->1.2.3-alpha.01.2.3b1->1.2.3-beta.11.2.3rc2->1.2.3-rc.2- Stable versions pass through unchanged.
#read_version
def read_version(self, dir_path)Read the version from pyproject.toml in the given directory.
If the version is in PEP 440 pre-release format (e.g. 1.2.3a0), it is converted back to semver format (1.2.3-alpha.0) so that all internal version handling uses a consistent semver representation.
#write_version
def write_version(self, dir_path, version, ctx)Write a new version to pyproject.toml and __version__ in package source.
Translates semver pre-release versions to PEP 440 format before writing (e.g. 1.2.3-alpha.0 -> 1.2.3a0).
Returns a list of relative file paths (relative to dir_path) that were modified.
#_update_dunder_version
def _update_dunder_version(self, dir_path, doc, version)Update __version__ in the package's __init__.py if present.
Uses AST parsing to find __version__ assignments with static string literals, handling plain assignments and typed annotations.
Returns the relative path (relative to dir_path) of the file that was modified, or None if no file was updated.
#version_file
def version_file(self, dir_path=None)Return the version file name for PyPI projects.
#tag_format
def tag_format(self, version)Return the git tag string for a PyPI release version.
#template_dir
def template_dir(self)Return the path to the PyPI-specific template directory.
#template_vars
def template_vars(self, dir_path, ctx)Extract template variables from the target project's pyproject.toml.
#template_mappings
def template_mappings(self, ctx)Return the PyPI-specific CI workflow template mapping.
#build
def build(self, dir_path, version, *, config=None)Build the package, rewriting path deps if in a monorepo context.
When the project has path dependencies (e.g., sibling packages in a monorepo), copies the project to a temp directory with rewritten pyproject.toml so the working tree is never modified. Otherwise runs uv build in place.
#_build_with_rewrite
def _build_with_rewrite(self, dir_path, pyproject_path, rewrite_map, *, timeout=120)Copy project to a temp dir with rewritten deps, then build.
#check_project_exists
def check_project_exists(self, dir_path)Return True if pyproject.toml exists in dir_path.
#get_project_init_hint
def get_project_init_hint(self)Return a hint for initializing a Python project.
#dev_install_command
def dev_install_command(self, project_dir)Return install specs for editable Python installs via uv.
#registry_display_name
def registry_display_name(self)#run_tests
def run_tests(self, *, project_dir=None, workspace_root=None, skip_sync=False, config=None, check_timeout=None)Run the Python suite via uv (or bare pytest when uv is absent).
#find_dead_modules
def find_dead_modules(self, root, *, exclude_dirs=None, suppress=frozenset())Union-of-imports detector over the project's Python modules.
#find_circular_dependencies
def find_circular_dependencies(self, root, *, exclude_dirs=None)Detect circular imports between the project's Python modules.
#normalize_package_name
def normalize_package_name(self, raw_name)PyPI folds runs of -_. to a single hyphen (PEP 503).
#query_latest_version
def query_latest_version(self, name)Ask PyPI for the latest published version.
#claim_placeholder
def claim_placeholder(self, name, tmpdir)Build and publish a version 0.0.0 sdist/wheel to reserve name.
#yank
def yank(self, project_dir, version, tag, *, reason=None, dry_run=False)Walk the operator through PyPI's manual yank.
PyPI exposes no yank API, so this target prints the steps and waits for the operator to confirm they performed them. The confirmation is the only honest answer available: nothing here can verify the yank.