Full Code of pypa/hatch for AI

master b998d2b755bc cached
499 files
2.6 MB
703.1k tokens
3469 symbols
1 requests
Download .txt
Showing preview only (2,803K chars total). Download the full file or copy to clipboard to get everything.
Repository: pypa/hatch
Branch: master
Commit: b998d2b755bc
Files: 499
Total size: 2.6 MB

Directory structure:
gitextract_qo3g_3ii/

├── .gitattributes
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── 1-hatch_bug_report.yml
│   │   └── 2-feature_request.yml
│   ├── dependabot.yml
│   └── workflows/
│       ├── auto-merge.yml
│       ├── build-distributions.yml
│       ├── build-hatch.yml
│       ├── build-hatchling.yml
│       ├── cli.yml
│       ├── docs-dev.yml
│       ├── docs-release.yml
│       └── test.yml
├── .gitignore
├── .linkcheckerrc
├── LICENSE.txt
├── README.md
├── backend/
│   ├── LICENSE.txt
│   ├── README.md
│   ├── pyproject.toml
│   ├── src/
│   │   └── hatchling/
│   │       ├── __about__.py
│   │       ├── __init__.py
│   │       ├── __main__.py
│   │       ├── bridge/
│   │       │   ├── __init__.py
│   │       │   └── app.py
│   │       ├── build.py
│   │       ├── builders/
│   │       │   ├── __init__.py
│   │       │   ├── app.py
│   │       │   ├── binary.py
│   │       │   ├── config.py
│   │       │   ├── constants.py
│   │       │   ├── custom.py
│   │       │   ├── hooks/
│   │       │   │   ├── __init__.py
│   │       │   │   ├── custom.py
│   │       │   │   ├── plugin/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── hooks.py
│   │       │   │   │   └── interface.py
│   │       │   │   └── version.py
│   │       │   ├── macos.py
│   │       │   ├── plugin/
│   │       │   │   ├── __init__.py
│   │       │   │   ├── hooks.py
│   │       │   │   └── interface.py
│   │       │   ├── sdist.py
│   │       │   ├── utils.py
│   │       │   └── wheel.py
│   │       ├── cli/
│   │       │   ├── __init__.py
│   │       │   ├── build/
│   │       │   │   └── __init__.py
│   │       │   ├── dep/
│   │       │   │   ├── __init__.py
│   │       │   │   └── core.py
│   │       │   ├── metadata/
│   │       │   │   └── __init__.py
│   │       │   └── version/
│   │       │       └── __init__.py
│   │       ├── dep/
│   │       │   ├── __init__.py
│   │       │   └── core.py
│   │       ├── licenses/
│   │       │   ├── __init__.py
│   │       │   └── supported.py
│   │       ├── metadata/
│   │       │   ├── __init__.py
│   │       │   ├── core.py
│   │       │   ├── custom.py
│   │       │   ├── plugin/
│   │       │   │   ├── __init__.py
│   │       │   │   ├── hooks.py
│   │       │   │   └── interface.py
│   │       │   ├── spec.py
│   │       │   └── utils.py
│   │       ├── ouroboros.py
│   │       ├── plugin/
│   │       │   ├── __init__.py
│   │       │   ├── exceptions.py
│   │       │   ├── manager.py
│   │       │   ├── specs.py
│   │       │   └── utils.py
│   │       ├── py.typed
│   │       ├── utils/
│   │       │   ├── __init__.py
│   │       │   ├── constants.py
│   │       │   ├── context.py
│   │       │   └── fs.py
│   │       └── version/
│   │           ├── __init__.py
│   │           ├── core.py
│   │           ├── scheme/
│   │           │   ├── __init__.py
│   │           │   ├── plugin/
│   │           │   │   ├── __init__.py
│   │           │   │   ├── hooks.py
│   │           │   │   └── interface.py
│   │           │   └── standard.py
│   │           └── source/
│   │               ├── __init__.py
│   │               ├── code.py
│   │               ├── env.py
│   │               ├── plugin/
│   │               │   ├── __init__.py
│   │               │   ├── hooks.py
│   │               │   └── interface.py
│   │               └── regex.py
│   └── tests/
│       ├── __init__.py
│       └── downstream/
│           ├── datadogpy/
│           │   ├── data.json
│           │   └── pyproject.toml
│           ├── hatch-showcase/
│           │   └── data.json
│           ├── integrate.py
│           └── requirements.txt
├── docs/
│   ├── .hooks/
│   │   ├── expand_blocks.py
│   │   ├── inject_version.py
│   │   ├── plugin_register.py
│   │   ├── render_default_test_env.py
│   │   ├── render_ruff_defaults.py
│   │   └── title_from_content.py
│   ├── .overrides/
│   │   └── partials/
│   │       └── copyright.html
│   ├── .snippets/
│   │   ├── abbrs.txt
│   │   └── links.txt
│   ├── assets/
│   │   ├── badge/
│   │   │   └── v0.json
│   │   └── css/
│   │       └── custom.css
│   ├── blog/
│   │   ├── .authors.yml
│   │   ├── index.md
│   │   └── posts/
│   │       ├── release-hatch-1100.md
│   │       ├── release-hatch-1160.md
│   │       ├── release-hatch-160.md
│   │       ├── release-hatch-180.md
│   │       └── release-hatch-190.md
│   ├── build.md
│   ├── cli/
│   │   ├── about.md
│   │   └── reference.md
│   ├── community/
│   │   ├── contributing.md
│   │   ├── highlights.md
│   │   └── users.md
│   ├── config/
│   │   ├── build.md
│   │   ├── context.md
│   │   ├── dependency.md
│   │   ├── environment/
│   │   │   ├── advanced.md
│   │   │   └── overview.md
│   │   ├── hatch.md
│   │   ├── internal/
│   │   │   ├── build.md
│   │   │   ├── static-analysis.md
│   │   │   └── testing.md
│   │   ├── metadata.md
│   │   └── project-templates.md
│   ├── environment.md
│   ├── history/
│   │   ├── hatch.md
│   │   └── hatchling.md
│   ├── how-to/
│   │   ├── config/
│   │   │   └── dynamic-metadata.md
│   │   ├── environment/
│   │   │   ├── dependency-resolution.md
│   │   │   ├── select-installer.md
│   │   │   └── workspace.md
│   │   ├── integrate/
│   │   │   └── vscode.md
│   │   ├── meta/
│   │   │   └── report-issues.md
│   │   ├── plugins/
│   │   │   └── testing-builds.md
│   │   ├── publish/
│   │   │   ├── auth.md
│   │   │   └── repo.md
│   │   ├── python/
│   │   │   └── custom.md
│   │   ├── run/
│   │   │   └── python-scripts.md
│   │   └── static-analysis/
│   │       └── behavior.md
│   ├── index.md
│   ├── install.md
│   ├── intro.md
│   ├── meta/
│   │   ├── authors.md
│   │   └── faq.md
│   ├── next-steps.md
│   ├── plugins/
│   │   ├── about.md
│   │   ├── build-hook/
│   │   │   ├── custom.md
│   │   │   ├── reference.md
│   │   │   └── version.md
│   │   ├── builder/
│   │   │   ├── binary.md
│   │   │   ├── custom.md
│   │   │   ├── reference.md
│   │   │   ├── sdist.md
│   │   │   └── wheel.md
│   │   ├── environment/
│   │   │   ├── reference.md
│   │   │   └── virtual.md
│   │   ├── environment-collector/
│   │   │   ├── custom.md
│   │   │   ├── default.md
│   │   │   └── reference.md
│   │   ├── metadata-hook/
│   │   │   ├── custom.md
│   │   │   └── reference.md
│   │   ├── publisher/
│   │   │   ├── package-index.md
│   │   │   └── reference.md
│   │   ├── utilities.md
│   │   ├── version-scheme/
│   │   │   ├── reference.md
│   │   │   └── standard.md
│   │   └── version-source/
│   │       ├── code.md
│   │       ├── env.md
│   │       ├── reference.md
│   │       └── regex.md
│   ├── publish.md
│   ├── tutorials/
│   │   ├── environment/
│   │   │   └── basic-usage.md
│   │   ├── python/
│   │   │   └── manage.md
│   │   └── testing/
│   │       └── overview.md
│   ├── version.md
│   └── why.md
├── hatch.toml
├── mkdocs.insiders.yml
├── mkdocs.yml
├── pyoxidizer.bzl
├── pyproject.toml
├── release/
│   ├── README.md
│   ├── macos/
│   │   ├── build_pkg.py
│   │   └── pkg/
│   │       └── distribution.xml
│   ├── unix/
│   │   └── make_scripts_portable.py
│   └── windows/
│       └── make_scripts_portable.py
├── ruff.toml
├── ruff_defaults.toml
├── scripts/
│   ├── bump.py
│   ├── generate_coverage_summary.py
│   ├── install_mkdocs_material_insiders.py
│   ├── release_github.py
│   ├── set_release_version.py
│   ├── update_distributions.py
│   ├── update_ruff.py
│   ├── utils.py
│   ├── validate_history.py
│   └── write_coverage_summary_report.py
├── src/
│   └── hatch/
│       ├── __init__.py
│       ├── __main__.py
│       ├── cli/
│       │   ├── __init__.py
│       │   ├── application.py
│       │   ├── build/
│       │   │   └── __init__.py
│       │   ├── clean/
│       │   │   └── __init__.py
│       │   ├── config/
│       │   │   └── __init__.py
│       │   ├── dep/
│       │   │   └── __init__.py
│       │   ├── env/
│       │   │   ├── __init__.py
│       │   │   ├── create.py
│       │   │   ├── find.py
│       │   │   ├── prune.py
│       │   │   ├── remove.py
│       │   │   ├── run.py
│       │   │   └── show.py
│       │   ├── fmt/
│       │   │   ├── __init__.py
│       │   │   └── core.py
│       │   ├── new/
│       │   │   ├── __init__.py
│       │   │   └── migrate.py
│       │   ├── project/
│       │   │   ├── __init__.py
│       │   │   └── metadata.py
│       │   ├── publish/
│       │   │   └── __init__.py
│       │   ├── python/
│       │   │   ├── __init__.py
│       │   │   ├── find.py
│       │   │   ├── install.py
│       │   │   ├── remove.py
│       │   │   ├── show.py
│       │   │   └── update.py
│       │   ├── run/
│       │   │   └── __init__.py
│       │   ├── self/
│       │   │   ├── __init__.py
│       │   │   ├── report.py
│       │   │   ├── restore.py
│       │   │   └── update.py
│       │   ├── shell/
│       │   │   └── __init__.py
│       │   ├── status/
│       │   │   └── __init__.py
│       │   ├── terminal.py
│       │   ├── test/
│       │   │   ├── __init__.py
│       │   │   └── core.py
│       │   └── version/
│       │       └── __init__.py
│       ├── config/
│       │   ├── __init__.py
│       │   ├── constants.py
│       │   ├── model.py
│       │   ├── user.py
│       │   └── utils.py
│       ├── dep/
│       │   ├── __init__.py
│       │   ├── core.py
│       │   └── sync.py
│       ├── env/
│       │   ├── __init__.py
│       │   ├── collectors/
│       │   │   ├── __init__.py
│       │   │   ├── custom.py
│       │   │   ├── default.py
│       │   │   └── plugin/
│       │   │       ├── __init__.py
│       │   │       ├── hooks.py
│       │   │       └── interface.py
│       │   ├── context.py
│       │   ├── internal/
│       │   │   ├── __init__.py
│       │   │   ├── build.py
│       │   │   ├── static_analysis.py
│       │   │   ├── test.py
│       │   │   └── uv.py
│       │   ├── plugin/
│       │   │   ├── __init__.py
│       │   │   ├── hooks.py
│       │   │   └── interface.py
│       │   ├── system.py
│       │   ├── utils.py
│       │   └── virtual.py
│       ├── errors/
│       │   └── __init__.py
│       ├── index/
│       │   ├── __init__.py
│       │   ├── core.py
│       │   ├── errors.py
│       │   └── publish.py
│       ├── plugin/
│       │   ├── __init__.py
│       │   ├── constants.py
│       │   ├── manager.py
│       │   ├── specs.py
│       │   └── utils.py
│       ├── project/
│       │   ├── __init__.py
│       │   ├── config.py
│       │   ├── constants.py
│       │   ├── core.py
│       │   ├── env.py
│       │   ├── frontend/
│       │   │   ├── __init__.py
│       │   │   ├── core.py
│       │   │   └── scripts/
│       │   │       ├── __init__.py
│       │   │       ├── build_deps.py
│       │   │       ├── core_metadata.py
│       │   │       └── standard.py
│       │   └── utils.py
│       ├── publish/
│       │   ├── __init__.py
│       │   ├── auth.py
│       │   ├── index.py
│       │   └── plugin/
│       │       ├── __init__.py
│       │       ├── hooks.py
│       │       └── interface.py
│       ├── py.typed
│       ├── python/
│       │   ├── __init__.py
│       │   ├── core.py
│       │   ├── distributions.py
│       │   └── resolve.py
│       ├── template/
│       │   ├── __init__.py
│       │   ├── default.py
│       │   ├── files_default.py
│       │   ├── files_feature_ci.py
│       │   ├── files_feature_cli.py
│       │   ├── files_feature_tests.py
│       │   └── plugin/
│       │       ├── __init__.py
│       │       ├── hooks.py
│       │       └── interface.py
│       ├── utils/
│       │   ├── __init__.py
│       │   ├── ci.py
│       │   ├── dep.py
│       │   ├── env.py
│       │   ├── fs.py
│       │   ├── metadata.py
│       │   ├── network.py
│       │   ├── platform.py
│       │   ├── runner.py
│       │   ├── shells.py
│       │   ├── structures.py
│       │   └── toml.py
│       └── venv/
│           ├── __init__.py
│           ├── core.py
│           └── utils.py
└── tests/
    ├── __init__.py
    ├── backend/
    │   ├── __init__.py
    │   ├── builders/
    │   │   ├── __init__.py
    │   │   ├── hooks/
    │   │   │   ├── __init__.py
    │   │   │   ├── test_custom.py
    │   │   │   └── test_version.py
    │   │   ├── plugin/
    │   │   │   ├── __init__.py
    │   │   │   └── test_interface.py
    │   │   ├── test_binary.py
    │   │   ├── test_config.py
    │   │   ├── test_custom.py
    │   │   ├── test_sdist.py
    │   │   ├── test_wheel.py
    │   │   └── utils.py
    │   ├── metadata/
    │   │   ├── __init__.py
    │   │   ├── test_build.py
    │   │   ├── test_core.py
    │   │   ├── test_custom_hook.py
    │   │   ├── test_hatch.py
    │   │   └── test_spec.py
    │   ├── test_build.py
    │   ├── utils/
    │   │   ├── __init__.py
    │   │   ├── test_context.py
    │   │   ├── test_fs.py
    │   │   └── test_macos.py
    │   └── version/
    │       ├── __init__.py
    │       ├── scheme/
    │       │   ├── __init__.py
    │       │   └── test_standard.py
    │       └── source/
    │           ├── __init__.py
    │           ├── test_code.py
    │           ├── test_env.py
    │           └── test_regex.py
    ├── cli/
    │   ├── __init__.py
    │   ├── build/
    │   │   ├── __init__.py
    │   │   └── test_build.py
    │   ├── clean/
    │   │   ├── __init__.py
    │   │   └── test_clean.py
    │   ├── config/
    │   │   ├── __init__.py
    │   │   ├── test_explore.py
    │   │   ├── test_find.py
    │   │   ├── test_restore.py
    │   │   ├── test_set.py
    │   │   └── test_show.py
    │   ├── dep/
    │   │   ├── __init__.py
    │   │   ├── show/
    │   │   │   ├── __init__.py
    │   │   │   ├── test_requirements.py
    │   │   │   └── test_table.py
    │   │   └── test_hash.py
    │   ├── env/
    │   │   ├── __init__.py
    │   │   ├── test_create.py
    │   │   ├── test_find.py
    │   │   ├── test_prune.py
    │   │   ├── test_remove.py
    │   │   ├── test_run.py
    │   │   └── test_show.py
    │   ├── fmt/
    │   │   ├── __init__.py
    │   │   └── test_fmt.py
    │   ├── new/
    │   │   ├── __init__.py
    │   │   └── test_new.py
    │   ├── project/
    │   │   ├── __init__.py
    │   │   └── test_metadata.py
    │   ├── publish/
    │   │   ├── __init__.py
    │   │   └── test_publish.py
    │   ├── python/
    │   │   ├── __init__.py
    │   │   ├── conftest.py
    │   │   ├── test_find.py
    │   │   ├── test_install.py
    │   │   ├── test_remove.py
    │   │   ├── test_show.py
    │   │   └── test_update.py
    │   ├── run/
    │   │   ├── __init__.py
    │   │   └── test_run.py
    │   ├── self/
    │   │   ├── __init__.py
    │   │   ├── test_report.py
    │   │   └── test_self.py
    │   ├── status/
    │   │   ├── __init__.py
    │   │   └── test_status.py
    │   ├── test/
    │   │   ├── __init__.py
    │   │   └── test_test.py
    │   ├── test_root.py
    │   └── version/
    │       ├── __init__.py
    │       └── test_version.py
    ├── config/
    │   ├── __init__.py
    │   └── test_model.py
    ├── conftest.py
    ├── dep/
    │   ├── __init__.py
    │   └── test_sync.py
    ├── env/
    │   ├── __init__.py
    │   ├── collectors/
    │   │   ├── __init__.py
    │   │   └── test_custom.py
    │   └── plugin/
    │       ├── __init__.py
    │       └── test_interface.py
    ├── helpers/
    │   ├── __init__.py
    │   ├── helpers.py
    │   └── templates/
    │       ├── __init__.py
    │       ├── licenses/
    │       │   └── __init__.py
    │       ├── new/
    │       │   ├── __init__.py
    │       │   ├── basic.py
    │       │   ├── default.py
    │       │   ├── feature_ci.py
    │       │   ├── feature_cli.py
    │       │   ├── feature_no_src_layout.py
    │       │   ├── licenses_empty.py
    │       │   ├── licenses_multiple.py
    │       │   ├── projects_urls_empty.py
    │       │   └── projects_urls_space_in_label.py
    │       ├── sdist/
    │       │   ├── __init__.py
    │       │   ├── standard_default.py
    │       │   ├── standard_default_build_script_artifacts.py
    │       │   ├── standard_default_build_script_extra_dependencies.py
    │       │   ├── standard_default_support_legacy.py
    │       │   ├── standard_default_vcs_git_exclusion_files.py
    │       │   ├── standard_default_vcs_mercurial_exclusion_files.py
    │       │   ├── standard_include.py
    │       │   └── standard_include_config_file.py
    │       └── wheel/
    │           ├── __init__.py
    │           ├── standard_default_build_script.py
    │           ├── standard_default_build_script_artifacts.py
    │           ├── standard_default_build_script_artifacts_with_src_layout.py
    │           ├── standard_default_build_script_configured_build_hooks.py
    │           ├── standard_default_build_script_extra_dependencies.py
    │           ├── standard_default_build_script_force_include.py
    │           ├── standard_default_build_script_force_include_no_duplication.py
    │           ├── standard_default_extra_metadata.py
    │           ├── standard_default_license_multiple.py
    │           ├── standard_default_license_single.py
    │           ├── standard_default_namespace_package.py
    │           ├── standard_default_python_constraint.py
    │           ├── standard_default_python_constraint_three_components.py
    │           ├── standard_default_sbom.py
    │           ├── standard_default_shared_data.py
    │           ├── standard_default_shared_scripts.py
    │           ├── standard_default_single_module.py
    │           ├── standard_default_symlink.py
    │           ├── standard_editable_exact.py
    │           ├── standard_editable_exact_extra_dependencies.py
    │           ├── standard_editable_exact_force_include.py
    │           ├── standard_editable_pth.py
    │           ├── standard_editable_pth_extra_dependencies.py
    │           ├── standard_editable_pth_force_include.py
    │           ├── standard_entry_points.py
    │           ├── standard_no_strict_naming.py
    │           ├── standard_only_packages_artifact_override.py
    │           ├── standard_tests.py
    │           └── utils.py
    ├── index/
    │   ├── __init__.py
    │   ├── server/
    │   │   ├── devpi/
    │   │   │   ├── Dockerfile
    │   │   │   └── entrypoint.sh
    │   │   ├── docker-compose.yaml
    │   │   └── nginx/
    │   │       └── nginx.conf
    │   └── test_core.py
    ├── project/
    │   ├── __init__.py
    │   ├── test_config.py
    │   ├── test_core.py
    │   ├── test_frontend.py
    │   └── test_utils.py
    ├── publish/
    │   ├── __init__.py
    │   └── plugin/
    │       ├── __init__.py
    │       └── test_interface.py
    ├── python/
    │   ├── __init__.py
    │   ├── test_core.py
    │   └── test_resolve.py
    ├── utils/
    │   ├── __init__.py
    │   ├── test_auth.py
    │   ├── test_fs.py
    │   ├── test_platform.py
    │   ├── test_runner.py
    │   └── test_structures.py
    ├── venv/
    │   ├── __init__.py
    │   ├── test_core.py
    │   └── test_utils.py
    └── workspaces/
        ├── __init__.py
        └── test_config.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitattributes
================================================
# Auto detect text files and perform LF normalization
* text=auto

================================================
FILE: .github/FUNDING.yml
================================================
github:
- ofek
custom:
- https://ofek.dev/donate/


================================================
FILE: .github/ISSUE_TEMPLATE/1-hatch_bug_report.yml
================================================
---
name: Hatch Bug report
description: Problems and issues with code in Hatch
body:
- type: markdown
  attributes:
    # yamllint disable rule:line-length
    value: "
      <img src='https://raw.githubusercontent.com/pypa/hatch/HEAD/docs/assets/images/logo.svg' align='left' width='80' height='80'>
      Thank you for finding the time to report the problem, we ask that you use 
      the command `hatch self report` to report bugs instead of using this form.
      
      <br clear='left'/>"
    # yamllint enable rule:line-length


================================================
FILE: .github/ISSUE_TEMPLATE/2-feature_request.yml
================================================
---
name: Hatch feature request
description: Suggest an idea for this project
labels: ["kind:feature"]
body:
- type: markdown
  attributes:
    # yamllint disable rule:line-length
    value: |
      <img src='https://raw.githubusercontent.com/pypa/hatch/HEAD/docs/assets/images/logo.svg' align='left' width='80' height='80'>
      Thank you for finding the time to propose new feature!

      We really appreciate the community efforts to improve Hatch.

      Please keep feature requests to smaller incremental changes that do not make changes to the assumptions
      about hatch. 
      
      If unsure - open a [discussion](https://github.com/pypa/hatch/discussions) first to gather
      an initial feedback on your idea.

      <br clear='left'/>

    # yamllint enable rule:line-length
- type: textarea
  attributes:
    label: Description
    description: A short description of your feature
- type: textarea
  attributes:
    label: Use case/motivation
    description: What would you like to happen?
    placeholder: >
      Rather than telling us how you might implement this feature, try to take a
      step back and describe what you are trying to achieve.
- type: textarea
  attributes:
    label: Related issues
    description: Is there currently another issue associated with this?
- type: checkboxes
  attributes:
    label: Are you willing to submit a PR?
    description: >
      If want to submit a PR you do not need to open feature request, <b>just create the PR!</b>.
      Especially if you already have a good understanding of how to implement the feature.
      Hatch is a PyPA managed project but we love to bring new contributors in.
      Find us on the PyPA Discord Server under #hatch
      It's optional though - if you have good idea for small feature,
      others might implement it if they pick an interest in it, so feel free to leave that
      checkbox unchecked.
    options:
    - label: Yes I am willing to submit a PR!
- type: checkboxes
  attributes:
    label: Code of Conduct
    description: The Code of Conduct helps create a safe space for everyone. We require
      that everyone agrees to it.
    options:
    - label: >
        I agree to follow the Python Software Foundation's
        [Code of Conduct](https://policies.python.org/python.org/code-of-conduct/)
      required: true
- type: markdown
  attributes:
    value: Thanks for completing our form!


================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: github-actions
  directory: /
  schedule:
    interval: monthly


================================================
FILE: .github/workflows/auto-merge.yml
================================================
name: auto-merge

on:
  pull_request_target:
    types:
    - opened
    - reopened
    - synchronize
    branches:
    - master

jobs:
  dependabot:
    runs-on: ubuntu-latest
    if: ${{ github.actor == 'dependabot[bot]' }}

    steps:
    - name: Wait for tests to succeed
      uses: lewagon/wait-on-check-action@v1.3.4
      with:
        ref: ${{ github.ref }}
        check-name: check
        wait-interval: 10
        repo-token: ${{ secrets.GITHUB_TOKEN }}

    - name: Enable auto-merge for Dependabot PRs
      run: gh pr merge --auto --squash ${{ github.event.pull_request.html_url }}
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .github/workflows/build-distributions.yml
================================================
name: build distributions

on:
  workflow_call:
    inputs:
      version:
        required: false
        type: string

defaults:
  run:
    shell: bash

env:
  DIST_URL: "https://github.com/indygreg/python-build-standalone/releases/download"
  DIST_VERSION: "20240415"
  DIST_PYTHON_VERSION: "3.12.3"
  PYTHONDONTWRITEBYTECODE: "1"
  PIP_ONLY_BINARY: ":all:"
  # Some pip environment variables are weird, this means do not compile
  PIP_NO_COMPILE: "0"

jobs:
  ensure-installable:
    name: Ensure Hatch is installable
    runs-on: ubuntu-22.04

    steps:
    - name: Set up Python ${{ env.DIST_PYTHON_VERSION }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ env.DIST_PYTHON_VERSION }}

    - name: Install UV
      uses: astral-sh/setup-uv@v3

    - name: Install Hatch
      if: inputs.version
      # Try to install the specific version of Hatch that was just released until successful
      run: |-
        for i in {1..20}; do
          uv pip install --system hatch==${{ inputs.version }} && break || sleep 5
        done

  linux:
    name: Distribution ${{ matrix.job.target }}
    needs: ensure-installable
    runs-on: ubuntu-22.04
    strategy:
      fail-fast: false
      matrix:
        job:
        - target: x86_64-unknown-linux-gnu
          image: quay.io/pypa/manylinux2014_x86_64
          target-override: x86_64_v3-unknown-linux-gnu
        - target: aarch64-unknown-linux-gnu
          image: quay.io/pypa/manylinux_2_28_aarch64
          emulation: arm64

    steps:
    - name: Checkout code
      uses: actions/checkout@v4
      with:
        fetch-depth: ${{ inputs.version && 1 || 0 }}

    - name: Set up QEMU
      if: matrix.job.emulation
      uses: docker/setup-qemu-action@v3

    - name: Set up Docker container
      run: >-
        docker run --rm -d
        --name builder
        --workdir /home
        --env PYTHONDONTWRITEBYTECODE
        --env PIP_ONLY_BINARY
        --env PIP_NO_COMPILE
        --volume ${{ github.workspace }}:/home/hatch
        ${{ matrix.job.image }}
        sleep infinity

    - name: Download distribution
      run: >-
        docker exec builder
        curl -LO
        ${{ env.DIST_URL }}/${{ env.DIST_VERSION }}/cpython-${{ env.DIST_PYTHON_VERSION }}+${{ env.DIST_VERSION }}-${{ matrix.job.target-override || matrix.job.target }}-install_only.tar.gz

    - name: Unpack distribution
      run: >-
        docker exec builder
        tar xzf cpython-${{ env.DIST_PYTHON_VERSION }}+${{ env.DIST_VERSION }}-${{ matrix.job.target-override || matrix.job.target }}-install_only.tar.gz

    - name: Install Hatch
      run: >-
        docker exec builder
        /home/python/bin/python -m pip install
        ${{ inputs.version && format('hatch=={0}', inputs.version) || '/home/hatch' }}

    - name: Make scripts portable
      run: >-
        docker exec builder
        /home/python/bin/python /home/hatch/release/unix/make_scripts_portable.py

    - name: Strip debug symbols
      run: >-
        docker exec builder
        sh -c "find /home/python -name '*.so' | xargs strip -S"

    - name: Archive distribution
      run: >-
        docker exec builder
        tar czf hatch-dist-${{ matrix.job.target }}.tar.gz python

    - name: Move to host
      run: docker cp builder:/home/hatch-dist-${{ matrix.job.target }}.tar.gz .

    - name: Check original size
      run: >-
        docker exec builder
        ls -lh cpython-${{ env.DIST_PYTHON_VERSION }}+${{ env.DIST_VERSION }}-${{ matrix.job.target-override || matrix.job.target }}-install_only.tar.gz

    - name: Check final size
      run: ls -lh hatch-dist-${{ matrix.job.target }}.tar.gz

    - name: Upload archive
      uses: actions/upload-artifact@v4
      with:
        name: distribution-${{ matrix.job.target }}
        path: hatch-dist-${{ matrix.job.target }}.tar.gz

  windows-macos:
    name: Distribution ${{ matrix.job.target }}
    needs: ensure-installable
    runs-on: ${{ matrix.job.os }}
    strategy:
      fail-fast: false
      matrix:
        job:
        - target: x86_64-pc-windows-msvc
          os: windows-2022
        - target: aarch64-apple-darwin
          os: macos-14
        - target: x86_64-apple-darwin
          os: macos-14

    steps:
    - name: Checkout code
      uses: actions/checkout@v4
      with:
        fetch-depth: ${{ inputs.version && 1 || 0 }}

    - name: Download distribution
      run: curl -LO ${{ env.DIST_URL }}/${{ env.DIST_VERSION }}/cpython-${{ env.DIST_PYTHON_VERSION }}+${{ env.DIST_VERSION }}-${{ matrix.job.target }}-install_only.tar.gz

    - name: Unpack distribution
      run: tar xzf cpython-${{ env.DIST_PYTHON_VERSION }}+${{ env.DIST_VERSION }}-${{ matrix.job.target }}-install_only.tar.gz

    - name: Install Hatch
      run: >-
        ${{ startsWith(matrix.job.os, 'windows-') && '.\\python\\python.exe' || './python/bin/python' }}
        -m pip install
        ${{ inputs.version && format('hatch=={0}', inputs.version) || '.' }}

    - name: Make scripts portable
      run: >-
        ${{ startsWith(matrix.job.os, 'windows-') && '.\\python\\python.exe' || './python/bin/python' }}
        release/${{ startsWith(matrix.job.os, 'windows-') && 'windows' || 'unix' }}/make_scripts_portable.py

    - name: Strip debug symbols
      if: startsWith(matrix.job.os, 'macos-')
      run: find python -name '*.so' | xargs strip -S

    - name: Remove debug symbols
      if: startsWith(matrix.job.os, 'windows-')
      run: Get-ChildItem -Path python -Filter "*.pdb" -Recurse | Remove-Item
      shell: pwsh

    - name: Archive distribution
      run: tar czf hatch-dist-${{ matrix.job.target }}.tar.gz python

    - name: Check original size
      run: ls -lh cpython-${{ env.DIST_PYTHON_VERSION }}+${{ env.DIST_VERSION }}-${{ matrix.job.target }}-install_only.tar.gz

    - name: Check final size
      run: ls -lh hatch-dist-${{ matrix.job.target }}.tar.gz

    - name: Upload archive
      uses: actions/upload-artifact@v4
      with:
        name: distribution-${{ matrix.job.target }}
        path: hatch-dist-${{ matrix.job.target }}.tar.gz


================================================
FILE: .github/workflows/build-hatch.yml
================================================
name: build hatch

on:
  push:
    tags:
    - hatch-v*
    branches:
    - master
  pull_request:
    branches:
    - master

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
  cancel-in-progress: true

defaults:
  run:
    shell: bash

env:
  APP_NAME: hatch
  PYTHON_VERSION: "3.12"
  PYOXIDIZER_VERSION: "0.24.0"
  DIST_URL: "https://github.com/pypa/hatch/releases/download"

jobs:
  python-artifacts:
    name: Build wheel and source distribution
    runs-on: ubuntu-latest

    outputs:
      old-version: ${{ steps.version.outputs.old-version }}
      version: ${{ steps.version.outputs.version }}

    steps:
    - name: Checkout code
      uses: actions/checkout@v4
      with:
        fetch-depth: 0

    - name: Set up Python ${{ env.PYTHON_VERSION }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ env.PYTHON_VERSION }}

    - name: Install UV
      uses: astral-sh/setup-uv@v3

    - name: Install tools
      run: |-
        uv pip install --system build
        uv pip install --system .
        hatch env create

    # Windows installers don't accept non-integer versions so we ubiquitously
    # perform the following transformation: X.Y.Z.devN -> X.Y.Z.N
    - name: Set project version
      id: version
      run: |-
        old_version="$(hatch version)"
        version="${old_version/dev/}"

        echo "old-version=$old_version" >> $GITHUB_OUTPUT
        echo "version=$version" >> $GITHUB_OUTPUT
        echo "$version"

    - name: Build
      run: python -m build

    - name: Upload artifacts
      uses: actions/upload-artifact@v4
      with:
        name: python-artifacts
        path: dist/*
        if-no-files-found: error

  publish-pypi:
    name: Publish to PyPI
    if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
    needs: python-artifacts
    runs-on: ubuntu-latest

    permissions:
      id-token: write

    steps:
    - name: Download Python artifacts
      uses: actions/download-artifact@v4
      with:
        name: python-artifacts
        path: dist

    - name: Push Python artifacts to PyPI
      uses: pypa/gh-action-pypi-publish@v1.12.3
      with:
        skip-existing: true

  binaries:
    name: Binary ${{ matrix.job.target }} (${{ matrix.job.os }})
    needs:
    - python-artifacts
    runs-on: ${{ matrix.job.os }}
    strategy:
      fail-fast: false
      matrix:
        job:
        # Linux
        - target: aarch64-unknown-linux-gnu
          os: ubuntu-22.04
          use-dist: true
          cross: true
        - target: x86_64-unknown-linux-gnu
          os: ubuntu-22.04
          use-dist: true
          cross: true
        - target: x86_64-unknown-linux-musl
          os: ubuntu-22.04
          cross: true
        - target: powerpc64le-unknown-linux-gnu
          os: ubuntu-22.04
          cross: true
        # Windows
        - target: x86_64-pc-windows-msvc
          os: windows-2022
          use-dist: true
        - target: i686-pc-windows-msvc
          os: windows-2022
        # macOS
        - target: aarch64-apple-darwin
          os: macos-14
          use-dist: true
        - target: x86_64-apple-darwin
          os: macos-14
          use-dist: true

    env:
      CARGO: cargo
      CARGO_BUILD_TARGET: ${{ matrix.job.target }}
      PYAPP_REPO: pyapp
      PYAPP_VERSION: "0.22.0"
      PYAPP_UV_ENABLED: "true"
      PYAPP_PASS_LOCATION: "true"

    steps:
    - name: Checkout code
      uses: actions/checkout@v4
      with:
        fetch-depth: 0

    - name: Fetch PyApp
      run: >-
        mkdir $PYAPP_REPO && curl -L
        https://github.com/ofek/pyapp/releases/download/v$PYAPP_VERSION/source.tar.gz
        |
        tar --strip-components=1 -xzf - -C $PYAPP_REPO

    - name: Set up Python ${{ env.PYTHON_VERSION }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ env.PYTHON_VERSION }}

    - name: Install UV
      uses: astral-sh/setup-uv@v3

    - name: Install Hatch
      run: |-
        uv pip install --system -e .
        hatch env create

    - name: Install Rust toolchain
      uses: dtolnay/rust-toolchain@stable
      with:
        targets: ${{ matrix.job.target }}

    - name: Set up cross compiling
      if: matrix.job.cross
      uses: taiki-e/install-action@v2
      with:
        tool: cross

    - name: Configure cross compiling
      if: matrix.job.cross
      run: echo "CARGO=cross" >> $GITHUB_ENV

    - name: Configure target
      run: |-
        config_file="$PYAPP_REPO/.cargo/config_${{ matrix.job.target }}.toml"
        if [[ -f "$config_file" ]]; then
          mv "$config_file" "$PYAPP_REPO/.cargo/config.toml"
        fi

    - name: Download Python artifacts
      if: ${{ !startsWith(github.event.ref, 'refs/tags') }}
      uses: actions/download-artifact@v4
      with:
        name: python-artifacts
        path: dist

    - name: Configure embedded project
      if: ${{ !startsWith(github.event.ref, 'refs/tags') }}
      run: |-
        cd dist
        wheel="$(echo *.whl)"
        mv "$wheel" "../$PYAPP_REPO"
        echo "PYAPP_PROJECT_PATH=$wheel" >> $GITHUB_ENV

    - name: Configure release with distribution
      if: startsWith(github.event.ref, 'refs/tags') && matrix.job.use-dist
      run: |-
        echo "PYAPP_SKIP_INSTALL=true" >> $GITHUB_ENV
        echo "PYAPP_FULL_ISOLATION=true" >> $GITHUB_ENV
        echo "PYAPP_DISTRIBUTION_SOURCE=${{ env.DIST_URL }}/hatch-v${{ needs.python-artifacts.outputs.version }}/hatch-dist-${{ matrix.job.target }}.tar.gz" >> $GITHUB_ENV
        echo "PYAPP_DISTRIBUTION_PATH_PREFIX=python" >> $GITHUB_ENV
        echo "PYAPP_ALLOW_UPDATES=true" >> $GITHUB_ENV

        # Disable in the case of self updates
        echo "PYAPP_UV_ENABLED=false" >> $GITHUB_ENV

    - name: Build binary
      run: hatch build --target binary

    - name: Correct binary version
      run: |-
        old_version="${{ needs.python-artifacts.outputs.old-version }}"
        version="${{ needs.python-artifacts.outputs.version }}"

        if [[ "$version" != "$old_version" ]]; then
          cd dist/binary
          old_binary="$(ls)"
          binary="${old_binary/$old_version/$version}"
          mv "$old_binary" "$binary"
        fi

    - name: Archive binary
      run: |-
        mkdir packaging
        cd dist/binary

        old_binary="$(ls)"

        if [[ "$old_binary" =~ -pc-windows- ]]; then
          new_binary="${{ env.APP_NAME }}.exe"
          mv "$old_binary" "$new_binary"
          7z a "../../packaging/${{ env.APP_NAME }}-${{ matrix.job.target }}.zip" "$new_binary"
        else
          new_binary="${{ env.APP_NAME }}"
          mv "$old_binary" "$new_binary"
          chmod +x "$new_binary"
          tar -czf "../../packaging/${{ env.APP_NAME }}-${{ matrix.job.target }}.tar.gz" "$new_binary"
        fi

    - name: Upload staged archive
      if: runner.os != 'Linux'
      uses: actions/upload-artifact@v4
      with:
        name: staged-${{ runner.os }}-${{ matrix.job.target }}
        path: packaging/*
        if-no-files-found: error

    - name: Upload archive
      if: runner.os == 'Linux'
      uses: actions/upload-artifact@v4
      with:
        name: standalone-${{ matrix.job.target }}
        path: packaging/*
        if-no-files-found: error

  windows-packaging:
    name: Build Windows installers
    if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository
    needs:
    - binaries
    - python-artifacts
    runs-on: windows-2022

    env:
      VERSION: ${{ needs.python-artifacts.outputs.version }}

    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Set up Python ${{ env.PYTHON_VERSION }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ env.PYTHON_VERSION }}

    - name: Install UV
      uses: astral-sh/setup-uv@v3

    - name: Install PyOxidizer ${{ env.PYOXIDIZER_VERSION }}
      run: uv pip install --system pyoxidizer==${{ env.PYOXIDIZER_VERSION }}

    - name: Download staged binaries
      uses: actions/download-artifact@v4
      with:
        pattern: staged-${{ runner.os }}-*
        path: archives
        merge-multiple: true

    - name: Extract staged binaries
      run: |-
        mkdir bin

        cd archives
        for f in *; do
          binary_id=${f:0:-4}
          7z e "$f" -o../bin
          mv "../bin/${{ env.APP_NAME }}.exe" "../bin/$binary_id.exe"
        done

    # bin/<APP_NAME>-<TARGET>.exe -> targets/<TARGET>/<APP_NAME>.exe
    - name: Prepare binaries
      run: |-
        mkdir targets
        for f in bin/*; do
          if [[ "$f" =~ ${{ env.APP_NAME }}-(.+).exe$ ]]; then
            target="${BASH_REMATCH[1]}"
            mkdir "targets/$target"
            mv "$f" "targets/$target/${{ env.APP_NAME }}.exe"
          fi
        done

    - name: Build installers
      run: >-
        pyoxidizer build windows_installers
        --release
        --var version ${{ env.VERSION }}

    - name: Prepare installers
      run: |-
        mkdir installers
        mv build/*/release/*/*.{exe,msi} installers

        cd installers
        universal_installer="$(ls *.exe)"
        mv "$universal_installer" "${{ env.APP_NAME }}-universal.exe"

    - name: Upload binaries
      uses: actions/upload-artifact@v4
      with:
        name: standalone-${{ runner.os }}
        path: archives/*
        if-no-files-found: error

    - name: Upload installers
      uses: actions/upload-artifact@v4
      with:
        name: installers-${{ runner.os }}
        path: installers/*
        if-no-files-found: error

  macos-packaging:
    name: Build macOS installer and sign/notarize artifacts
    if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository
    needs:
    - binaries
    - python-artifacts
    runs-on: macos-14

    env:
      VERSION: ${{ needs.python-artifacts.outputs.version }}
      NOTARY_WAIT_TIME: "3600"  # 1 hour

    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Set up Python ${{ env.PYTHON_VERSION }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ env.PYTHON_VERSION }}

    - name: Install UV
      uses: astral-sh/setup-uv@v3

    - name: Install PyOxidizer ${{ env.PYOXIDIZER_VERSION }}
      run: uv pip install --system pyoxidizer==${{ env.PYOXIDIZER_VERSION }}

    - name: Install rcodesign
      env:
        ARCHIVE_NAME: "apple-codesign-0.27.0-x86_64-apple-darwin"
      run: >-
        curl -L
        "https://github.com/indygreg/apple-platform-rs/releases/download/apple-codesign%2F0.27.0/$ARCHIVE_NAME.tar.gz"
        |
        tar --strip-components=1 -xzf - -C /usr/local/bin "$ARCHIVE_NAME/rcodesign"

    - name: Download staged binaries
      uses: actions/download-artifact@v4
      with:
        pattern: staged-${{ runner.os }}-*
        path: archives
        merge-multiple: true

    - name: Extract staged binaries
      run: |-
        mkdir bin

        cd archives
        for f in *; do
          binary_id=${f:0:${#f}-7}
          tar -xzf "$f" -C ../bin
          mv "../bin/${{ env.APP_NAME }}" "../bin/$binary_id"
        done

    - name: Write credentials
      env:
        APPLE_DEVELOPER_ID_APPLICATION_CERTIFICATE: "${{ secrets.APPLE_DEVELOPER_ID_APPLICATION_CERTIFICATE }}"
        APPLE_DEVELOPER_ID_APPLICATION_PRIVATE_KEY: "${{ secrets.APPLE_DEVELOPER_ID_APPLICATION_PRIVATE_KEY }}"
        APPLE_DEVELOPER_ID_INSTALLER_CERTIFICATE: "${{ secrets.APPLE_DEVELOPER_ID_INSTALLER_CERTIFICATE }}"
        APPLE_DEVELOPER_ID_INSTALLER_PRIVATE_KEY: "${{ secrets.APPLE_DEVELOPER_ID_INSTALLER_PRIVATE_KEY }}"
        APPLE_APP_STORE_CONNECT_API_DATA: "${{ secrets.APPLE_APP_STORE_CONNECT_API_DATA }}"
      run: |-
        echo "$APPLE_DEVELOPER_ID_APPLICATION_CERTIFICATE" > /tmp/certificate-application.pem
        echo "$APPLE_DEVELOPER_ID_APPLICATION_PRIVATE_KEY" > /tmp/private-key-application.pem
        echo "$APPLE_DEVELOPER_ID_INSTALLER_CERTIFICATE" > /tmp/certificate-installer.pem
        echo "$APPLE_DEVELOPER_ID_INSTALLER_PRIVATE_KEY" > /tmp/private-key-installer.pem
        echo "$APPLE_APP_STORE_CONNECT_API_DATA" > /tmp/app-store-connect.json

    # https://developer.apple.com/documentation/security/hardened_runtime
    - name: Sign binaries
      run: |-
        for f in bin/*; do
          rcodesign sign -vv \
          --pem-source /tmp/certificate-application.pem \
          --pem-source /tmp/private-key-application.pem \
          --code-signature-flags runtime \
          "$f"
        done

    # https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution
    - name: Notarize binaries
      run: |-
        mkdir notarize-bin

        cd bin
        for f in *; do
          zip "../notarize-bin/$f.zip" "$f"
        done

        cd ../notarize-bin
        for f in *; do
          rcodesign notary-submit -vv \
          --max-wait-seconds ${{ env.NOTARY_WAIT_TIME }} \
          --api-key-path /tmp/app-store-connect.json \
          "$f"
        done

    - name: Archive binaries
      run: |-
        rm archives/*

        cd bin
        for f in *; do
          mv "$f" "${{ env.APP_NAME }}"
          tar -czf "../archives/$f.tar.gz" "${{ env.APP_NAME }}"
          mv "${{ env.APP_NAME }}" "$f"
        done

    # bin/<APP_NAME>-<TARGET> -> targets/<TARGET>/<APP_NAME>
    - name: Prepare binaries
      run: |-
        mkdir targets
        for f in bin/*; do
          if [[ "$f" =~ ${{ env.APP_NAME }}-(.+)$ ]]; then
            target="${BASH_REMATCH[1]}"
            mkdir "targets/$target"
            mv "$f" "targets/$target/${{ env.APP_NAME }}"
          fi
        done

    - name: Build universal binary
      run: >-
        pyoxidizer build macos_universal_binary
        --release
        --var version ${{ env.VERSION }}

    - name: Prepare universal binary
      id: binary
      run: |-
        binary=$(echo build/*/release/*/${{ env.APP_NAME }})
        chmod +x "$binary"
        echo "path=$binary" >> "$GITHUB_OUTPUT"

    - name: Build PKG
      run: >-
        python release/macos/build_pkg.py
        --binary ${{ steps.binary.outputs.path }}
        --version ${{ env.VERSION }}
        staged

    - name: Stage PKG
      id: pkg
      run: |-
        mkdir signed
        pkg_file="$(ls staged)"
        echo "path=$pkg_file" >> "$GITHUB_OUTPUT"

    - name: Sign PKG
      run: >-
        rcodesign sign -vv
        --pem-source /tmp/certificate-installer.pem
        --pem-source /tmp/private-key-installer.pem
        "staged/${{ steps.pkg.outputs.path }}"
        "signed/${{ steps.pkg.outputs.path }}"

    - name: Notarize PKG
      run: >-
        rcodesign notary-submit -vv
        --max-wait-seconds ${{ env.NOTARY_WAIT_TIME }}
        --api-key-path /tmp/app-store-connect.json
        --staple
        "signed/${{ steps.pkg.outputs.path }}"

    - name: Upload binaries
      uses: actions/upload-artifact@v4
      with:
        name: standalone-${{ runner.os }}
        path: archives/*
        if-no-files-found: error

    - name: Upload installer
      uses: actions/upload-artifact@v4
      with:
        name: installers-${{ runner.os }}
        path: signed/${{ steps.pkg.outputs.path }}
        if-no-files-found: error

  distributions-dev:
    name: Build development distributions
    if: ${{ !startsWith(github.event.ref, 'refs/tags') }}
    uses: ./.github/workflows/build-distributions.yml
    # This actually does not need the binary jobs but we want to prioritize
    # resources for the test jobs therefore this forces these later on
    needs: binaries

  distributions-release:
    name: Build release distributions
    needs:
    - python-artifacts
    - publish-pypi
    if: startsWith(github.event.ref, 'refs/tags')
    uses: ./.github/workflows/build-distributions.yml
    with:
      version: ${{ needs.python-artifacts.outputs.version }}

  publish-release:
    name: Publish distributions
    if: startsWith(github.event.ref, 'refs/tags')
    needs:
    - binaries
    - windows-packaging
    - macos-packaging
    - distributions-release
    runs-on: ubuntu-latest

    permissions:
      contents: write
      id-token: write

    steps:
    - name: Download distributions
      uses: actions/download-artifact@v4
      with:
        pattern: distribution-*
        path: distributions
        merge-multiple: true

    - name: Download binaries
      uses: actions/download-artifact@v4
      with:
        pattern: standalone-*
        path: archives
        merge-multiple: true

    - name: Download installers
      uses: actions/download-artifact@v4
      with:
        pattern: installers-*
        path: installers
        merge-multiple: true

    - name: Add assets to draft release
      uses: softprops/action-gh-release@v2
      with:
        files: |-
          archives/*
          distributions/*
          installers/*


================================================
FILE: .github/workflows/build-hatchling.yml
================================================
name: build hatchling

on:
  push:
    tags:
    - hatchling-v*

env:
  PYTHON_VERSION: "3.12"

jobs:
  build:
    name: Build wheels and source distribution
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Set up Python ${{ env.PYTHON_VERSION }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ env.PYTHON_VERSION }}

    - name: Install UV
      uses: astral-sh/setup-uv@v3

    - name: Install build dependencies
      run: uv pip install --system --upgrade build

    - name: Build source distribution
      run: python -m build backend

    - uses: actions/upload-artifact@v4
      with:
        name: artifacts
        path: backend/dist
        if-no-files-found: error

  publish:
    name: Publish release
    needs:
    - build
    runs-on: ubuntu-latest

    permissions:
      contents: write
      id-token: write

    steps:
    - uses: actions/download-artifact@v4
      with:
        name: artifacts
        path: dist

    - name: Push build artifacts to PyPI
      uses: pypa/gh-action-pypi-publish@v1.12.3
      with:
        skip-existing: true

    - name: Add assets to draft release
      uses: softprops/action-gh-release@v2
      with:
        files: dist/*


================================================
FILE: .github/workflows/cli.yml
================================================
name: CLI experience

on:
  push:
    branches:
    - master
  pull_request:
    branches:
    - master

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
  cancel-in-progress: true

env:
  STABLE_PYTHON_VERSION: '3.12'
  HYPERFINE_VERSION: '1.18.0'

jobs:
  response-time:
    name: CLI responsiveness with latest Python
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Set up Python ${{ env.STABLE_PYTHON_VERSION }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ env.STABLE_PYTHON_VERSION }}

    - name: Install UV
      uses: astral-sh/setup-uv@v3

    - name: Install hyperfine
      uses: taiki-e/install-action@v2
      with:
        tool: hyperfine@${{ env.HYPERFINE_VERSION }}

    - name: Install other tools
      run: uv pip install --system --upgrade flit poetry pipenv

    - name: Install ourself
      run: |
        uv pip install --system .

    - name: Benchmark
      run: |
        hyperfine -m 100 --warmup 10 -i pipenv
        hyperfine -m 100 --warmup 10 poetry
        hyperfine -m 100 --warmup 10 -i flit
        hyperfine -m 100 --warmup 10 hatch


================================================
FILE: .github/workflows/docs-dev.yml
================================================
name: dev docs

on:
  push:
    branches:
    - master
  pull_request:
    branches:
    - master

concurrency:
  group: docs-deploy

env:
  FORCE_COLOR: "1"

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4
      with:
        # Fetch all history for applying timestamps to every page
        fetch-depth: 0

    - name: Set up Python
      uses: actions/setup-python@v5
      with:
        python-version: '3.11'

    - name: Validate history
      run: python scripts/validate_history.py

    - name: Install UV
      uses: astral-sh/setup-uv@v3

    - name: Install ourself
      run: |
        uv pip install --system -e .
        hatch env create

    - name: Configure Git for GitHub Actions bot
      run: |
        git config --local user.name 'github-actions[bot]'
        git config --local user.email 'github-actions[bot]@users.noreply.github.com'

    - name: Build documentation
      run: hatch -v run docs:build-check
      env:
        GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        GH_TOKEN_MKDOCS_MATERIAL_INSIDERS: ${{ secrets.GH_TOKEN_MKDOCS_MATERIAL_INSIDERS }}

    - name: Commit documentation
      run: hatch -v run docs:ci-build dev
      env:
        GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        GH_TOKEN_MKDOCS_MATERIAL_INSIDERS: ${{ secrets.GH_TOKEN_MKDOCS_MATERIAL_INSIDERS }}

    - name: Create archive
      run: git archive -o site.zip gh-pages

    - uses: actions/upload-artifact@v4
      with:
        name: documentation
        path: site.zip

  publish:
    runs-on: ubuntu-latest

    if: github.event_name == 'push' && github.ref == 'refs/heads/master'
    needs:
    - build

    steps:
    - uses: actions/download-artifact@v4
      with:
        name: documentation

    - name: Unpack archive
      run: python -m zipfile -e site.zip site

    - uses: peaceiris/actions-gh-pages@v4
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        publish_dir: site
        commit_message: ${{ github.event.head_commit.message }}
        # Write .nojekyll at the root, see:
        # https://help.github.com/en/github/working-with-github-pages/about-github-pages#static-site-generators
        enable_jekyll: false
        # Only deploy if there were changes
        allow_empty_commit: false


================================================
FILE: .github/workflows/docs-release.yml
================================================
name: release docs

on:
  push:
    tags:
    - hatch-v*
  workflow_dispatch:

concurrency:
  group: docs-deploy

env:
  FORCE_COLOR: "1"

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4
      with:
        # Fetch all history for applying timestamps to every page
        fetch-depth: 0

    - name: Set up Python
      uses: actions/setup-python@v5
      with:
        python-version: '3.11'

    - name: Validate history
      run: python scripts/validate_history.py

    - name: Install UV
      uses: astral-sh/setup-uv@v3

    - name: Install ourself
      run: |
        uv pip install --system -e .
        hatch env create     

    - name: Display full version
      run: hatch version

    - name: Set the version of docs to publish
      run: python scripts/set_release_version.py

    - name: Configure Git for GitHub Actions bot
      run: |
        git config --local user.name 'github-actions[bot]'
        git config --local user.email 'github-actions[bot]@users.noreply.github.com'

    - name: Build documentation
      run: hatch run docs:build-check
      env:
        GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        GH_TOKEN_MKDOCS_MATERIAL_INSIDERS: ${{ secrets.GH_TOKEN_MKDOCS_MATERIAL_INSIDERS }}

    - name: Commit documentation
      run: hatch run docs:ci-build $HATCH_DOCS_VERSION latest
      env:
        GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        GH_TOKEN_MKDOCS_MATERIAL_INSIDERS: ${{ secrets.GH_TOKEN_MKDOCS_MATERIAL_INSIDERS }}

    - name: Create archive
      run: git archive -o site.zip gh-pages

    - uses: actions/upload-artifact@v4
      with:
        name: documentation
        path: site.zip

  publish:
    runs-on: ubuntu-latest
    needs:
    - build

    steps:
    - uses: actions/download-artifact@v4
      with:
        name: documentation

    - name: Unpack archive
      run: python -m zipfile -e site.zip site

    - uses: peaceiris/actions-gh-pages@v4
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        publish_dir: site
        commit_message: ${{ github.event.head_commit.message }}
        # Write .nojekyll at the root, see:
        # https://help.github.com/en/github/working-with-github-pages/about-github-pages#static-site-generators
        enable_jekyll: false
        # Only deploy if there were changes
        allow_empty_commit: false


================================================
FILE: .github/workflows/test.yml
================================================
name: test

on:
  push:
    branches:
    - master
  pull_request:
    branches:
    - master

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
  cancel-in-progress: true

env:
  PYTHONUNBUFFERED: "1"
  FORCE_COLOR: "1"

jobs:
  run:
    name: Python ${{ matrix.python-version }} on ${{ startsWith(matrix.os, 'macos-') && 'macOS' || startsWith(matrix.os, 'windows-') && 'Windows' || 'Linux' }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.14t"]

    steps:
    - uses: actions/checkout@v4

    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v6
      with:
        python-version: ${{ matrix.python-version }}

    - name: Install uv
      uses: astral-sh/setup-uv@v3

    - name: Install ourself
      run: |
        uv pip install --system -e .
        hatch env create

    - name: Run static analysis
      run: hatch fmt --check

    - name: Check types
      run: hatch run types:check

    - name: Run tests
      run: hatch test --python ${{ matrix.python-version }} --cover-quiet --randomize --parallel --retries 5 --retry-delay 3

    - name: Disambiguate coverage filename
      run: mv .coverage ".coverage.${{ matrix.os }}.${{ matrix.python-version }}"

    - name: Upload coverage data
      uses: actions/upload-artifact@v4
      with:
        include-hidden-files: true
        name: coverage-${{ matrix.os }}-${{ matrix.python-version }}
        path: .coverage*

  coverage:
    name: Report coverage
    runs-on: ubuntu-latest
    needs:
    - run

    steps:
    - uses: actions/checkout@v4

    - name: Install Hatch
      uses: pypa/hatch@install

    - name: Trigger build for auto-generated files
      run: hatch build --hooks-only

    - name: Download coverage data
      uses: actions/download-artifact@v4
      with:
        pattern: coverage-*
        merge-multiple: true

    - name: Combine coverage data
      run: hatch run coverage:combine

    - name: Export coverage reports
      run: |
        hatch run coverage:report-xml
        hatch run coverage:report-uncovered-html

    - name: Upload uncovered HTML report
      uses: actions/upload-artifact@v4
      with:
        name: uncovered-html-report
        path: htmlcov

    - name: Generate coverage summary
      run: hatch run coverage:generate-summary

    - name: Write coverage summary report
      if: github.event_name == 'pull_request'
      run: hatch run coverage:write-summary-report

    - name: Update coverage pull request comment
      if: github.event_name == 'pull_request' && !github.event.pull_request.head.repo.fork
      uses: marocchino/sticky-pull-request-comment@v2
      with:
        path: coverage-report.md

  downstream:
    name: Downstream builds with Python ${{ matrix.python-version }}
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]

    steps:
    - uses: actions/checkout@v4

    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python-version }}

    - name: Install tools
      run: pip install --upgrade -r backend/tests/downstream/requirements.txt

    - name: Build downstream projects
      run: python backend/tests/downstream/integrate.py

  # https://github.com/marketplace/actions/alls-green#why
  check: # This job does nothing and is only used for the branch protection
    if: always()

    needs:
    - coverage
    - downstream

    runs-on: ubuntu-latest

    steps:
    - name: Decide whether the needed jobs succeeded or failed
      uses: re-actors/alls-green@release/v1
      with:
        jobs: ${{ toJSON(needs) }}


================================================
FILE: .gitignore
================================================
# Global directories
__pycache__/

# Global files
*.py[cod]
*.dll
*.so
*.log
*.swp

# Root directories
/.benchmarks/
/.cache/
/.env/
/.idea/
/.mypy_cache/
/.pytest_cache/
/.ruff_cache/
/.vscode/
/backend/dist/
/dist/
/site/

# Root files
/.coverage*

# Auto-generated during builds
/src/hatch/_version.py


================================================
FILE: .linkcheckerrc
================================================
# https://linkchecker.github.io/linkchecker/man/linkcheckerrc.html
[filtering]
ignore=
  https://docs.astral.sh/ruff/rules/.+
  https://github.com/pypa/hatch/releases/tag/hatch-v.+

[AnchorCheck]


================================================
FILE: LICENSE.txt
================================================
MIT License

Copyright (c) 2017-present Ofek Lev <oss@ofek.dev>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================
# Hatch

<div align="center">

<img src="https://raw.githubusercontent.com/pypa/hatch/master/docs/assets/images/logo.svg" alt="Hatch logo" width="500" role="img">

| | |
| --- | --- |
| CI/CD | [![CI - Test](https://github.com/pypa/hatch/actions/workflows/test.yml/badge.svg)](https://github.com/pypa/hatch/actions/workflows/test.yml) [![CD - Build Hatch](https://github.com/pypa/hatch/actions/workflows/build-hatch.yml/badge.svg)](https://github.com/pypa/hatch/actions/workflows/build-hatch.yml) [![CD - Build Hatchling](https://github.com/pypa/hatch/actions/workflows/build-hatchling.yml/badge.svg)](https://github.com/pypa/hatch/actions/workflows/build-hatchling.yml) |
| Docs | [![Docs - Release](https://github.com/pypa/hatch/actions/workflows/docs-release.yml/badge.svg)](https://github.com/pypa/hatch/actions/workflows/docs-release.yml) [![Docs - Dev](https://github.com/pypa/hatch/actions/workflows/docs-dev.yml/badge.svg)](https://github.com/pypa/hatch/actions/workflows/docs-dev.yml) |
| Package | [![PyPI - Version](https://img.shields.io/pypi/v/hatch.svg?logo=pypi&label=PyPI&logoColor=gold)](https://pypi.org/project/hatch/) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/hatch.svg?logo=python&label=Python&logoColor=gold)](https://pypi.org/project/hatch/) [![PyPI - Installs](https://img.shields.io/pypi/dm/hatchling.svg?color=blue&label=Installs&logo=pypi&logoColor=gold)](https://pypi.org/project/hatch/) [![Release - Downloads](https://img.shields.io/github/downloads/pypa/hatch/total?label=Downloads)](https://github.com/pypa/hatch/releases) |
| Meta | [![Hatch project](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/pypa/hatch/master/docs/assets/badge/v0.json)](https://github.com/pypa/hatch) [![linting - Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) [![types - Mypy](https://img.shields.io/badge/types-Mypy-blue.svg)](https://github.com/python/mypy) [![License - MIT](https://img.shields.io/badge/license-MIT-9400d3.svg)](https://spdx.org/licenses/) [![GitHub Sponsors](https://img.shields.io/github/sponsors/ofek?logo=GitHub%20Sponsors&style=social)](https://github.com/sponsors/ofek) |

</div>

-----

Hatch is a modern, extensible Python project manager.

## Features

- Standardized [build system](https://hatch.pypa.io/latest/config/build/#build-system) with reproducible builds by default
- Robust [environment management](https://hatch.pypa.io/latest/environment/) with support for custom scripts and UV
- Configurable [Python distribution management](https://hatch.pypa.io/latest/tutorials/python/manage/)
- [Test execution](https://hatch.pypa.io/latest/tutorials/testing/overview/) with known best practices
- [Static analysis](https://hatch.pypa.io/latest/config/static-analysis/) with sane defaults
- Built-in Python [script runner](https://hatch.pypa.io/latest/how-to/run/python-scripts/)
- Easy [publishing](https://hatch.pypa.io/latest/publish/) to PyPI or other indices
- [Version](https://hatch.pypa.io/latest/version/) management
- Best practice [project generation](https://hatch.pypa.io/latest/config/project-templates/)
- Responsive [CLI](https://hatch.pypa.io/latest/cli/about/), ~2-3x [faster](https://github.com/pypa/hatch/actions/workflows/cli.yml) than equivalent tools

See the [Why Hatch?](https://hatch.pypa.io/latest/why/) page for more information.

## Documentation

The [documentation](https://hatch.pypa.io/) is made with [Material for MkDocs](https://github.com/squidfunk/mkdocs-material) and is hosted by [GitHub Pages](https://docs.github.com/en/pages).

## License

Hatch is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.


================================================
FILE: backend/LICENSE.txt
================================================
MIT License

Copyright (c) 2021-present Ofek Lev <oss@ofek.dev>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: backend/README.md
================================================
# Hatchling

<div align="center">

<img src="https://raw.githubusercontent.com/pypa/hatch/master/docs/assets/images/logo.svg" alt="Hatch logo" width="500" role="img">

| | |
| --- | --- |
| Package | [![PyPI - Version](https://img.shields.io/pypi/v/hatchling.svg?logo=pypi&label=PyPI&logoColor=gold)](https://pypi.org/project/hatchling/) [![PyPI - Downloads](https://img.shields.io/pypi/dm/hatchling.svg?color=blue&label=Downloads&logo=pypi&logoColor=gold)](https://pypi.org/project/hatchling/) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/hatchling.svg?logo=python&label=Python&logoColor=gold)](https://pypi.org/project/hatchling/) |
| Meta | [![Hatch project](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/pypa/hatch/master/docs/assets/badge/v0.json)](https://github.com/pypa/hatch) [![linting - Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) [![code style - Black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) [![types - Mypy](https://img.shields.io/badge/types-Mypy-blue.svg)](https://github.com/python/mypy) [![License - MIT](https://img.shields.io/badge/license-MIT-9400d3.svg)](https://spdx.org/licenses/) [![GitHub Sponsors](https://img.shields.io/github/sponsors/ofek?logo=GitHub%20Sponsors&style=social)](https://github.com/sponsors/ofek) |

</div>

-----

This is the extensible, standards compliant build backend used by [Hatch](https://github.com/pypa/hatch).

## Usage

The following snippet must be present in your project's `pyproject.toml` file in order to use Hatchling as your build backend:

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

Then a build frontend like [pip](https://github.com/pypa/pip), [build](https://github.com/pypa/build), or Hatch itself can build or install your project automatically:

```console
# install using pip
pip install /path/to/project

# build
python -m build /path/to/project

# build with Hatch
hatch build /path/to/project
```

## Documentation

- [Project metadata](https://hatch.pypa.io/latest/config/metadata/)
- [Dependencies](https://hatch.pypa.io/latest/config/dependency/)
- [Packaging](https://hatch.pypa.io/latest/config/build/)


================================================
FILE: backend/pyproject.toml
================================================
[build-system]
requires = []
build-backend = 'hatchling.ouroboros'
backend-path = ['src']

[project]
name = "hatchling"
dynamic = ["version"]
description = "Modern, extensible Python build backend"
readme = "README.md"
license = "MIT"
license-files = ["LICENSE.txt"]
requires-python = ">=3.10"
keywords = [
  "build",
  "hatch",
  "packaging",
]
authors = [
  { name = "Ofek Lev", email = "oss@ofek.dev" },
]
classifiers = [
  "Development Status :: 5 - Production/Stable",
  "Intended Audience :: Developers",
  "Natural Language :: English",
  "Operating System :: OS Independent",
  "Programming Language :: Python :: 3.10",
  "Programming Language :: Python :: 3.11",
  "Programming Language :: Python :: 3.12",
  "Programming Language :: Python :: 3.13",
  "Programming Language :: Python :: 3.14",
  "Programming Language :: Python :: Implementation :: CPython",
  "Programming Language :: Python :: Implementation :: PyPy",
  "Topic :: Software Development :: Build Tools",
  "Topic :: Software Development :: Libraries :: Python Modules",
]
dependencies = [
  "packaging>=24.2",
  "pathspec>=0.10.1",
  "pluggy>=1.0.0",
  "tomli>=1.2.2; python_version < '3.11'",
  "trove-classifiers",
]

[project.urls]
Homepage = "https://hatch.pypa.io/latest/"
Sponsor = "https://github.com/sponsors/ofek"
History = "https://hatch.pypa.io/dev/history/hatchling/"
Tracker = "https://github.com/pypa/hatch/issues"
Source = "https://github.com/pypa/hatch/tree/master/backend"

[project.scripts]
hatchling = "hatchling.cli:hatchling"

[tool.hatch.version]
path = "src/hatchling/__about__.py"


================================================
FILE: backend/src/hatchling/__about__.py
================================================
__version__ = "1.29.0"


================================================
FILE: backend/src/hatchling/__init__.py
================================================


================================================
FILE: backend/src/hatchling/__main__.py
================================================
import sys

if __name__ == "__main__":
    from hatchling.cli import hatchling

    sys.exit(hatchling())


================================================
FILE: backend/src/hatchling/bridge/__init__.py
================================================


================================================
FILE: backend/src/hatchling/bridge/app.py
================================================
from __future__ import annotations

import os
import sys
from typing import Any


class Application:
    """
    The way output is displayed can be [configured](../config/hatch.md#terminal) by users.

    !!! important
        Never import this directly; Hatch judiciously decides if a type of plugin requires
        the capabilities herein and will grant access via an attribute.
    """

    def __init__(self) -> None:
        self.__verbosity = int(os.environ.get("HATCH_VERBOSE", "0")) - int(os.environ.get("HATCH_QUIET", "0"))

    @property
    def verbosity(self) -> int:
        """
        The verbosity level of the application, with 0 as the default.
        """
        return self.__verbosity

    @staticmethod
    def display(message: str = "", **kwargs: Any) -> None:  # noqa: ARG004
        # Do not document
        _display(message, always=True)

    def display_info(self, message: str = "", **kwargs: Any) -> None:  # noqa: ARG002
        """
        Meant to be used for messages conveying basic information.
        """
        if self.__verbosity >= 0:
            _display(message)

    def display_waiting(self, message: str = "", **kwargs: Any) -> None:  # noqa: ARG002
        """
        Meant to be used for messages shown before potentially time consuming operations.
        """
        if self.__verbosity >= 0:
            _display(message)

    def display_success(self, message: str = "", **kwargs: Any) -> None:  # noqa: ARG002
        """
        Meant to be used for messages indicating some positive outcome.
        """
        if self.__verbosity >= 0:
            _display(message)

    def display_warning(self, message: str = "", **kwargs: Any) -> None:  # noqa: ARG002
        """
        Meant to be used for messages conveying important information.
        """
        if self.__verbosity >= -1:
            _display(message)

    def display_error(self, message: str = "", **kwargs: Any) -> None:  # noqa: ARG002
        """
        Meant to be used for messages indicating some unrecoverable error.
        """
        if self.__verbosity >= -2:  # noqa: PLR2004
            _display(message)

    def display_debug(self, message: str = "", level: int = 1, **kwargs: Any) -> None:  # noqa: ARG002
        """
        Meant to be used for messages that are not useful for most user experiences.
        The `level` option must be between 1 and 3 (inclusive).
        """
        if not 1 <= level <= 3:  # noqa: PLR2004
            error_message = "Debug output can only have verbosity levels between 1 and 3 (inclusive)"
            raise ValueError(error_message)

        if self.__verbosity >= level:
            _display(message)

    def display_mini_header(self, message: str = "", **kwargs: Any) -> None:  # noqa: ARG002
        if self.__verbosity >= 0:
            _display(f"[{message}]")

    def abort(self, message: str = "", code: int = 1, **kwargs: Any) -> None:  # noqa: ARG002
        """
        Terminate the program with the given return code.
        """
        if message and self.__verbosity >= -2:  # noqa: PLR2004
            _display(message)

        sys.exit(code)

    def get_safe_application(self) -> SafeApplication:
        return SafeApplication(self)


class SafeApplication:
    def __init__(self, app: Application) -> None:
        self.abort = app.abort
        self.verbosity = app.verbosity
        self.display = app.display
        self.display_info = app.display_info
        self.display_error = app.display_error
        self.display_success = app.display_success
        self.display_waiting = app.display_waiting
        self.display_warning = app.display_warning
        self.display_debug = app.display_debug
        self.display_mini_header = app.display_mini_header


def _display(message: str, *, always: bool = False) -> None:
    print(message, file=None if always else sys.stderr)


================================================
FILE: backend/src/hatchling/build.py
================================================
from __future__ import annotations

import os
from typing import Any

__all__ = [
    "build_editable",
    "build_sdist",
    "build_wheel",
    "get_requires_for_build_editable",
    "get_requires_for_build_sdist",
    "get_requires_for_build_wheel",
]
__all__ += ["__all__"]


def get_requires_for_build_sdist(config_settings: dict[str, Any] | None = None) -> list[str]:  # noqa: ARG001
    """
    https://peps.python.org/pep-0517/#get-requires-for-build-sdist
    """
    from hatchling.builders.sdist import SdistBuilder

    builder = SdistBuilder(os.getcwd())
    return builder.config.dependencies


def build_sdist(sdist_directory: str, config_settings: dict[str, Any] | None = None) -> str:  # noqa: ARG001
    """
    https://peps.python.org/pep-0517/#build-sdist
    """
    from hatchling.builders.sdist import SdistBuilder

    builder = SdistBuilder(os.getcwd())
    return os.path.basename(next(builder.build(directory=sdist_directory, versions=["standard"])))


def get_requires_for_build_wheel(config_settings: dict[str, Any] | None = None) -> list[str]:  # noqa: ARG001
    """
    https://peps.python.org/pep-0517/#get-requires-for-build-wheel
    """
    from hatchling.builders.wheel import WheelBuilder

    builder = WheelBuilder(os.getcwd())
    return builder.config.dependencies


def build_wheel(
    wheel_directory: str,
    config_settings: dict[str, Any] | None = None,  # noqa: ARG001
    metadata_directory: str | None = None,  # noqa: ARG001
) -> str:
    """
    https://peps.python.org/pep-0517/#build-wheel
    """
    from hatchling.builders.wheel import WheelBuilder

    builder = WheelBuilder(os.getcwd())
    return os.path.basename(next(builder.build(directory=wheel_directory, versions=["standard"])))


def get_requires_for_build_editable(config_settings: dict[str, Any] | None = None) -> list[str]:  # noqa: ARG001
    """
    https://peps.python.org/pep-0660/#get-requires-for-build-editable
    """
    from hatchling.builders.constants import EDITABLES_REQUIREMENT
    from hatchling.builders.wheel import WheelBuilder

    builder = WheelBuilder(os.getcwd())
    return [*builder.config.dependencies, EDITABLES_REQUIREMENT]


def build_editable(
    wheel_directory: str,
    config_settings: dict[str, Any] | None = None,  # noqa: ARG001
    metadata_directory: str | None = None,  # noqa: ARG001
) -> str:
    """
    https://peps.python.org/pep-0660/#build-editable
    """
    from hatchling.builders.wheel import WheelBuilder

    builder = WheelBuilder(os.getcwd())
    return os.path.basename(next(builder.build(directory=wheel_directory, versions=["editable"])))


# Any builder that has build-time hooks like Hatchling and setuptools cannot technically keep PEP 517's identical
# metadata promise e.g. C extensions would require different tags in the `WHEEL` file. Therefore, we consider the
# methods as mostly being for non-frontend tools like tox and dependency updaters. So Hatchling only writes the
# `METADATA` file to the metadata directory and continues to ignore that directory itself.
#
# An issue we encounter by supporting this metadata-only access is that for installations with pip the required
# dependencies of the project are read at this stage. This means that build hooks that add to the `dependencies`
# build data or modify the built wheel have no effect on what dependencies are or are not installed.
#
# There are legitimate use cases in which this is required, so we only define these when no pip build is detected.
# See: https://github.com/pypa/pip/blob/22.2.2/src/pip/_internal/operations/build/build_tracker.py#L41-L51
# Example use case: https://github.com/pypa/hatch/issues/532
if "PIP_BUILD_TRACKER" not in os.environ:
    __all__ += ["prepare_metadata_for_build_editable", "prepare_metadata_for_build_wheel"]

    def prepare_metadata_for_build_wheel(
        metadata_directory: str,
        config_settings: dict[str, Any] | None = None,  # noqa: ARG001
    ) -> str:
        """
        https://peps.python.org/pep-0517/#prepare-metadata-for-build-wheel
        """
        from hatchling.builders.wheel import WheelBuilder

        builder = WheelBuilder(os.getcwd())

        directory = os.path.join(metadata_directory, f"{builder.artifact_project_id}.dist-info")
        if not os.path.isdir(directory):
            os.mkdir(directory)

        with open(os.path.join(directory, "METADATA"), "w", encoding="utf-8") as f:
            f.write(builder.config.core_metadata_constructor(builder.metadata))

        return os.path.basename(directory)

    def prepare_metadata_for_build_editable(
        metadata_directory: str,
        config_settings: dict[str, Any] | None = None,  # noqa: ARG001
    ) -> str:
        """
        https://peps.python.org/pep-0660/#prepare-metadata-for-build-editable
        """
        from hatchling.builders.constants import EDITABLES_REQUIREMENT
        from hatchling.builders.wheel import WheelBuilder

        builder = WheelBuilder(os.getcwd())

        directory = os.path.join(metadata_directory, f"{builder.artifact_project_id}.dist-info")
        if not os.path.isdir(directory):
            os.mkdir(directory)

        extra_dependencies = []
        if not builder.config.dev_mode_dirs and builder.config.dev_mode_exact:
            extra_dependencies.append(EDITABLES_REQUIREMENT)

        with open(os.path.join(directory, "METADATA"), "w", encoding="utf-8") as f:
            f.write(builder.config.core_metadata_constructor(builder.metadata, extra_dependencies=extra_dependencies))

        return os.path.basename(directory)


================================================
FILE: backend/src/hatchling/builders/__init__.py
================================================


================================================
FILE: backend/src/hatchling/builders/app.py
================================================
from __future__ import annotations

from typing import Any

from hatchling.builders.binary import BinaryBuilder


class AppBuilder(BinaryBuilder):
    PLUGIN_NAME = "app"

    def build_bootstrap(
        self,
        directory: str,
        **build_data: Any,
    ) -> str:
        self.app.display_warning(
            "The `app` build target is deprecated and will be removed in a future release. "
            "Use the `binary` build target instead."
        )
        return super().build_bootstrap(directory, **build_data)


================================================
FILE: backend/src/hatchling/builders/binary.py
================================================
from __future__ import annotations

import os
import sys
from typing import TYPE_CHECKING, Any

from hatchling.builders.config import BuilderConfig
from hatchling.builders.plugin.interface import BuilderInterface

if TYPE_CHECKING:
    from collections.abc import Callable


class BinaryBuilderConfig(BuilderConfig):
    SUPPORTED_VERSIONS = ("3.12", "3.11", "3.10", "3.9", "3.8", "3.7")

    def __init__(self, *args: Any, **kwargs: Any) -> None:
        super().__init__(*args, **kwargs)

        self.__scripts: list[str] | None = None
        self.__python_version: str | None = None
        self.__pyapp_version: str | None = None

    @property
    def scripts(self) -> list[str]:
        if self.__scripts is None:
            known_scripts = self.builder.metadata.core.scripts
            scripts = self.target_config.get("scripts", [])

            if not isinstance(scripts, list):
                message = f"Field `tool.hatch.build.targets.{self.plugin_name}.scripts` must be an array"
                raise TypeError(message)

            for i, script in enumerate(scripts, 1):
                if not isinstance(script, str):
                    message = (
                        f"Script #{i} of field `tool.hatch.build.targets.{self.plugin_name}.scripts` must be a string"
                    )
                    raise TypeError(message)

                if script not in known_scripts:
                    message = f"Unknown script in field `tool.hatch.build.targets.{self.plugin_name}.scripts`: {script}"
                    raise ValueError(message)

            self.__scripts = sorted(set(scripts)) if scripts else list(known_scripts)

        return self.__scripts

    @property
    def python_version(self) -> str:
        if self.__python_version is None:
            python_version = self.target_config.get("python-version", "")

            if not isinstance(python_version, str):
                message = f"Field `tool.hatch.build.targets.{self.plugin_name}.python-version` must be a string"
                raise TypeError(message)

            if not python_version and "PYAPP_DISTRIBUTION_SOURCE" not in os.environ:
                for supported_version in self.SUPPORTED_VERSIONS:
                    if self.builder.metadata.core.python_constraint.contains(supported_version):
                        python_version = supported_version
                        break
                else:
                    message = "Field `project.requires-python` is incompatible with the known distributions"
                    raise ValueError(message)

            self.__python_version = python_version

        return self.__python_version

    @property
    def pyapp_version(self) -> str:
        if self.__pyapp_version is None:
            pyapp_version = self.target_config.get("pyapp-version", "")

            if not isinstance(pyapp_version, str):
                message = f"Field `tool.hatch.build.targets.{self.plugin_name}.pyapp-version` must be a string"
                raise TypeError(message)

            self.__pyapp_version = pyapp_version

        return self.__pyapp_version


class BinaryBuilder(BuilderInterface):
    """
    Build binaries
    """

    PLUGIN_NAME = "binary"

    def get_version_api(self) -> dict[str, Callable]:
        return {"bootstrap": self.build_bootstrap}

    def get_default_versions(self) -> list[str]:  # noqa: PLR6301
        return ["bootstrap"]

    def clean(
        self,
        directory: str,
        versions: list[str],  # noqa: ARG002
    ) -> None:
        import shutil

        app_dir = os.path.join(directory, self.PLUGIN_NAME)
        if os.path.isdir(app_dir):
            shutil.rmtree(app_dir)

    def build_bootstrap(
        self,
        directory: str,
        **build_data: Any,  # noqa: ARG002
    ) -> str:
        import shutil
        import tempfile

        cargo_path = os.environ.get("CARGO", "")
        if not cargo_path:
            if not shutil.which("cargo"):
                message = "Executable `cargo` could not be found on PATH"
                raise OSError(message)

            cargo_path = "cargo"

        app_dir = os.path.join(directory, self.PLUGIN_NAME)
        if not os.path.isdir(app_dir):
            os.makedirs(app_dir)

        on_windows = sys.platform == "win32"
        base_env = dict(os.environ)
        base_env["PYAPP_PROJECT_NAME"] = self.metadata.name
        base_env["PYAPP_PROJECT_VERSION"] = self.metadata.version

        if self.config.python_version:
            base_env["PYAPP_PYTHON_VERSION"] = self.config.python_version

        # https://doc.rust-lang.org/cargo/reference/config.html#buildtarget
        build_target = os.environ.get("CARGO_BUILD_TARGET", "")

        # This will determine whether we install from crates.io or build locally and is currently required for
        # cross compilation: https://github.com/cross-rs/cross/issues/1215
        repo_path = os.environ.get("PYAPP_REPO", "")

        with tempfile.TemporaryDirectory() as temp_dir:
            exe_name = "pyapp.exe" if on_windows else "pyapp"
            if repo_path:
                context_dir = repo_path
                target_dir = os.path.join(temp_dir, "build")
                if build_target:
                    temp_exe_path = os.path.join(target_dir, build_target, "release", exe_name)
                else:
                    temp_exe_path = os.path.join(target_dir, "release", exe_name)
                install_command = [cargo_path, "build", "--release", "--target-dir", target_dir]
            else:
                context_dir = temp_dir
                temp_exe_path = os.path.join(temp_dir, "bin", exe_name)
                install_command = [cargo_path, "install", "pyapp", "--force", "--root", temp_dir]
                if self.config.pyapp_version:
                    install_command.extend(["--version", self.config.pyapp_version])

            if self.config.scripts:
                for script in self.config.scripts:
                    env = dict(base_env)
                    env["PYAPP_EXEC_SPEC"] = self.metadata.core.scripts[script]

                    self.cargo_build(install_command, cwd=context_dir, env=env)

                    exe_stem = (
                        f"{script}-{self.metadata.version}-{build_target}"
                        if build_target
                        else f"{script}-{self.metadata.version}"
                    )
                    exe_path = os.path.join(app_dir, f"{exe_stem}.exe" if on_windows else exe_stem)
                    shutil.move(temp_exe_path, exe_path)
            else:
                self.cargo_build(install_command, cwd=context_dir, env=base_env)

                exe_stem = (
                    f"{self.metadata.name}-{self.metadata.version}-{build_target}"
                    if build_target
                    else f"{self.metadata.name}-{self.metadata.version}"
                )
                exe_path = os.path.join(app_dir, f"{exe_stem}.exe" if on_windows else exe_stem)
                shutil.move(temp_exe_path, exe_path)

        return app_dir

    def cargo_build(self, *args: Any, **kwargs: Any) -> None:
        import subprocess

        if self.app.verbosity < 0:
            kwargs["stdout"] = subprocess.PIPE
            kwargs["stderr"] = subprocess.STDOUT

        process = subprocess.run(*args, **kwargs)  # noqa: PLW1510
        if process.returncode:
            message = f"Compilation failed (code {process.returncode})"
            raise OSError(message)

    @classmethod
    def get_config_class(cls) -> type[BinaryBuilderConfig]:
        return BinaryBuilderConfig


================================================
FILE: backend/src/hatchling/builders/config.py
================================================
from __future__ import annotations

import os
from contextlib import contextmanager
from functools import cached_property
from typing import TYPE_CHECKING, Any, TypeVar

import pathspec

from hatchling.builders.constants import DEFAULT_BUILD_DIRECTORY, EXCLUDED_DIRECTORIES, BuildEnvVars
from hatchling.builders.utils import normalize_inclusion_map, normalize_relative_directory, normalize_relative_path
from hatchling.metadata.utils import normalize_project_name
from hatchling.utils.fs import locate_file

if TYPE_CHECKING:
    from collections.abc import Generator

    from hatchling.builders.plugin.interface import BuilderInterface


class BuilderConfig:
    def __init__(
        self,
        builder: BuilderInterface,
        root: str,
        plugin_name: str,
        build_config: dict[str, Any],
        target_config: dict[str, Any],
    ) -> None:
        self.__builder = builder
        self.__root = root
        self.__plugin_name = plugin_name
        self.__build_config = build_config
        self.__target_config = target_config

        # This is used when the only file selection is based on forced inclusion or build-time artifacts. This
        # instructs to `exclude` every encountered path without doing pattern matching that matches everything.
        self.__exclude_all: bool = False

        # Modified at build time
        self.build_artifact_spec: pathspec.GitIgnoreSpec | None = None
        self.build_force_include: dict[str, str] = {}
        self.build_reserved_paths: set[str] = set()

    @property
    def builder(self) -> BuilderInterface:
        return self.__builder

    @property
    def root(self) -> str:
        return self.__root

    @property
    def plugin_name(self) -> str:
        return self.__plugin_name

    @property
    def build_config(self) -> dict[str, Any]:
        return self.__build_config

    @property
    def target_config(self) -> dict[str, Any]:
        return self.__target_config

    def include_path(self, relative_path: str, *, explicit: bool = False, is_package: bool = True) -> bool:
        return (
            self.path_is_build_artifact(relative_path)
            or self.path_is_artifact(relative_path)
            or (
                not (self.only_packages and not is_package)
                and not self.path_is_excluded(relative_path)
                and (explicit or self.path_is_included(relative_path))
            )
        )

    def path_is_included(self, relative_path: str) -> bool:
        if self.include_spec is None:
            return True

        return self.include_spec.match_file(relative_path)

    def path_is_excluded(self, relative_path: str) -> bool:
        if self.__exclude_all:
            return True

        if self.exclude_spec is None:
            return False

        return self.exclude_spec.match_file(relative_path)

    def path_is_artifact(self, relative_path: str) -> bool:
        if self.artifact_spec is None:
            return False

        return self.artifact_spec.match_file(relative_path)

    def path_is_build_artifact(self, relative_path: str) -> bool:
        if self.build_artifact_spec is None:
            return False

        return self.build_artifact_spec.match_file(relative_path)

    def path_is_reserved(self, relative_path: str) -> bool:
        return relative_path in self.build_reserved_paths

    def directory_is_excluded(self, name: str, relative_path: str) -> bool:
        if name in EXCLUDED_DIRECTORIES:
            return True

        relative_directory = os.path.join(relative_path, name)
        return (
            self.path_is_reserved(relative_directory)
            # The trailing slash is necessary so e.g. `bar/` matches `foo/bar`
            or (self.skip_excluded_dirs and self.path_is_excluded(f"{relative_directory}/"))
        )

    @cached_property
    def include_spec(self) -> pathspec.GitIgnoreSpec | None:
        if "include" in self.target_config:
            include_config = self.target_config
            include_location = f"tool.hatch.build.targets.{self.plugin_name}.include"
        else:
            include_config = self.build_config
            include_location = "tool.hatch.build.include"

        all_include_patterns = []

        include_patterns = include_config.get("include", self.default_include())
        if not isinstance(include_patterns, list):
            message = f"Field `{include_location}` must be an array of strings"
            raise TypeError(message)

        for i, include_pattern in enumerate(include_patterns, 1):
            if not isinstance(include_pattern, str):
                message = f"Pattern #{i} in field `{include_location}` must be a string"
                raise TypeError(message)

            if not include_pattern:
                message = f"Pattern #{i} in field `{include_location}` cannot be an empty string"
                raise ValueError(message)

            all_include_patterns.append(include_pattern)

        # Matching only at the root requires a forward slash, back slashes do not work. As such,
        # normalize to forward slashes for consistency.
        all_include_patterns.extend(f"/{relative_path.replace(os.sep, '/')}/" for relative_path in self.packages)

        if all_include_patterns:
            return pathspec.GitIgnoreSpec.from_lines(all_include_patterns)
        return None

    @cached_property
    def exclude_spec(self) -> pathspec.GitIgnoreSpec | None:
        if "exclude" in self.target_config:
            exclude_config = self.target_config
            exclude_location = f"tool.hatch.build.targets.{self.plugin_name}.exclude"
        else:
            exclude_config = self.build_config
            exclude_location = "tool.hatch.build.exclude"

        all_exclude_patterns = self.default_global_exclude()

        if not self.ignore_vcs:
            all_exclude_patterns.extend(self.load_vcs_exclusion_patterns())

        exclude_patterns = exclude_config.get("exclude", self.default_exclude())
        if not isinstance(exclude_patterns, list):
            message = f"Field `{exclude_location}` must be an array of strings"
            raise TypeError(message)

        for i, exclude_pattern in enumerate(exclude_patterns, 1):
            if not isinstance(exclude_pattern, str):
                message = f"Pattern #{i} in field `{exclude_location}` must be a string"
                raise TypeError(message)

            if not exclude_pattern:
                message = f"Pattern #{i} in field `{exclude_location}` cannot be an empty string"
                raise ValueError(message)

            all_exclude_patterns.append(exclude_pattern)

        if all_exclude_patterns:
            return pathspec.GitIgnoreSpec.from_lines(all_exclude_patterns)
        return None

    @property
    def artifact_spec(self) -> pathspec.GitIgnoreSpec | None:
        if "artifacts" in self.target_config:
            artifact_config = self.target_config
            artifact_location = f"tool.hatch.build.targets.{self.plugin_name}.artifacts"
        else:
            artifact_config = self.build_config
            artifact_location = "tool.hatch.build.artifacts"

        all_artifact_patterns = []

        artifact_patterns = artifact_config.get("artifacts", [])
        if not isinstance(artifact_patterns, list):
            message = f"Field `{artifact_location}` must be an array of strings"
            raise TypeError(message)

        for i, artifact_pattern in enumerate(artifact_patterns, 1):
            if not isinstance(artifact_pattern, str):
                message = f"Pattern #{i} in field `{artifact_location}` must be a string"
                raise TypeError(message)

            if not artifact_pattern:
                message = f"Pattern #{i} in field `{artifact_location}` cannot be an empty string"
                raise ValueError(message)

            all_artifact_patterns.append(artifact_pattern)

        if all_artifact_patterns:
            return pathspec.GitIgnoreSpec.from_lines(all_artifact_patterns)
        return None

    @cached_property
    def hook_config(self) -> dict[str, Any]:
        hook_config: dict[str, dict[str, Any]] = {}

        global_hook_config = self.build_config.get("hooks", {})
        if not isinstance(global_hook_config, dict):
            message = "Field `tool.hatch.build.hooks` must be a table"
            raise TypeError(message)

        for hook_name, config in global_hook_config.items():
            if not isinstance(config, dict):
                message = f"Field `tool.hatch.build.hooks.{hook_name}` must be a table"
                raise TypeError(message)

            hook_config.setdefault(hook_name, config)

        target_hook_config = self.target_config.get("hooks", {})
        if not isinstance(target_hook_config, dict):
            message = f"Field `tool.hatch.build.targets.{self.plugin_name}.hooks` must be a table"
            raise TypeError(message)

        for hook_name, config in target_hook_config.items():
            if not isinstance(config, dict):
                message = f"Field `tool.hatch.build.targets.{self.plugin_name}.hooks.{hook_name}` must be a table"
                raise TypeError(message)

            hook_config[hook_name] = config

        if not env_var_enabled(BuildEnvVars.NO_HOOKS):
            all_hooks_enabled = env_var_enabled(BuildEnvVars.HOOKS_ENABLE)
            final_hook_config = {
                hook_name: config
                for hook_name, config in hook_config.items()
                if (
                    all_hooks_enabled
                    or config.get("enable-by-default", True)
                    or env_var_enabled(f"{BuildEnvVars.HOOK_ENABLE_PREFIX}{hook_name.upper()}")
                )
            }
        else:
            final_hook_config = {}

        return final_hook_config

    @cached_property
    def directory(self) -> str:
        if "directory" in self.target_config:
            directory = self.target_config["directory"]
            if not isinstance(directory, str):
                message = f"Field `tool.hatch.build.targets.{self.plugin_name}.directory` must be a string"
                raise TypeError(message)
        else:
            directory = self.build_config.get("directory", DEFAULT_BUILD_DIRECTORY)
            if not isinstance(directory, str):
                message = "Field `tool.hatch.build.directory` must be a string"
                raise TypeError(message)

        return self.normalize_build_directory(directory)

    @cached_property
    def skip_excluded_dirs(self) -> bool:
        if "skip-excluded-dirs" in self.target_config:
            skip_excluded_dirs = self.target_config["skip-excluded-dirs"]
            if not isinstance(skip_excluded_dirs, bool):
                message = f"Field `tool.hatch.build.targets.{self.plugin_name}.skip-excluded-dirs` must be a boolean"
                raise TypeError(message)
        else:
            skip_excluded_dirs = self.build_config.get("skip-excluded-dirs", False)
            if not isinstance(skip_excluded_dirs, bool):
                message = "Field `tool.hatch.build.skip-excluded-dirs` must be a boolean"
                raise TypeError(message)

        return skip_excluded_dirs

    @cached_property
    def ignore_vcs(self) -> bool:
        if "ignore-vcs" in self.target_config:
            ignore_vcs = self.target_config["ignore-vcs"]
            if not isinstance(ignore_vcs, bool):
                message = f"Field `tool.hatch.build.targets.{self.plugin_name}.ignore-vcs` must be a boolean"
                raise TypeError(message)
        else:
            ignore_vcs = self.build_config.get("ignore-vcs", False)
            if not isinstance(ignore_vcs, bool):
                message = "Field `tool.hatch.build.ignore-vcs` must be a boolean"
                raise TypeError(message)

        return ignore_vcs

    @cached_property
    def require_runtime_dependencies(self) -> bool:
        if "require-runtime-dependencies" in self.target_config:
            require_runtime_dependencies = self.target_config["require-runtime-dependencies"]
            if not isinstance(require_runtime_dependencies, bool):
                message = (
                    f"Field `tool.hatch.build.targets.{self.plugin_name}.require-runtime-dependencies` "
                    f"must be a boolean"
                )
                raise TypeError(message)
        else:
            require_runtime_dependencies = self.build_config.get("require-runtime-dependencies", False)
            if not isinstance(require_runtime_dependencies, bool):
                message = "Field `tool.hatch.build.require-runtime-dependencies` must be a boolean"
                raise TypeError(message)

        return require_runtime_dependencies

    @cached_property
    def require_runtime_features(self) -> list[str]:
        if "require-runtime-features" in self.target_config:
            features_config = self.target_config
            features_location = f"tool.hatch.build.targets.{self.plugin_name}.require-runtime-features"
        else:
            features_config = self.build_config
            features_location = "tool.hatch.build.require-runtime-features"

        require_runtime_features = features_config.get("require-runtime-features", [])
        if not isinstance(require_runtime_features, list):
            message = f"Field `{features_location}` must be an array"
            raise TypeError(message)

        all_features: dict[str, None] = {}
        for i, raw_feature in enumerate(require_runtime_features, 1):
            if not isinstance(raw_feature, str):
                message = f"Feature #{i} of field `{features_location}` must be a string"
                raise TypeError(message)

            if not raw_feature:
                message = f"Feature #{i} of field `{features_location}` cannot be an empty string"
                raise ValueError(message)

            feature = normalize_project_name(raw_feature)
            if feature not in self.builder.metadata.core.optional_dependencies:
                message = (
                    f"Feature `{feature}` of field `{features_location}` is not defined in "
                    f"field `project.optional-dependencies`"
                )
                raise ValueError(message)

            all_features[feature] = None

        return list(all_features)

    @cached_property
    def only_packages(self) -> bool:
        """
        Whether or not the target should ignore non-artifact files that do not reside within a Python package.
        """
        if "only-packages" in self.target_config:
            only_packages = self.target_config["only-packages"]
            if not isinstance(only_packages, bool):
                message = f"Field `tool.hatch.build.targets.{self.plugin_name}.only-packages` must be a boolean"
                raise TypeError(message)
        else:
            only_packages = self.build_config.get("only-packages", False)
            if not isinstance(only_packages, bool):
                message = "Field `tool.hatch.build.only-packages` must be a boolean"
                raise TypeError(message)

        return only_packages

    @cached_property
    def reproducible(self) -> bool:
        """
        Whether or not the target should be built in a reproducible manner, defaulting to true.
        """
        if "reproducible" in self.target_config:
            reproducible = self.target_config["reproducible"]
            if not isinstance(reproducible, bool):
                message = f"Field `tool.hatch.build.targets.{self.plugin_name}.reproducible` must be a boolean"
                raise TypeError(message)
        else:
            reproducible = self.build_config.get("reproducible", True)
            if not isinstance(reproducible, bool):
                message = "Field `tool.hatch.build.reproducible` must be a boolean"
                raise TypeError(message)

        return reproducible

    @cached_property
    def dev_mode_dirs(self) -> list[str]:
        """
        Directories which must be added to Python's search path in
        [dev mode](../config/environment/overview.md#dev-mode).
        """
        if "dev-mode-dirs" in self.target_config:
            dev_mode_dirs_config = self.target_config
            dev_mode_dirs_location = f"tool.hatch.build.targets.{self.plugin_name}.dev-mode-dirs"
        else:
            dev_mode_dirs_config = self.build_config
            dev_mode_dirs_location = "tool.hatch.build.dev-mode-dirs"

        all_dev_mode_dirs = []

        dev_mode_dirs = dev_mode_dirs_config.get("dev-mode-dirs", [])
        if not isinstance(dev_mode_dirs, list):
            message = f"Field `{dev_mode_dirs_location}` must be an array of strings"
            raise TypeError(message)

        for i, dev_mode_dir in enumerate(dev_mode_dirs, 1):
            if not isinstance(dev_mode_dir, str):
                message = f"Directory #{i} in field `{dev_mode_dirs_location}` must be a string"
                raise TypeError(message)

            if not dev_mode_dir:
                message = f"Directory #{i} in field `{dev_mode_dirs_location}` cannot be an empty string"
                raise ValueError(message)

            all_dev_mode_dirs.append(dev_mode_dir)

        return all_dev_mode_dirs

    @cached_property
    def dev_mode_exact(self) -> bool:
        if "dev-mode-exact" in self.target_config:
            dev_mode_exact = self.target_config["dev-mode-exact"]
            if not isinstance(dev_mode_exact, bool):
                message = f"Field `tool.hatch.build.targets.{self.plugin_name}.dev-mode-exact` must be a boolean"
                raise TypeError(message)
        else:
            dev_mode_exact = self.build_config.get("dev-mode-exact", False)
            if not isinstance(dev_mode_exact, bool):
                message = "Field `tool.hatch.build.dev-mode-exact` must be a boolean"
                raise TypeError(message)

        return dev_mode_exact

    @cached_property
    def versions(self) -> list[str]:
        # Used as an ordered set
        all_versions: dict[str, None] = {}

        versions = self.target_config.get("versions", [])
        if not isinstance(versions, list):
            message = f"Field `tool.hatch.build.targets.{self.plugin_name}.versions` must be an array of strings"
            raise TypeError(message)

        for i, version in enumerate(versions, 1):
            if not isinstance(version, str):
                message = (
                    f"Version #{i} in field `tool.hatch.build.targets.{self.plugin_name}.versions` must be a string"
                )
                raise TypeError(message)

            if not version:
                message = (
                    f"Version #{i} in field `tool.hatch.build.targets.{self.plugin_name}.versions` "
                    f"cannot be an empty string"
                )
                raise ValueError(message)

            all_versions[version] = None

        if not all_versions:
            default_versions = self.__builder.get_default_versions()
            for version in default_versions:
                all_versions[version] = None
        else:
            unknown_versions = set(all_versions) - set(self.__builder.get_version_api())
            if unknown_versions:
                message = (
                    f"Unknown versions in field `tool.hatch.build.targets.{self.plugin_name}.versions`: "
                    f"{', '.join(map(str, sorted(unknown_versions)))}"
                )
                raise ValueError(message)

        return list(all_versions)

    @cached_property
    def dependencies(self) -> list[str]:
        # Used as an ordered set
        dependencies: dict[str, None] = {}

        target_dependencies = self.target_config.get("dependencies", [])
        if not isinstance(target_dependencies, list):
            message = f"Field `tool.hatch.build.targets.{self.plugin_name}.dependencies` must be an array"
            raise TypeError(message)

        for i, dependency in enumerate(target_dependencies, 1):
            if not isinstance(dependency, str):
                message = (
                    f"Dependency #{i} of field `tool.hatch.build.targets.{self.plugin_name}.dependencies` "
                    f"must be a string"
                )
                raise TypeError(message)

            dependencies[dependency] = None

        global_dependencies = self.build_config.get("dependencies", [])
        if not isinstance(global_dependencies, list):
            message = "Field `tool.hatch.build.dependencies` must be an array"
            raise TypeError(message)

        for i, dependency in enumerate(global_dependencies, 1):
            if not isinstance(dependency, str):
                message = f"Dependency #{i} of field `tool.hatch.build.dependencies` must be a string"
                raise TypeError(message)

            dependencies[dependency] = None

        require_runtime_dependencies = self.require_runtime_dependencies
        require_runtime_features = dict.fromkeys(self.require_runtime_features)
        for hook_name, config in self.hook_config.items():
            hook_require_runtime_dependencies = config.get("require-runtime-dependencies", False)
            if not isinstance(hook_require_runtime_dependencies, bool):
                message = f"Option `require-runtime-dependencies` of build hook `{hook_name}` must be a boolean"
                raise TypeError(message)

            if hook_require_runtime_dependencies:
                require_runtime_dependencies = True

            hook_require_runtime_features = config.get("require-runtime-features", [])
            if not isinstance(hook_require_runtime_features, list):
                message = f"Option `require-runtime-features` of build hook `{hook_name}` must be an array"
                raise TypeError(message)

            for i, raw_feature in enumerate(hook_require_runtime_features, 1):
                if not isinstance(raw_feature, str):
                    message = (
                        f"Feature #{i} of option `require-runtime-features` of build hook `{hook_name}` "
                        f"must be a string"
                    )
                    raise TypeError(message)

                if not raw_feature:
                    message = (
                        f"Feature #{i} of option `require-runtime-features` of build hook `{hook_name}` "
                        f"cannot be an empty string"
                    )
                    raise ValueError(message)

                feature = normalize_project_name(raw_feature)
                if feature not in self.builder.metadata.core.optional_dependencies:
                    message = (
                        f"Feature `{feature}` of option `require-runtime-features` of build hook `{hook_name}` "
                        f"is not defined in field `project.optional-dependencies`"
                    )
                    raise ValueError(message)

                require_runtime_features[feature] = None

            hook_dependencies = config.get("dependencies", [])
            if not isinstance(hook_dependencies, list):
                message = f"Option `dependencies` of build hook `{hook_name}` must be an array"
                raise TypeError(message)

            for i, dependency in enumerate(hook_dependencies, 1):
                if not isinstance(dependency, str):
                    message = f"Dependency #{i} of option `dependencies` of build hook `{hook_name}` must be a string"
                    raise TypeError(message)

                dependencies[dependency] = None

        if require_runtime_dependencies:
            for dependency in self.builder.metadata.core.dependencies:
                dependencies[dependency] = None

        if require_runtime_features:
            for feature in require_runtime_features:
                for dependency in self.builder.metadata.core.optional_dependencies[feature]:
                    dependencies[dependency] = None

        for dependency in self.dynamic_dependencies:
            dependencies[dependency] = None

        return list(dependencies)

    @cached_property
    def dynamic_dependencies(self) -> list[str]:
        dependencies = []
        for hook_name, config in self.hook_config.items():
            build_hook_cls = self.builder.plugin_manager.build_hook.get(hook_name)
            if build_hook_cls is None:
                continue

            # Hook exists but dynamic dependencies are not imported lazily.
            # This happens for example when using the `custom` build hook.
            try:
                build_hook = build_hook_cls(
                    self.root, config, self, self.builder.metadata, "", self.builder.PLUGIN_NAME, self.builder.app
                )
            except ImportError:
                continue

            dependencies.extend(build_hook.dependencies())

        return dependencies

    @cached_property
    def sources(self) -> dict[str, str]:
        if "sources" in self.target_config:
            sources_config = self.target_config
            sources_location = f"tool.hatch.build.targets.{self.plugin_name}.sources"
        else:
            sources_config = self.build_config
            sources_location = "tool.hatch.build.sources"

        sources = {}

        raw_sources = sources_config.get("sources", [])
        if isinstance(raw_sources, list):
            for i, source in enumerate(raw_sources, 1):
                if not isinstance(source, str):
                    message = f"Source #{i} in field `{sources_location}` must be a string"
                    raise TypeError(message)

                if not source:
                    message = f"Source #{i} in field `{sources_location}` cannot be an empty string"
                    raise ValueError(message)

                sources[normalize_relative_directory(source)] = ""
        elif isinstance(raw_sources, dict):
            for source, path in raw_sources.items():
                if not isinstance(path, str):
                    message = f"Path for source `{source}` in field `{sources_location}` must be a string"
                    raise TypeError(message)

                normalized_path = normalize_relative_path(path)
                if normalized_path == ".":
                    normalized_path = ""
                else:
                    normalized_path += os.sep

                sources[normalize_relative_directory(source) if source else source] = normalized_path
        else:
            message = f"Field `{sources_location}` must be a mapping or array of strings"
            raise TypeError(message)

        for relative_path in self.packages:
            source, _package = os.path.split(relative_path)
            if source and normalize_relative_directory(relative_path) not in sources:
                sources[normalize_relative_directory(source)] = ""

        return dict(sorted(sources.items()))

    @cached_property
    def packages(self) -> list[str]:
        if "packages" in self.target_config:
            package_config = self.target_config
            package_location = f"tool.hatch.build.targets.{self.plugin_name}.packages"
        else:
            package_config = self.build_config
            package_location = "tool.hatch.build.packages"

        packages = package_config.get("packages", self.default_packages())
        if not isinstance(packages, list):
            message = f"Field `{package_location}` must be an array of strings"
            raise TypeError(message)

        for i, package in enumerate(packages, 1):
            if not isinstance(package, str):
                message = f"Package #{i} in field `{package_location}` must be a string"
                raise TypeError(message)

            if not package:
                message = f"Package #{i} in field `{package_location}` cannot be an empty string"
                raise ValueError(message)

        return sorted(normalize_relative_path(package) for package in packages)

    @cached_property
    def force_include(self) -> dict[str, str]:
        if "force-include" in self.target_config:
            force_include_config = self.target_config
            force_include_location = f"tool.hatch.build.targets.{self.plugin_name}.force-include"
        else:
            force_include_config = self.build_config
            force_include_location = "tool.hatch.build.force-include"

        force_include = force_include_config.get("force-include", {})
        if not isinstance(force_include, dict):
            message = f"Field `{force_include_location}` must be a mapping"
            raise TypeError(message)

        for i, (source, relative_path) in enumerate(force_include.items(), 1):
            if not source:
                message = f"Source #{i} in field `{force_include_location}` cannot be an empty string"
                raise ValueError(message)

            if not isinstance(relative_path, str):
                message = f"Path for source `{source}` in field `{force_include_location}` must be a string"
                raise TypeError(message)

            if not relative_path:
                message = f"Path for source `{source}` in field `{force_include_location}` cannot be an empty string"
                raise ValueError(message)

        return normalize_inclusion_map(force_include, self.root)

    @cached_property
    def only_include(self) -> dict[str, str]:
        if "only-include" in self.target_config:
            only_include_config = self.target_config
            only_include_location = f"tool.hatch.build.targets.{self.plugin_name}.only-include"
        else:
            only_include_config = self.build_config
            only_include_location = "tool.hatch.build.only-include"

        only_include = only_include_config.get("only-include", self.default_only_include()) or self.packages
        if not isinstance(only_include, list):
            message = f"Field `{only_include_location}` must be an array"
            raise TypeError(message)

        inclusion_map = {}

        for i, relative_path in enumerate(only_include, 1):
            if not isinstance(relative_path, str):
                message = f"Path #{i} in field `{only_include_location}` must be a string"
                raise TypeError(message)

            normalized_path = normalize_relative_path(relative_path)
            if not normalized_path or normalized_path.startswith(("~", "..")):
                message = f"Path #{i} in field `{only_include_location}` must be relative: {relative_path}"
                raise ValueError(message)

            if normalized_path in inclusion_map:
                message = f"Duplicate path in field `{only_include_location}`: {normalized_path}"
                raise ValueError(message)

            inclusion_map[normalized_path] = normalized_path

        return normalize_inclusion_map(inclusion_map, self.root)

    def get_distribution_path(self, relative_path: str) -> str:
        # src/foo/bar.py -> foo/bar.py
        for source, replacement in self.sources.items():
            if not source:
                return replacement + relative_path

            if relative_path.startswith(source):
                return relative_path.replace(source, replacement, 1)

        return relative_path

    @cached_property
    def vcs_exclusion_files(self) -> dict[str, list[str]]:
        exclusion_files: dict[str, list[str]] = {"git": [], "hg": []}

        local_gitignore = locate_file(self.root, ".gitignore", boundary=".git")
        if local_gitignore is not None:
            exclusion_files["git"].append(local_gitignore)

        local_hgignore = locate_file(self.root, ".hgignore", boundary=".hg")
        if local_hgignore is not None:
            exclusion_files["hg"].append(local_hgignore)

        return exclusion_files

    def load_vcs_exclusion_patterns(self) -> list[str]:
        patterns = []

        # https://git-scm.com/docs/gitignore#_pattern_format
        for exclusion_file in self.vcs_exclusion_files["git"]:
            with open(exclusion_file, encoding="utf-8") as f:
                patterns.extend(f.readlines())

        # https://linux.die.net/man/5/hgignore
        for exclusion_file in self.vcs_exclusion_files["hg"]:
            with open(exclusion_file, encoding="utf-8") as f:
                glob_mode = False
                for line in f:
                    exact_line = line.strip()
                    if exact_line == "syntax: glob":
                        glob_mode = True
                        continue

                    if exact_line.startswith("syntax: "):
                        glob_mode = False
                        continue

                    if glob_mode:
                        patterns.append(line)

        # validate project root is not excluded by vcs
        exclude_spec = pathspec.GitIgnoreSpec.from_lines(patterns)
        if exclude_spec.match_file(self.root):
            return []

        return patterns

    def normalize_build_directory(self, build_directory: str) -> str:
        if not os.path.isabs(build_directory):
            build_directory = os.path.join(self.root, build_directory)

        return os.path.normpath(build_directory)

    def default_include(self) -> list:  # noqa: PLR6301
        return []

    def default_exclude(self) -> list:  # noqa: PLR6301
        return []

    def default_packages(self) -> list:  # noqa: PLR6301
        return []

    def default_only_include(self) -> list:  # noqa: PLR6301
        return []

    def default_global_exclude(self) -> list[str]:  # noqa: PLR6301
        patterns = ["*.py[cdo]", f"/{DEFAULT_BUILD_DIRECTORY}"]
        patterns.sort()
        return patterns

    def set_exclude_all(self) -> None:
        self.__exclude_all = True

    def get_force_include(self) -> dict[str, str]:
        force_include = self.force_include.copy()
        force_include.update(self.build_force_include)
        return force_include

    @contextmanager
    def set_build_data(self, build_data: dict[str, Any]) -> Generator:
        try:
            # Include anything the hooks indicate
            build_artifacts = build_data["artifacts"]
            if build_artifacts:
                self.build_artifact_spec = pathspec.GitIgnoreSpec.from_lines(build_artifacts)

            self.build_force_include.update(normalize_inclusion_map(build_data["force_include"], self.root))

            for inclusion_map in (self.force_include, self.build_force_include):
                for source, target in inclusion_map.items():
                    # Ignore source
                    # old/ -> new/
                    # old.ext -> new.ext
                    if source.startswith(f"{self.root}{os.sep}"):
                        self.build_reserved_paths.add(self.get_distribution_path(os.path.relpath(source, self.root)))
                    # Ignore target files only
                    # ../out.ext -> ../in.ext
                    elif os.path.isfile(source):
                        self.build_reserved_paths.add(self.get_distribution_path(target))

            yield
        finally:
            self.build_artifact_spec = None
            self.build_force_include.clear()
            self.build_reserved_paths.clear()


def env_var_enabled(env_var: str, *, default: bool = False) -> bool:
    if env_var in os.environ:
        return os.environ[env_var] in {"1", "true"}

    return default


BuilderConfigBound = TypeVar("BuilderConfigBound", bound=BuilderConfig)


================================================
FILE: backend/src/hatchling/builders/constants.py
================================================
DEFAULT_BUILD_DIRECTORY = "dist"

EXCLUDED_DIRECTORIES = frozenset((
    # Python bytecode
    "__pycache__",
    # Single virtual environment
    ".venv",
    # Git
    ".git",
    # Mercurial
    ".hg",
    # Hatch
    ".hatch",
    # tox
    ".tox",
    # nox
    ".nox",
    # Ruff
    ".ruff_cache",
    # pytest
    ".pytest_cache",
    # Mypy
    ".mypy_cache",
    # pixi
    ".pixi",
))
EXCLUDED_FILES = frozenset((
    # https://en.wikipedia.org/wiki/.DS_Store
    ".DS_Store",
))


class BuildEnvVars:
    LOCATION = "HATCH_BUILD_LOCATION"
    HOOKS_ONLY = "HATCH_BUILD_HOOKS_ONLY"
    NO_HOOKS = "HATCH_BUILD_NO_HOOKS"
    HOOKS_ENABLE = "HATCH_BUILD_HOOKS_ENABLE"
    HOOK_ENABLE_PREFIX = "HATCH_BUILD_HOOK_ENABLE_"
    CLEAN = "HATCH_BUILD_CLEAN"
    CLEAN_HOOKS_AFTER = "HATCH_BUILD_CLEAN_HOOKS_AFTER"


EDITABLES_REQUIREMENT = "editables~=0.3"


================================================
FILE: backend/src/hatchling/builders/custom.py
================================================
from __future__ import annotations

import os
from typing import TYPE_CHECKING, Any, Generic

from hatchling.builders.plugin.interface import BuilderInterface
from hatchling.metadata.core import ProjectMetadata
from hatchling.plugin.manager import PluginManagerBound
from hatchling.plugin.utils import load_plugin_from_script
from hatchling.utils.constants import DEFAULT_BUILD_SCRIPT

if TYPE_CHECKING:
    from hatchling.bridge.app import Application


class CustomBuilder(Generic[PluginManagerBound]):
    PLUGIN_NAME = "custom"

    def __new__(  # type: ignore[misc]
        cls,
        root: str,
        plugin_manager: PluginManagerBound | None = None,
        config: dict[str, Any] | None = None,
        metadata: ProjectMetadata | None = None,
        app: Application | None = None,
    ) -> BuilderInterface:
        project_metadata = ProjectMetadata(root, plugin_manager, config)

        target_config = project_metadata.hatch.build_targets.get(cls.PLUGIN_NAME, {})
        if not isinstance(target_config, dict):
            message = f"Field `tool.hatch.build.targets.{cls.PLUGIN_NAME}` must be a table"
            raise TypeError(message)

        build_script = target_config.get("path", DEFAULT_BUILD_SCRIPT)
        if not isinstance(build_script, str):
            message = f"Option `path` for builder `{cls.PLUGIN_NAME}` must be a string"
            raise TypeError(message)

        if not build_script:
            message = f"Option `path` for builder `{cls.PLUGIN_NAME}` must not be empty if defined"
            raise ValueError(message)

        path = os.path.normpath(os.path.join(root, build_script))
        if not os.path.isfile(path):
            message = f"Build script does not exist: {build_script}"
            raise OSError(message)

        hook_class = load_plugin_from_script(path, build_script, BuilderInterface, "builder")  # type: ignore[type-abstract]
        hook = hook_class(root, plugin_manager=plugin_manager, config=config, metadata=metadata, app=app)

        # Always keep the name to avoid confusion
        hook.PLUGIN_NAME = cls.PLUGIN_NAME

        return hook


================================================
FILE: backend/src/hatchling/builders/hooks/__init__.py
================================================


================================================
FILE: backend/src/hatchling/builders/hooks/custom.py
================================================
from __future__ import annotations

import os
from typing import Any

from hatchling.builders.hooks.plugin.interface import BuildHookInterface
from hatchling.plugin.utils import load_plugin_from_script
from hatchling.utils.constants import DEFAULT_BUILD_SCRIPT


class CustomBuildHook:
    PLUGIN_NAME = "custom"

    def __new__(  # type: ignore[misc]
        cls,
        root: str,
        config: dict[str, Any],
        *args: Any,
        **kwargs: Any,
    ) -> BuildHookInterface:
        build_script = config.get("path", DEFAULT_BUILD_SCRIPT)
        if not isinstance(build_script, str):
            message = f"Option `path` for build hook `{cls.PLUGIN_NAME}` must be a string"
            raise TypeError(message)

        if not build_script:
            message = f"Option `path` for build hook `{cls.PLUGIN_NAME}` must not be empty if defined"
            raise ValueError(message)

        path = os.path.normpath(os.path.join(root, build_script))
        if not os.path.isfile(path):
            message = f"Build script does not exist: {build_script}"
            raise OSError(message)

        hook_class = load_plugin_from_script(path, build_script, BuildHookInterface, "build_hook")
        hook = hook_class(root, config, *args, **kwargs)

        # Always keep the name to avoid confusion
        hook.PLUGIN_NAME = cls.PLUGIN_NAME

        return hook


================================================
FILE: backend/src/hatchling/builders/hooks/plugin/__init__.py
================================================


================================================
FILE: backend/src/hatchling/builders/hooks/plugin/hooks.py
================================================
from __future__ import annotations

import typing

from hatchling.builders.hooks.custom import CustomBuildHook
from hatchling.builders.hooks.version import VersionBuildHook
from hatchling.plugin import hookimpl

if typing.TYPE_CHECKING:
    from hatchling.builders.hooks.plugin.interface import BuildHookInterface


@hookimpl
def hatch_register_build_hook() -> list[type[BuildHookInterface]]:
    return [CustomBuildHook, VersionBuildHook]


================================================
FILE: backend/src/hatchling/builders/hooks/plugin/interface.py
================================================
from __future__ import annotations

from typing import TYPE_CHECKING, Any, Generic, cast

from hatchling.builders.config import BuilderConfigBound

if TYPE_CHECKING:
    from hatchling.bridge.app import Application
    from hatchling.metadata.core import ProjectMetadata


class BuildHookInterface(Generic[BuilderConfigBound]):  # no cov
    """
    Example usage:

    ```python tab="plugin.py"
    from hatchling.builders.hooks.plugin.interface import BuildHookInterface


    class SpecialBuildHook(BuildHookInterface):
        PLUGIN_NAME = "special"
        ...
    ```

    ```python tab="hooks.py"
    from hatchling.plugin import hookimpl

    from .plugin import SpecialBuildHook


    @hookimpl
    def hatch_register_build_hook():
        return SpecialBuildHook
    ```
    """

    PLUGIN_NAME = ""
    """The name used for selection."""

    def __init__(
        self,
        root: str,
        config: dict[str, Any],
        build_config: BuilderConfigBound,
        metadata: ProjectMetadata,
        directory: str,
        target_name: str,
        app: Application | None = None,
    ) -> None:
        self.__root = root
        self.__config = config
        self.__build_config = build_config
        self.__metadata = metadata
        self.__directory = directory
        self.__target_name = target_name
        self.__app = app

    @property
    def app(self) -> Application:
        """
        An instance of [Application](../utilities.md#hatchling.bridge.app.Application).
        """
        if self.__app is None:
            from hatchling.bridge.app import Application

            self.__app = cast(Application, Application().get_safe_application())

        return self.__app

    @property
    def root(self) -> str:
        """
        The root of the project tree.
        """
        return self.__root

    @property
    def config(self) -> dict[str, Any]:
        """
        The cumulative hook configuration.

        ```toml config-example
        [tool.hatch.build.hooks.<PLUGIN_NAME>]
        [tool.hatch.build.targets.<TARGET_NAME>.hooks.<PLUGIN_NAME>]
        ```
        """
        return self.__config

    @property
    def metadata(self) -> ProjectMetadata:
        # Undocumented for now
        return self.__metadata

    @property
    def build_config(self) -> BuilderConfigBound:
        """
        An instance of [BuilderConfig](../utilities.md#hatchling.builders.config.BuilderConfig).
        """
        return self.__build_config

    @property
    def directory(self) -> str:
        """
        The build directory.
        """
        return self.__directory

    @property
    def target_name(self) -> str:
        """
        The plugin name of the build target.
        """
        return self.__target_name

    def dependencies(self) -> list[str]:  # noqa: PLR6301
        """
        A list of extra [dependencies](../../config/dependency.md) that must be installed
        prior to builds.

        !!! warning
            - For this to have any effect the hook dependency itself cannot be dynamic and
                must always be defined in `build-system.requires`.
            - As the hook must be imported to call this method, imports that require these
                dependencies must be evaluated lazily.
        """
        return []

    def clean(self, versions: list[str]) -> None:
        """
        This occurs before the build process if the `-c`/`--clean` flag was passed to
        the [`build`](../../cli/reference.md#hatch-build) command, or when invoking
        the [`clean`](../../cli/reference.md#hatch-clean) command.
        """

    def initialize(self, version: str, build_data: dict[str, Any]) -> None:
        """
        This occurs immediately before each build.

        Any modifications to the build data will be seen by the build target.
        """

    def finalize(self, version: str, build_data: dict[str, Any], artifact_path: str) -> None:
        """
        This occurs immediately after each build and will not run if the `--hooks-only` flag
        was passed to the [`build`](../../cli/reference.md#hatch-build) command.

        The build data will reflect any modifications done by the target during the build.
        """


================================================
FILE: backend/src/hatchling/builders/hooks/version.py
================================================
from __future__ import annotations

from typing import Any

from hatchling.builders.hooks.plugin.interface import BuildHookInterface
from hatchling.version.core import VersionFile


class VersionBuildHook(BuildHookInterface):
    PLUGIN_NAME = "version"

    def __init__(self, *args: Any, **kwargs: Any) -> None:
        super().__init__(*args, **kwargs)

        self.__config_path: str | None = None
        self.__config_template: str | None = None
        self.__config_pattern: str | bool | None = None

    @property
    def config_path(self) -> str:
        if self.__config_path is None:
            path = self.config.get("path", "")
            if not isinstance(path, str):
                message = f"Option `path` for build hook `{self.PLUGIN_NAME}` must be a string"
                raise TypeError(message)

            if not path:
                message = f"Option `path` for build hook `{self.PLUGIN_NAME}` is required"
                raise ValueError(message)

            self.__config_path = path

        return self.__config_path

    @property
    def config_template(self) -> str:
        if self.__config_template is None:
            template = self.config.get("template", "")
            if not isinstance(template, str):
                message = f"Option `template` for build hook `{self.PLUGIN_NAME}` must be a string"
                raise TypeError(message)

            self.__config_template = template

        return self.__config_template

    @property
    def config_pattern(self) -> str | bool:
        if self.__config_pattern is None:
            pattern = self.config.get("pattern", "")
            if not isinstance(pattern, (str, bool)):
                message = f"Option `pattern` for build hook `{self.PLUGIN_NAME}` must be a string or a boolean"
                raise TypeError(message)

            self.__config_pattern = pattern

        return self.__config_pattern

    def initialize(
        self,
        version: str,  # noqa: ARG002
        build_data: dict[str, Any],
    ) -> None:
        version_file = VersionFile(self.root, self.config_path)
        if self.config_pattern:
            version_file.read(pattern=self.config_pattern)
            version_file.set_version(self.metadata.version)
        else:
            version_file.write(self.metadata.version, self.config_template)

        build_data["artifacts"].append(f"/{self.config_path}")


================================================
FILE: backend/src/hatchling/builders/macos.py
================================================
from __future__ import annotations

import os
import platform
import re

__all__ = ["process_macos_plat_tag"]


def process_macos_plat_tag(plat: str, /, *, compat: bool) -> str:
    """
    Process the macOS platform tag. This will normalize the macOS version to
    10.16 if compat=True. If the MACOSX_DEPLOYMENT_TARGET environment variable
    is set, then it will be used instead for the target version.  If archflags
    is set, then the archs will be respected, including a universal build.
    """
    # Default to a native build
    current_arch = platform.machine()
    arm = current_arch == "arm64"

    # Look for cross-compiles
    archflags = os.environ.get("ARCHFLAGS", "")
    if archflags and (archs := re.findall(r"-arch (\S+)", archflags)):
        new_arch = "universal2" if set(archs) == {"x86_64", "arm64"} else archs[0]
        arm = archs == ["arm64"]
        plat = f"{plat[: plat.rfind(current_arch)]}{new_arch}"

    # Process macOS version
    if sdk_match := re.search(r"macosx_(\d+_\d+)", plat):
        macos_version = sdk_match.group(1)
        target = os.environ.get("MACOSX_DEPLOYMENT_TARGET", None)

        try:
            new_version = normalize_macos_version(target or macos_version, arm=arm, compat=compat)
        except ValueError:
            new_version = normalize_macos_version(macos_version, arm=arm, compat=compat)

        return plat.replace(macos_version, new_version, 1)

    return plat


def normalize_macos_version(version: str, *, arm: bool, compat: bool) -> str:
    """
    Set minor version to 0 if major is 11+. Enforces 11+ if arm=True. 11+ is
    converted to 10.16 if compat=True. Version is always returned in
    "major_minor" format.
    """
    version = version.replace(".", "_")
    if "_" not in version:
        version = f"{version}_0"
    major, minor = (int(d) for d in version.split("_")[:2])
    major = max(major, 11) if arm else major
    minor = 0 if major >= 11 else minor  # noqa: PLR2004
    if compat and major >= 11:  # noqa: PLR2004
        major = 10
        minor = 16
    return f"{major}_{minor}"


================================================
FILE: backend/src/hatchling/builders/plugin/__init__.py
================================================


================================================
FILE: backend/src/hatchling/builders/plugin/hooks.py
================================================
from __future__ import annotations

import typing

from hatchling.builders.app import AppBuilder
from hatchling.builders.binary import BinaryBuilder
from hatchling.builders.custom import CustomBuilder
from hatchling.builders.sdist import SdistBuilder
from hatchling.builders.wheel import WheelBuilder
from hatchling.plugin import hookimpl

if typing.TYPE_CHECKING:
    from hatchling.builders.plugin.interface import BuilderInterface


@hookimpl
def hatch_register_builder() -> list[type[BuilderInterface]]:
    return [AppBuilder, BinaryBuilder, CustomBuilder, SdistBuilder, WheelBuilder]  # type: ignore[list-item]


================================================
FILE: backend/src/hatchling/builders/plugin/interface.py
================================================
from __future__ import annotations

import os
import re
from abc import ABC, abstractmethod
from typing import TYPE_CHECKING, Any, Generic, cast

from hatchling.builders.config import BuilderConfig, BuilderConfigBound, env_var_enabled
from hatchling.builders.constants import EXCLUDED_DIRECTORIES, EXCLUDED_FILES, BuildEnvVars
from hatchling.builders.utils import get_relative_path, safe_walk
from hatchling.plugin.manager import PluginManagerBound

if TYPE_CHECKING:
    from collections.abc import Callable, Generator, Iterable

    from hatchling.bridge.app import Application
    from hatchling.builders.hooks.plugin.interface import BuildHookInterface
    from hatchling.metadata.core import ProjectMetadata


class IncludedFile:
    __slots__ = ("distribution_path", "path", "relative_path")

    def __init__(self, path: str, relative_path: str, distribution_path: str) -> None:
        self.path = path
        self.relative_path = relative_path
        self.distribution_path = distribution_path


class BuilderInterface(ABC, Generic[BuilderConfigBound, PluginManagerBound]):
    """
    Example usage:

    ```python tab="plugin.py"
    from hatchling.builders.plugin.interface import BuilderInterface


    class SpecialBuilder(BuilderInterface):
        PLUGIN_NAME = "special"
        ...
    ```

    ```python tab="hooks.py"
    from hatchling.plugin import hookimpl

    from .plugin import SpecialBuilder


    @hookimpl
    def hatch_register_builder():
        return SpecialBuilder
    ```
    """

    PLUGIN_NAME = ""
    """The name used for selection."""

    def __init__(
        self,
        root: str,
        plugin_manager: PluginManagerBound | None = None,
        config: dict[str, Any] | None = None,
        metadata: ProjectMetadata | None = None,
        app: Application | None = None,
    ) -> None:
        self.__root = root
        self.__plugin_manager = cast(PluginManagerBound, plugin_manager)
        self.__raw_config = config
        self.__metadata = metadata
        self.__app = app
        self.__config = cast(BuilderConfigBound, None)
        self.__project_config: dict[str, Any] | None = None
        self.__hatch_config: dict[str, Any] | None = None
        self.__build_config: dict[str, Any] | None = None
        self.__build_targets: list[str] | None = None
        self.__target_config: dict[str, Any] | None = None

        # Metadata
        self.__project_id: str | None = None

    def build(
        self,
        *,
        directory: str | None = None,
        versions: list[str] | None = None,
        hooks_only: bool | None = None,
        clean: bool | None = None,
        clean_hooks_after: bool | None = None,
        clean_only: bool | None = False,
    ) -> Generator[str, None, None]:
        # Fail early for invalid project metadata
        self.metadata.validate_fields()

        if directory is None:
            directory = (
                self.config.normalize_build_directory(os.environ[BuildEnvVars.LOCATION])
                if BuildEnvVars.LOCATION in os.environ
                else self.config.directory
            )

        if not os.path.isdir(directory):
            os.makedirs(directory)

        version_api = self.get_version_api()

        versions = versions or self.config.versions
        if versions:
            unknown_versions = set(versions) - set(version_api)
            if unknown_versions:
                message = (
                    f"Unknown versions for target `{self.PLUGIN_NAME}`: {', '.join(map(str, sorted(unknown_versions)))}"
                )
                raise ValueError(message)

        if hooks_only is None:
            hooks_only = env_var_enabled(BuildEnvVars.HOOKS_ONLY)

        configured_build_hooks = self.get_build_hooks(directory)
        build_hooks = list(configured_build_hooks.values())

        if clean_only:
            clean = True
        elif clean is None:
            clean = env_var_enabled(BuildEnvVars.CLEAN)
        if clean:
            if not hooks_only:
                self.clean(directory, versions)

            for build_hook in build_hooks:
                build_hook.clean(versions)

            if clean_only:
                return

        if clean_hooks_after is None:
            clean_hooks_after = env_var_enabled(BuildEnvVars.CLEAN_HOOKS_AFTER)

        for version in versions:
            self.app.display_debug(f"Building `{self.PLUGIN_NAME}` version `{version}`")

            build_data = self.get_default_build_data()
            self.set_build_data_defaults(build_data)

            # Allow inspection of configured build hooks and the order in which they run
            build_data["build_hooks"] = tuple(configured_build_hooks)

            # Execute all `initialize` build hooks
            for build_hook in build_hooks:
                build_hook.initialize(version, build_data)

            if hooks_only:
                self.app.display_debug(f"Only ran build hooks for `{self.PLUGIN_NAME}` version `{version}`")
                continue

            # Build the artifact
            with self.config.set_build_data(build_data):
                artifact = version_api[version](directory, **build_data)

            # Execute all `finalize` build hooks
            for build_hook in build_hooks:
                build_hook.finalize(version, build_data, artifact)

            if clean_hooks_after:
                for build_hook in build_hooks:
                    build_hook.clean([version])

            yield artifact

    def recurse_included_files(self) -> Iterable[IncludedFile]:
        """
        Returns a consistently generated series of file objects for every file that should be distributed. Each file
        object has three `str` attributes:

        - `path` - the absolute path
        - `relative_path` - the path relative to the project root; will be an empty string for external files
        - `distribution_path` - the path to be distributed as
        """
        yield from self.recurse_selected_project_files()
        yield from self.recurse_forced_files(self.config.get_force_include())

    def recurse_selected_project_files(self) -> Iterable[IncludedFile]:
        if self.config.only_include:
            yield from self.recurse_explicit_files(self.config.only_include)
        else:
            yield from self.recurse_project_files()

    def recurse_project_files(self) -> Iterable[IncludedFile]:
        for root, dirs, files in safe_walk(self.root):
            relative_path = get_relative_path(root, self.root)

            dirs[:] = sorted(d for d in dirs if not self.config.directory_is_excluded(d, relative_path))

            files.sort()
            is_package = "__init__.py" in files
            for f in files:
                if f in EXCLUDED_FILES:
                    continue

                relative_file_path = os.path.join(relative_path, f)
                distribution_path = self.config.get_distribution_path(relative_file_path)
                if self.config.path_is_reserved(distribution_path):
                    continue

                if self.config.include_path(relative_file_path, is_package=is_package):
                    yield IncludedFile(
                        os.path.join(root, f), relative_file_path, self.config.get_distribution_path(relative_file_path)
                    )

    def recurse_forced_files(self, inclusion_map: dict[str, str]) -> Iterable[IncludedFile]:
        for source, target_path in inclusion_map.items():
            external = not source.startswith(self.root)
            if os.path.isfile(source):
                yield IncludedFile(
                    source,
                    "" if external else os.path.relpath(source, self.root),
                    self.config.get_distribution_path(target_path),
                )
            elif os.path.isdir(source):
                for root, dirs, files in safe_walk(source):
                    relative_directory = get_relative_path(root, source)

                    dirs[:] = sorted(d for d in dirs if d not in EXCLUDED_DIRECTORIES)

                    files.sort()
                    for f in files:
                        if f in EXCLUDED_FILES:
                            continue

                        relative_file_path = os.path.join(target_path, relative_directory, f)
                        distribution_path = self.config.get_distribution_path(relative_file_path)
                        if not self.config.path_is_reserved(distribution_path):
                            yield IncludedFile(
                                os.path.join(root, f),
                                "" if external else relative_file_path,
                                distribution_path,
                            )
            else:
                msg = f"Forced include not found: {source}"
                raise FileNotFoundError(msg)

    def recurse_explicit_files(self, inclusion_map: dict[str, str]) -> Iterable[IncludedFile]:
        for source, target_path in inclusion_map.items():
            external = not source.startswith(self.root)
            if os.path.isfile(source):
                distribution_path = self.config.get_distribution_path(target_path)
                if not self.config.path_is_reserved(distribution_path):
                    yield IncludedFile(
                        source,
                        "" if external else os.path.relpath(source, self.root),
                        self.config.get_distribution_path(target_path),
                    )
            elif os.path.isdir(source):
                for root, dirs, files in safe_walk(source):
                    relative_directory = get_relative_path(root, source)

                    dirs[:] = sorted(d for d in dirs if d not in EXCLUDED_DIRECTORIES)

                    files.sort()
                    is_package = "__init__.py" in files
                    for f in files:
                        if f in EXCLUDED_FILES:
                            continue

                        relative_file_path = os.path.join(target_path, relative_directory, f)
                        distribution_path = self.config.get_distribution_path(relative_file_path)
                        if self.config.path_is_reserved(distribution_path):
                            continue

                        if self.config.include_path(relative_file_path, explicit=True, is_package=is_package):
                            yield IncludedFile(
                                os.path.join(root, f), "" if external else relative_file_path, distribution_path
                            )

    @property
    def root(self) -> str:
        """
        The root of the project tree.
        """
        return self.__root

    @property
    def plugin_manager(self) -> PluginManagerBound:
        if self.__plugin_manager is None:
            from hatchling.plugin.manager import PluginManager

            self.__plugin_manager = PluginManager()

        return self.__plugin_manager

    @property
    def metadata(self) -> ProjectMetadata:
        if self.__metadata is None:
            from hatchling.metadata.core import ProjectMetadata

            self.__metadata = ProjectMetadata(self.root, self.plugin_manager, self.__raw_config)

        return self.__metadata

    @property
    def app(self) -> Application:
        """
        An instance of [Application](../utilities.md#hatchling.bridge.app.Application).
        """
        if self.__app is None:
            from hatchling.bridge.app import Application

            self.__app = cast(Application, Application().get_safe_application())

        return self.__app

    @property
    def raw_config(self) -> dict[str, Any]:
        if self.__raw_config is None:
            self.__raw_config = self.metadata.config

        return self.__raw_config

    @property
    def project_config(self) -> dict[str, Any]:
        if self.__project_config is None:
            self.__project_config = self.metadata.core.config

        return self.__project_config

    @property
    def hatch_config(self) -> dict[str, Any]:
        if self.__hatch_config is None:
            self.__hatch_config = self.metadata.hatch.config

        return self.__hatch_config

    @property
    def config(self) -> BuilderConfigBound:
        """
        An instance of [BuilderConfig](../utilities.md#hatchling.builders.config.BuilderConfig).
        """
        if self.__config is None:
            self.__config = self.get_config_class()(
                self, self.root, self.PLUGIN_NAME, self.build_config, self.target_config
            )

        return self.__config

    @property
    def build_config(self) -> dict[str, Any]:
        """
        ```toml config-example
        [tool.hatch.build]
        ```
        """
        if self.__build_config is None:
            self.__build_config = self.metadata.hatch.build_config

        return self.__build_config

    @property
    def target_config(self) -> dict[str, Any]:
        """
        ```toml config-example
        [tool.hatch.build.targets.<PLUGIN_NAME>]
        ```
        """
        if self.__target_config is None:
            target_config: dict[str, Any] = self.metadata.hatch.build_targets.get(self.PLUGIN_NAME, {})
            if not isinstance(target_config, dict):
                message = f"Field `tool.hatch.build.targets.{self.PLUGIN_NAME}` must be a table"
                raise TypeError(message)

            self.__target_config = target_config

        return self.__target_config

    @property
    def project_id(self) -> str:
        if self.__project_id is None:
            self.__project_id = f"{self.normalize_file_name_component(self.metadata.core.name)}-{self.metadata.version}"

        return self.__project_id

    def get_build_hooks(self, directory: str) -> dict[str, BuildHookInterface]:
        configured_build_hooks = {}
        for hook_name, config in self.config.hook_config.items():
            build_hook = self.plugin_manager.build_hook.get(hook_name)
            if build_hook is None:
                from hatchling.plugin.exceptions import UnknownPluginError

                message = f"Unknown build hook: {hook_name}"
                raise UnknownPluginError(message)

            configured_build_hooks[hook_name] = build_hook(
                self.root, config, self.config, self.metadata, directory, self.PLUGIN_NAME, self.app
            )

        return configured_build_hooks

    @abstractmethod
    def get_version_api(self) -> dict[str, Callable]:
        """
        A mapping of `str` versions to a callable that is used for building.
        Each callable must have the following signature:

        ```python
        def ...(build_dir: str, build_data: dict) -> str:
        ```

        The return value must be the absolute path to the built artifact.
        """

    def get_default_versions(self) -> list[str]:
        """
        A list of versions to build when users do not specify any, defaulting to all versions.
        """
        return list(self.get_version_api())

    def get_default_build_data(self) -> dict[str, Any]:  # noqa: PLR6301
        """
        A mapping that can be modified by [build hooks](../build-hook/reference.md) to influence the behavior of builds.
        """
        return {}

    def set_build_data_defaults(self, build_data: dict[str, Any]) -> None:  # noqa: PLR6301
        build_data.setdefault("artifacts", [])
        build_data.setdefault("force_include", {})

    def clean(self, directory: str, versions: list[str]) -> None:
        """
        Called before builds if the `-c`/`--clean` flag was passed to the
        [`build`](../../cli/reference.md#hatch-build) command.
        """

    @classmethod
    def get_config_class(cls) -> type[BuilderConfig]:
        """
        Must return a subclass of [BuilderConfig](../utilities.md#hatchling.builders.config.BuilderConfig).
        """
        return BuilderConfig

    @staticmethod
    def normalize_file_name_component(file_name: str) -> str:
        """
        https://peps.python.org/pep-0427/#escaping-and-unicode
        """
        return re.sub(r"[^\w\d.]+", "_", file_name, flags=re.UNICODE)


================================================
FILE: backend/src/hatchling/builders/sdist.py
================================================
from __future__ import annotations

import gzip
import os
import tarfile
import tempfile
from contextlib import closing
from copy import copy
from io import BytesIO
from time import time as get_current_timestamp
from typing import TYPE_CHECKING, Any

from hatchling.builders.config import BuilderConfig
from hatchling.builders.plugin.interface import BuilderInterface
from hatchling.builders.utils import (
    get_reproducible_timestamp,
    normalize_archive_path,
    normalize_artifact_permissions,
    normalize_file_permissions,
    normalize_relative_path,
    replace_file,
)
from hatchling.metadata.spec import DEFAULT_METADATA_VERSION, get_core_metadata_constructors
from hatchling.utils.constants import DEFAULT_BUILD_SCRIPT, DEFAULT_CONFIG_FILE

if TYPE_CHECKING:
    from collections.abc import Callable
    from types import TracebackType


class SdistArchive:
    def __init__(self, name: str, *, reproducible: bool) -> None:
        """
        https://peps.python.org/pep-0517/#source-distributions
        """
        self.name = name
        self.reproducible = reproducible
        self.timestamp: int | None = get_reproducible_timestamp() if reproducible else None

        raw_fd, self.path = tempfile.mkstemp(suffix=".tar.gz")
        self.fd = os.fdopen(raw_fd, "w+b")
        self.gz = gzip.GzipFile(fileobj=self.fd, mode="wb", mtime=self.timestamp)
        self.tf = tarfile.TarFile(fileobj=self.gz, mode="w", format=tarfile.PAX_FORMAT)
        self.gettarinfo = lambda *args, **kwargs: self.normalize_tar_metadata(self.tf.gettarinfo(*args, **kwargs))

    def create_file(self, contents: str | bytes, *relative_paths: str) -> None:
        if not isinstance(contents, bytes):
            contents = contents.encode("utf-8")
        tar_info = tarfile.TarInfo(normalize_archive_path(os.path.join(self.name, *relative_paths)))
        tar_info.size = len(contents)
        if self.reproducible and self.timestamp is not None:
            tar_info.mtime = self.timestamp
        else:
            tar_info.mtime = int(get_current_timestamp())

        with closing(BytesIO(contents)) as buffer:
            self.tf.addfile(tar_info, buffer)

    def normalize_tar_metadata(self, tar_info: tarfile.TarInfo | None) -> tarfile.TarInfo | None:
        if not self.reproducible or tar_info is None:
            return tar_info

        tar_info = copy(tar_info)
        tar_info.uid = 0
        tar_info.gid = 0
        tar_info.uname = ""
        tar_info.gname = ""
        tar_info.mode = normalize_file_permissions(tar_info.mode)
        if self.timestamp is not None:
            tar_info.mtime = self.timestamp

        return tar_info

    def __getattr__(self, name: str) -> Any:
        attr = getattr(self.tf, name)
        setattr(self, name, attr)
        return attr

    def __enter__(self) -> SdistArchive:  # noqa: PYI034
        return self

    def __exit__(
        self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None
    ) -> None:
        self.tf.close()
        self.gz.close()
        self.fd.close()


class SdistBuilderConfig(BuilderConfig):
    def __init__(self, *args: Any, **kwargs: Any) -> None:
        super().__init__(*args, **kwargs)

        self.__core_metadata_constructor: Callable[..., str] | None = None
        self.__strict_naming: bool | None = None
        self.__support_legacy: bool | None = None

    @property
    def core_metadata_constructor(self) -> Callable[..., str]:
        if self.__core_metadata_constructor is None:
            core_metadata_version = self.target_config.get("core-metadata-version", DEFAULT_METADATA_VERSION)
            if not isinstance(core_metadata_version, str):
                message = f"Field `tool.hatch.build.targets.{self.plugin_name}.core-metadata-version` must be a string"
                raise TypeError(message)

            constructors = get_core_metadata_constructors()
            if core_metadata_version not in constructors:
                message = (
                    f"Unknown metadata version `{core_metadata_version}` for field "
                    f"`tool.hatch.build.targets.{self.plugin_name}.core-metadata-version`. "
                    f"Available: {', '.join(sorted(constructors))}"
                )
                raise ValueError(message)

            self.__core_metadata_constructor = constructors[core_metadata_version]

        return self.__core_metadata_constructor

    @property
    def strict_naming(self) -> bool:
        if self.__strict_naming is None:
            if "strict-naming" in self.target_config:
                strict_naming = self.target_config["strict-naming"]
                if not isinstance(strict_naming, bool):
                    message = f"Field `tool.hatch.build.targets.{self.plugin_name}.strict-naming` must be a boolean"
                    raise TypeError(message)
            else:
                strict_naming = self.build_config.get("strict-naming", True)
                if not isinstance(strict_naming, bool):
                    message = "Field `tool.hatch.build.strict-naming` must be a boolean"
                    raise TypeError(message)

            self.__strict_naming = strict_naming

        return self.__strict_naming

    @property
    def support_legacy(self) -> bool:
        if self.__support_legacy is None:
            self.__support_legacy = bool(self.target_config.get("support-legacy", False))

        return self.__support_legacy


class SdistBuilder(BuilderInterface):
    """
    Build an archive of the source files
    """

    PLUGIN_NAME = "sdist"

    def get_version_api(self) -> dict[str, Callable]:
        return {"standard": self.build_standard}

    def get_default_versions(self) -> list[str]:  # noqa: PLR6301
        return ["standard"]

    def clean(  # noqa: PLR6301
        self,
        directory: str,
        versions: list[str],  # noqa: ARG002
    ) -> None:
        for filename in os.listdir(directory):
            if filename.endswith(".tar.gz"):
                os.remove(os.path.join(directory, filename))

    def build_standard(self, directory: str, **build_data: Any) -> str:
        found_packages = set()

        with SdistArchive(self.artifact_project_id, reproducible=self.config.reproducible) as archive:
            for included_file in self.recurse_included_files():
                if self.config.support_legacy:
                    possible_package, file_name = os.path.split(included_file.relative_path)
                    if file_name == "__init__.py":
                        found_packages.add(possible_package)

                tar_info = archive.gettarinfo(
                    included_file.path,
                    arcname=normalize_archive_path(
                        os.path.join(self.artifact_project_id, included_file.distribution_path)
                    ),
                )
                if tar_info is None:  # no cov
                    continue

                if tar_info.isfile():
                    with open(included_file.path, "rb") as f:
                        archive.addfile(tar_info, f)
                else:  # no cov
                    # TODO: Investigate if this is necessary (for symlinks, etc.)
                    archive.addfile(tar_info)

            archive.create_file(
                self.config.core_metadata_constructor(self.metadata, extra_dependencies=build_data["dependencies"]),
                "PKG-INFO",
            )

            if self.config.support_legacy:
                archive.create_file(
                    self.construct_setup_py_file(sorted(found_packages), extra_dependencies=build_data["dependencies"]),
                    "setup.py",
                )

        target = os.path.join(directory, f"{self.artifact_project_id}.tar.gz")

        replace_file(archive.path, target)
        normalize_artifact_permissions(target)
        return target

    @property
    def artifact_project_id(self) -> str:
        return (
            self.project_id
            if self.config.strict_naming
            else f"{self.normalize_file_name_component(self.metadata.core.raw_name)}-{self.metadata.version}"
        )

    def construct_setup_py_file(self, packages: list[str], extra_dependencies: tuple[()] = ()) -> str:
        contents = "from setuptools import setup\n\n"

        contents += "setup(\n"

        contents += f"    name={self.metadata.core.name!r},\n"
        contents += f"    version={self.metadata.version!r},\n"

        if self.metadata.core.description:
            contents += f"    description={self.metadata.core.description!r},\n"

        if self.metadata.core.readme:
            contents += f"    long_description={self.metadata.core.readme!r},\n"

        authors_data = self.metadata.core.authors_data
        if authors_data["name"]:
            contents += f"    author={', '.join(authors_data['name'])!r},\n"
        if authors_data["email"]:
            contents += f"    author_email={', '.join(authors_data['email'])!r},\n"

        maintainers_data = self.metadata.core.maintainers_data
        if maintainers_data["name"]:
            contents += f"    maintainer={', '.join(maintainers_data['name'])!r},\n"
        if maintainers_data["email"]:
            contents += f"    maintainer_email={', '.join(maintainers_data['email'])!r},\n"

        if self.metadata.core.classifiers:
            contents += "    classifiers=[\n"

            for classifier in self.metadata.core.classifiers:
                contents += f"        {classifier!r},\n"

            contents += "    ],\n"

        dependencies = list(self.metadata.core.dependencies)
        dependencies.extend(extra_dependencies)
        if dependencies:
            contents += "    install_requires=[\n"

            for raw_specifier in dependencies:
                specifier = raw_specifier.replace("'", '"')
                contents += f"        {specifier!r},\n"

            contents += "    ],\n"

        if self.metadata.core.optional_dependencies:
            contents += "    extras_require={\n"

            for option, specifiers in self.metadata.core.optional_dependencies.items():
                if not specifiers:
                    continue

                contents += f"        {option!r}: [\n"

                for raw_specifier in specifiers:
                    specifier = raw_specifier.replace("'", '"')
                    contents += f"            {specifier!r},\n"

                contents += "        ],\n"

            contents += "    },\n"

        if self.metadata.core.scripts or self.metadata.core.gui_scripts or self.metadata.core.entry_points:
            contents += "    entry_points={\n"

            if self.metadata.core.scripts:
                contents += "        'console_scripts': [\n"

                for name, object_ref in self.metadata.core.scripts.items():
                    contents += f"            '{name} = {object_ref}',\n"

                contents += "        ],\n"

            if self.metadata.core.gui_scripts:
                contents += "        'gui_scripts': [\n"

                for name, object_ref in self.metadata.core.gui_scripts.items():
                    contents += f"            '{name} = {object_ref}',\n"

                contents += "        ],\n"

            if self.metadata.core.entry_points:
                for group, entry_points in self.metadata.core.entry_points.items():
                    contents += f"        {group!r}: [\n"

                    for name, object_ref in entry_points.items():
                        contents += f"            '{name} = {object_ref}',\n"

                    contents += "        ],\n"

            contents += "    },\n"

        if packages:
            src_layout = False
            contents += "    packages=[\n"

            for package in packages:
                if package.startswith(f"src{os.sep}"):
                    src_layout = True
                    contents += f"        {package.replace(os.sep, '.')[4:]!r},\n"
                else:
                    contents += f"        {package.replace(os.sep, '.')!r},\n"

            contents += "    ],\n"

            if src_layout:
                contents += "    package_dir={'': 'src'},\n"

        contents += ")\n"

        return contents

    def get_default_build_data(self) -> dict[str, Any]:
        force_include = {}
        for filename in ["pyproject.toml", DEFAULT_CONFIG_FILE, DEFAULT_BUILD_SCRIPT]:
            path = os.path.join(self.root, filename)
            if os.path.exists(path):
                force_include[path] = filename
        build_data = {"force_include": force_include, "dependencies": []}

        for exclusion_files in self.config.vcs_exclusion_files.values():
            for exclusion_file in exclusion_files:
                force_include[exclusion_file] = os.path.basename(exclusion_file)

        readme_path = self.metadata.core.readme_path
        if readme_path:
            readme_path = normalize_relative_path(readme_path)
            force_include[os.path.join(self.root, readme_path)] = readme_path

        license_files = self.metadata.core.license_files
        if license_files:
            for license_file in license_files:
                relative_path = normalize_relative_path(license_file)
                force_include[os.path.join(self.root, relative_path)] = relative_path

        return build_data

    @classmethod
    def get_config_class(cls) -> type[SdistBuilderConfig]:
        return SdistBuilderConfig


================================================
FILE: backend/src/hatchling/builders/utils.py
================================================
from __future__ import annotations

import os
import shutil
from base64 import urlsafe_b64encode
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from collections.abc import Iterable
    from zipfile import ZipInfo


def replace_file(src: str, dst: str) -> None:
    try:
        os.replace(src, dst)
    # Happens when on different filesystems like /tmp or caused by layering in containers
    except OSError:
        shutil.copy2(src, dst)
        os.remove(src)


def safe_walk(path: str) -> Iterable[tuple[str, list[str], list[str]]]:
    seen = set()
    for root, dirs, files in os.walk(path, followlinks=True):
        stat = os.stat(root)
        identifier = stat.st_dev, stat.st_ino
        if identifier in seen:
            del dirs[:]
            continue

        seen.add(identifier)
        yield root, dirs, files


def get_known_python_major_versions() -> map:
    return map(str, sorted((2, 3)))


def get_relative_path(path: str, start: str) -> str:
    relative_path = os.path.relpath(path, start)

    # First iteration of `os.walk`
    if relative_path == ".":
        return ""

    return relative_path


def normalize_relative_path(path: str) -> str:
    return os.path.normpath(path).strip(os.sep)


def normalize_relative_directory(path: str) -> str:
    return normalize_relative_path(path) + os.sep


def normalize_inclusion_map(inclusion_map: dict[str, str], root: str) -> dict[str, str]:
    normalized_inclusion_map = {}

    for raw_source, relative_path in inclusion_map.items():
        source = os.path.expanduser(os.path.normpath(raw_source))
        if not os.path.isabs(source):
            source = os.path.abspath(os.path.join(root, source))

        normalized_inclusion_map[source] = normalize_relative_path(relative_path)

    return dict(
        sorted(
            normalized_inclusion_map.items(),
            key=lambda item: (item[1].count(os.sep), item[1], item[0]),
        )
    )


def normalize_archive_path(path: str) -> str:
    if os.sep != "/":
        return path.replace(os.sep, "/")

    return path


def format_file_hash(digest: bytes) -> str:
    # https://peps.python.org/pep-0427/#signed-wheel-files
    return urlsafe_b64encode(digest).decode("ascii").rstrip("=")


def get_reproducible_timestamp() -> int:
    """
    Returns an `int` derived from the `SOURCE_DATE_EPOCH` environment variable; see
    https://reproducible-builds.org/specs/source-date-epoch/.

    The default value will always be: `1580601600`
    """
    return int(os.environ.get("SOURCE_DATE_EPOCH", "1580601600"))


def normalize_file_permissions(st_mode: int) -> int:
    """
    https://github.com/takluyver/flit/blob/6a2a8c6462e49f584941c667b70a6f48a7b3f9ab/flit_core/flit_core/common.py#L257

    Normalize the permission bits in the st_mode field from stat to 644/755.

    Popular VCSs only track whether a file is executable or not. The exact
    permissions can vary on systems with different umasks. Normalizing
    to 644 (non executable) or 755 (executable) makes builds more reproducible.
    """
    # Set 644 permissions, leaving higher bits of st_mode unchanged
    new_mode = (st_mode | 0o644) & ~0o133
    if st_mode & 0o100:  # no cov
        new_mode |= 0o111  # Executable: 644 -> 755
    return new_mode


def normalize_artifact_permissions(path: str) -> None:
    """
    Normalize the permission bits for artifacts
    """
    file_stat = os.stat(path)
    new_mode = normalize_file_permissions(file_stat.st_mode)
    os.chmod(path, new_mode)


def set_zip_info_mode(zip_info: ZipInfo, mode: int = 0o644) -> None:
    """
    https://github.com/python/cpython/blob/v3.12.3/Lib/zipfile/__init__.py#L574
    https://github.com/takluyver/flit/commit/3889583719888aef9f28baaa010e698cb7884904
    """
    zip_info.external_attr = (mode & 0xFFFF) << 16


================================================
FILE: backend/src/hatchling/builders/wheel.py
================================================
from __future__ import annotations

import csv
import hashlib
import os
import stat
import sys
import tempfile
import zipfile
from functools import cached_property
from io import StringIO
from typing import TYPE_CHECKING, Any, NamedTuple, cast

from hatchling.__about__ import __version__
from hatchling.builders.config import BuilderConfig
from hatchling.builders.constants import EDITABLES_REQUIREMENT
from hatchling.builders.plugin.interface import BuilderInterface
from hatchling.builders.utils import (
    format_file_hash,
    get_known_python_major_versions,
    get_reproducible_timestamp,
    normalize_archive_path,
    normalize_artifact_permissions,
    normalize_file_permissions,
    normalize_inclusion_map,
    replace_file,
    set_zip_info_mode,
)
from hatchling.metadata.spec import DEFAULT_METADATA_VERSION, get_core_metadata_constructors

if TYPE_CHECKING:
    from collections.abc import Callable, Iterable, Sequence
    from types import TracebackType

    from hatchling.builders.plugin.interface import IncludedFile


TIME_TUPLE = tuple[int, int, int, int, int, int]


class FileSelectionOptions(NamedTuple):
    include: list[str]
    exclude: list[str]
    packages: list[str]
    only_include: list[str]


class RecordFile:
    def __init__(self) -> None:
        self.__file_obj = StringIO()
        self.__writer = csv.writer(self.__file_obj, delimiter=",", quotechar='"', lineterminator="\n")

    def write(self, record: Iterable[Any]) -> None:
        self.__writer.writerow(record)

    def construct(self) -> str:
        return self.__file_obj.getvalue()

    def __enter__(self) -> RecordFile:  # noqa: PYI034
        return self

    def __exit__(
        self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None
    ) -> None:
        self.__file_obj.close()


class WheelArchive:
    def __init__(self, project_id: str, *, reproducible: bool) -> None:
        """
        https://peps.python.org/pep-0427/#abstract
        """
        self.metadata_directory = f"{project_id}.dist-info"
        self.shared_data_directory = f"{project_id}.data"
        self.time_tuple: TIME_TUPLE | None = None

        self.reproducible = reproducible
        if self.reproducible:
            self.time_tuple = self.get_reproducible_time_tuple()
        else:
            self.time_tuple = None

        raw_fd, self.path = tempfile.mkstemp(suffix=".whl")
        self.fd = os.fdopen(raw_fd, "w+b")
        self.zf = zipfile.ZipFile(self.fd, "w", compression=zipfile.ZIP_DEFLATED)

    @staticmethod
    def get_reproducible_time_tuple() -> TIME_TUPLE:
        from datetime import datetime, timezone

        # `zipfile.ZipInfo` does not support timestamps before 1980
        min_ts = 315532800  # 1980-01-01T00:00:00Z
        d = datetime.fromtimestamp(max(get_reproducible_timestamp(), min_ts), timezone.utc)
        return d.year, d.month, d.day, d.hour, d.minute, d.second

    def add_file(self, included_file: IncludedFile) -> tuple[str, str, str]:
        relative_path = normalize_archive_path(included_file.distribution_path)
        file_stat = os.stat(included_file.path)

        if self.reproducible:
            zip_info = zipfile.ZipInfo(relative_path, cast(TIME_TUPLE, self.time_tuple))

            # https://github.com/takluyver/flit/pull/66
            new_mode = normalize_file_permissions(file_stat.st_mode)
            set_zip_info_mode(zip_info, new_mode)
            if stat.S_ISDIR(file_stat.st_mode):  # no cov
                zip_info.external_attr |= 0x10
            else:
                zip_info.file_size = file_stat.st_size
        else:
            zip_info = zipfile.ZipInfo.from_file(included_file.path, relative_path)

        zip_info.compress_type = zipfile.ZIP_DEFLATED

        hash_obj = hashlib.sha256()
        with open(included_file.path, "rb") as in_file, self.zf.open(zip_info, "w") as out_file:
            while True:
                chunk = in_file.read(16384)
                if not chunk:
                    break

                hash_obj.update(chunk)
                out_file.write(chunk)

        hash_digest = format_file_hash(hash_obj.digest())
        return relative_path, f"sha256={hash_digest}", str(file_stat.st_size)

    def write_metadata(self, relative_path: str, contents: str | bytes) -> tuple[str, str, str]:
        relative_path = f"{self.metadata_directory}/{normalize_archive_path(relative_path)}"
        return self.write_file(relative_path, contents)

    def write_shared_script(self, included_file: IncludedFile, contents: str | bytes) -> tuple[str, str, str]:
        relative_path = (
            f"{self.shared_data_directory}/scripts/{normalize_archive_path(included_file.distribution_path)}"
        )
        if sys.platform == "win32":
            return self.write_file(relative_path, contents)

        file_stat = os.stat(included_file.path)
        return self.write_file(
            relative_path,
            contents,
            mode=normalize_file_permissions(file_stat.st_mode) if self.reproducible else file_stat.st_mode,
        )

    def add_shared_file(self, shared_file: IncludedFile) -> tuple[str, str, str]:
        shared_file.distribution_path = f"{self.shared_data_directory}/data/{shared_file.distribution_path}"
        return self.add_file(shared_file)

    def add_extra_metadata_file(self, extra_metadata_file: IncludedFile) -> tuple[str, str, str]:
        extra_metadata_file.distribution_path = (
            f"{self.metadata_directory}/extra_metadata/{extra_metadata_file.distribution_path}"
        )
        return self.add_file(extra_metadata_file)

    def add_sbom_file(self, sbom_file: IncludedFile) -> tuple[str, str, str]:
        """Add SBOM file to .dist-info/sboms/ directory."""
        sbom_file.distribution_path = f"{self.metadata_directory}/sboms/{sbom_file.distribution_path}"
        return self.add_file(sbom_file)

    def write_file(
        self,
        relative_path: str,
        contents: str | bytes,
        *,
        mode: int | None = None,
    ) -> tuple[str, str, str]:
        if not isinstance(contents, bytes):
            contents = contents.encode("utf-8")

        time_tuple = self.time_tuple or (2020, 2, 2, 0, 0, 0)
        zip_info = zipfile.ZipInfo(relative_path, time_tuple)
        if mode is None:
            set_zip_info_mode(zip_info)
        else:
            set_zip_info_mode(zip_info, mode)

        hash_obj = hashlib.sha256(contents)
        hash_digest = format_file_hash(hash_obj.digest())
        self.zf.writestr(zip_info, contents, compress_type=zipfile.ZIP_DEFLATED)

        return relative_path, f"sha256={hash_digest}", str(len(contents))

    def __enter__(self) -> WheelArchive:  # noqa: PYI034
        return self

    def __exit__(
        self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None
    ) -> None:
        self.zf.close()
        self.fd.close()


class WheelBuilderConfig(BuilderConfig):
    def __init__(self, *args: Any, **kwargs: Any) -> None:
        super().__init__(*args, **kwargs)

        self.__core_metadata_constructor: Callable[..., str] | None = None
        self.__shared_data: dict[str, str] | None = None
        self.__shared_scripts: dict[str, str] | None = None
        self.__extra_metadata: dict[str, str] | None = None
        self.__strict_naming: bool | None = None
        self.__macos_max_compat: bool | None = None

    @cached_property
    def default_file_selection_options(self) -> FileSelectionOptions:
        include = self.target_config.get("include", self.build_config.get("include", []))
        exclude = self.target_config.get("exclude", self.build_config.get("exclude", []))
        packages = self.target_config.get("packages", self.build_config.get("packages", []))
        only_include = self.target_config.get("only-include", self.build_config.get("only-include", []))

        if include or packages or only_include:
            return FileSelectionOptions(include, exclude, packages, only_include)

        project_names: set[str] = set()
        for project_name in (
            self.builder.normalize_file_name_component(self.builder.metadata.core.raw_name),
            self.builder.normalize_file_name_component(self.builder.metadata.core.name),
        ):
            if os.path.isfile(os.path.join(self.root, project_name, "__init__.py")):
                normalized_project_name = self.get_raw_fs_path_name(self.root, project_name)
                return FileSelectionOptions([], exclude, [normalized_project_name], [])

            if os.path.isfile(os.path.join(self.root, "src", project_name, "__init__.py")):
                normalized_project_name = self.get_raw_fs_path_name(os.path.join(self.root, "src"), project_name)
                return FileSelectionOptions([], exclude, [f"src/{normalized_project_name}"], [])

            module_file = f"{project_name}.py"
            if os.path.isfile(os.path.join(self.root, module_file)):
                return FileSelectionOptions([], exclude, [], [module_file])

            from glob import glob

            possible_namespace_packages = glob(os.path.join(self.root, "*", project_name, "__init__.py"))
            if len(possible_namespace_packages) == 1:
                relative_path = os.path.relpath(possible_namespace_packages[0], self.root)
                namespace = relative_path.split(os.sep)[0]
                return FileSelectionOptions([], exclude, [namespace], [])
            project_names.add(project_name)

        if self.bypass_selection or self.build_artifact_spec is not None or self.get_force_include():
            self.set_exclude_all()
            return FileSelectionOptions([], exclude, [], [])

        project_names_text = " or ".join(sorted(project_names))
        message = (
            f"Unable to determine which files to ship inside the wheel using the following heuristics: "
            f"https://hatch.pypa.io/latest/plugins/builder/wheel/#default-file-selection\n\n"
            f"The most likely cause of this is that there is no directory that matches the name of your "
            f"project ({project_names_text}).\n\n"
            f"At least one file selection option must be defined in the `tool.hatch.build.targets.wheel` "
            f"table, see: https://hatch.pypa.io/latest/config/build/\n\n"
            f"As an example, if you intend to ship a directory named `foo` that resides within a `src` "
            f"directory located at the root of your project, you can define the following:\n\n"
            f"[tool.hatch.build.targets.wheel]\n"
            f'packages = ["src/foo"]'
        )
        raise ValueError(message)

    def default_include(self) -> list[str]:
        return self.default_file_selection_options.include

    def default_exclude(self) -> list[str]:
        return self.default_file_selection_options.exclude

    def default_packages(self) -> list[str]:
        return self.default_file_selection_options.packages

    def default_only_include(self) -> list[str]:
        return self.default_file_selection_options.only_include

    @property
    def core_metadata_constructor(self) -> Callable[..., str]:
        if self.__core_metadata_constructor is None:
            core_metadata_version = self.target_config.get("core-metadata-version", DEFAULT_METADATA_VERSION)
            if not isinstance(core_metadata_version, str):
                message = f"Field `tool.hatch.build.targets.{self.plugin_name}.core-metadata-version` must be a string"
                raise TypeError(message)

            constructors = get_core_metadata_constructors()
            if core_metadata_version not in constructors:
                message = (
                    f"Unknown metadata version `{core_metadata_version}` for field "
                    f"`tool.hatch.build.targets.{self.plugin_name}.core-metadata-version`. "
                    f"Available: {', '.join(sorted(constructors))}"
                )
                raise ValueError(message)

            self.__core_metadata_constructor = constructors[core_metadata_version]

        return self.__core_metadata_constructor

    @property
    def shared_data(self) -> dict[str, str]:
        if self.__shared_data is None:
            shared_data = self.target_config.get("shared-data", {})
            if not isinstance(shared_data, dict):
                message = f"Field `tool.hatch.build.targets.{self.plugin_name}.shared-data` must be a mapping"
                raise TypeError(message)

            for i, (source, relative_path) in enumerate(shared_data.items(), 1):
                if not source:
                    message = (
                        f"Source #{i} in field `tool.hatch.build.targets.{self.plugin_name}.shared-data` "
                        f"cannot be an empty string"
                    )
                    raise ValueError(message)

                if not isinstance(relative_path, str):
                    message = (
                        f"Path for source `{source}` in field "
                        f"`tool.hatch.build.targets.{self.plugin_name}.shared-data` must be a string"
                    )
                    raise TypeError(message)

                if not relative_path:
                    message = (
                        f"Path for source `{source}` in field "
                        f"`tool.hatch.build.targets.{self.plugin_name}.shared-data` cannot be an empty string"
                    )
                    raise ValueError(message)

            self.__shared_data = normalize_inclusion_map(shared_data, self.root)

        return self.__shared_data

    @property
    def shared_scripts(self) -> dict[str, str]:
        if self.__shared_scripts is None:
            shared_scripts = self.target_config.get("shared-scripts", {})
            if not isinstance(shared_scripts, dict):
                message = f"Field `tool.hatch.build.targets.{self.plugin_name}.shared-scripts` must be a mapping"
                raise TypeError(message)

            for i, (source, relative_path) in enumerate(shared_scripts.items(), 1):
                if not source:
                    message = (
                        f"Source #{i} in field `tool.hatch.build.targets.{self.plugin_name}.shared-scripts` "
                        f"cannot be an empty string"
                    )
                    raise ValueError(message)

                if not isinstance(relative_path, str):
                    message = (
                        f"Path for source `{source}` in field "
                        f"`tool.hatch.build.targets.{self.plugin_name}.shared-scripts` must be a string"
                    )
                    raise TypeError(message)

                if not relative_path:
                    message = (
                        f"Path for source `{source}` in field "
                        f"`tool.hatch.build.targets.{self.plugin_name}.shared-scripts` cannot be an empty string"
                    )
                    raise ValueError(message)

            self.__shared_scripts = normalize_inclusion_map(shared_scripts, self.root)

        return self.__shared_scripts

    @property
    def extra_metadata(self) -> dict[str, str]:
        if self.__extra_metadata is None:
            extra_metadata = self.target_config.get("extra-metadata", {})
            if not isinstance(extra_metadata, dict):
                message = f"Field `tool.hatch.build.targets.{self.plugin_name}.extra-metadata` must be a mapping"
                raise TypeError(message)

            for i, (source, relative_path) in enumerate(extra_metadata.items(), 1):
                if not source:
                    message = (
                        f"Source #{i} in field `tool.hatch.build.targets.{self.plugin_name}.extra-metadata` "
                        f"cannot be an empty string"
                    )
                    raise ValueError(message)

                if not isinstance(relative_path, str):
                    message = (
                        f"Path for source `{source}` in field "
                        f"`tool.hatch.build.targets.{self.plugin_name}.extra-metadata` must be a string"
                    )
                    raise TypeError(message)

                if not relative_path:
                    message = (
                        f"Path for source `{source}` in field "
                        f"`tool.hatch.build.targets.{self.plugin_name}.extra-metadata` cannot be an empty string"
                    )
                    raise ValueError(message)

            self.__extra_metadata = normalize_inclusion_map(extra_metadata, self.root)

        return self.__extra_metadata

    @property
    def sbom_files(self) -> list[str]:
        """
        https://peps.python.org/pep-0770/
        """
        sbom_files = self.target_config.get("sbom-files", [])
        if not isinstance(sbom_files, list):
            message = f"Field `tool.hatch.build.targets.{self.plugin_name}.sbom-files` must be an array"
            raise TypeError(message)

        for i, sbom_file in enumerate(sbom_files, 1):
            if not isinstance(sbom_file, str):
                message = (
                    f"SBOM file #{i} in field `tool.hatch.build.targets.{self.plugin_name}.sbom-files` must be a string"
                )
                raise TypeError(message)

        return sbom_files

    @property
    def strict_naming(self) -> bool:
        if self.__strict_naming is None:
            if "strict-naming" in self.target_config:
                strict_naming = self.target_config["strict-naming"]
                if not isinstance(strict_naming, bool):
                    message = f"Field `tool.hatch.build.targets.{self.plugin_name}.strict-naming` must be a boolean"
                    raise TypeError(message)
            else:
                strict_naming = self.build_config.get("strict-naming", True)
                if not isinstance(strict_naming, bool):
                    message = "Field `tool.hatch.build.strict-naming` must be a boolean"
                    raise TypeError(message)

            self.__strict_naming = strict_naming

        return self.__strict_naming

    @property
    def macos_max_compat(self) -> bool:
        if self.__macos_max_compat is None:
            macos_max_compat = self.target_config.get("macos-max-compat", False)
            if not isinstance(macos_max_compat, bool):
                message = f"Field `tool.hatch.build.targets.{self.plugin_name}.macos-max-compat` must be a boolean"
                raise TypeError(message)

            self.__macos_max_compat = macos_max_compat

        return self.__macos_max_compat

    @cached_property
    def bypass_selection(self) -> bool:
        bypass_selection = self.target_config.get("bypass-selection", False)
        if not isinstance(bypass_selection, bool):
            message = f"Field `tool.hatch.build.targets.{self.plugin_name}.bypass-selection` must be a boolean"
            raise TypeError(message)

        return bypass_selection

    if sys.platform in {"darwin", "win32"}:

        @staticmethod
        def get_raw_fs_path_name(directory: str, name: str) -> str:
            normalized = name.casefold()
            entries = os.listdir(directory)
            for entry in entries:
                if entry.casefold() == normalized:
                    return entry

            return name  # no cov

    else:

        @staticmethod
        def get_raw_fs_path_name(directory: str, name: str) -> str:  # noqa: ARG004
            return name


class WheelBuilder(BuilderInterface):
    """
    Build a binary distribution (.whl file)
    """

    PLUGIN_NAME = "wheel"

    def get_version_api(self) -> dict[str, Callable]:
        return {"standard": self.build_standard, "editable": self.build_editable}

    def get_default_versions(self) -> list[str]:  # noqa: PLR6301
        return ["standard"]

    def clean(  # noqa: PLR6301
        self,
        directory: str,
        versions: list[str],  # noqa: ARG002
    ) -> None:
        for filename in os.listdir(directory):
            if filename.endswith(".whl"):
                os.remove(os.path.join(directory, filename))

    def build_standard(self, directory: str, **build_data: Any) -> str:
        if "tag" not in build_data:
            if build_data["infer_tag"]:
                build_data["tag"] = self.get_best_matching_tag()
            else:
                build_data["tag"] = self.get_default_tag()

        with (
            WheelArchive(self.artifact_project_id, reproducible=self.config.reproducible) as archive,
            RecordFile() as records,
        ):
            for included_file in self.recurse_included_files():
                record = archive.add_file(included_file)
                records.write(record)

            self.write_data(archive, records, build_data, build_data["dependencies"])

            records.write((f"{archive.metadata_directory}/RECORD", "", ""))
            archive.write_metadata("RECORD", records.construct())

        target = os.path.join(directory, f"{self.artifact_project_id}-{build_data['tag']}.whl")

        replace_file(archive.path, target)
        normalize_artifact_permissions(target)
        return target

    def build_editable(self, directory: str, **build_data: Any) -> str:
        if self.config.dev_mode_dirs:
            return self.build_editable_explicit(directory, **build_data)

        return self.build_editable_detection(directory, **build_data)

    def build_editable_detection(self, directory: str, **build_data: Any) -> str:
        from editables import EditableProject

        build_data["tag"] = self.get_default_tag()

        with (
            WheelArchive(self.artifact_project_id, reproducible=self.config.reproducible) as archive,
            RecordFile() as records,
        ):
            exposed_packages = {}
            for included_file in self.recurse_selected_project_files():
                if not included_file.path.endswith(".py"):
                    continue

                relative_path = included_file.relative_path
                distribution_path = included_file.distribution_path
                path_parts = relative_path.split(os.sep)

                # Root file
                if len(path_parts) == 1:  # no cov
                    exposed_packages[os.path.splitext(relative_path)[0]] = os.path.join(self.root, relative_path)
                    continue

                # Root package
                root_module = path_parts[0]
                if distribution_path == relative_path:
                    exposed_packages[root_module] = os.path.join(self.root, root_module)
                else:
                    distribution_module = distribution_path.split(os.sep)[0]
                    try:
                        exposed_packages[distribution_module] = os.path.join(
                            self.root,
                            f"{relative_path[: relative_path.index(distribution_path)]}{distribution_module}",
                        )
                    except ValueError:
                        message = (
                            "Dev mode installations are unsupported when any path rewrite in the `sources` option "
                            "changes a prefix rather than removes it, see: "
                            "https://github.com/pfmoore/editables/issues/20"
                        )
                        raise ValueError(message) from None

            editable_project = EditableProject(self.metadata.core.name, self.root)

            if self.config.dev_mode_exact:
                for module, relative_path in exposed_packages.items():
                    editable_project.map(module, relative_path)
            else:
                for relative_path in exposed_packages.values():
                    editable_project.add_to_path(os.path.dirname(relative_path))

            for raw_filename, content in sorted(editable_project.files()):
                filename = raw_filename
                if filename.endswith(".pth") and not filename.startswith("_"):
                    filename = f"_{filename}"

                record = archive.write_file(filename, content)
                records.write(record)

            for included_file in self.recurse_forced_files(self.get_forced_inclusion_map(build_data)):
                record = archive.add_file(included_file)
                records.write(record)

            extra_dependencies = list(build_data["dependencies"])
            for raw_dependency in editable_project.dependencies():
                dependency = raw_dependency
                if dependency == "editables":
                    dependency = EDITABLES_REQUIREMENT
                else:  # no cov
                    pass

                extra_dependencies.append(dependency)

            self.write_data(archive, records, build_data, extra_dependencies)

            records.write((f"{archive.metadata_directory}/RECORD", "", ""))
            archive.write_metadata("RECORD", records.construct())

        target = os.path.join(directory, f"{self.artifact_project_id}-{build_data['tag']}.whl")

        replace_file(archive.path, target)
        normalize_artifact_permissions(target)
        return target

    def build_editable_explicit(self, directory: str, **build_data: Any) -> str:
        build_data["tag"] = self.get_default_tag()

        with (
            WheelArchive(self.artifact_project_id, reproducible=self.config.reproducible) as archive,
            RecordFile() as records,
        ):
            directories = sorted(
                os.path.normpath(os.path.join(self.root, relative_directory))
                for relative_directory in self.config.dev_mode_dirs
            )

            record = archive.write_file(f"_{self.metadata.core.name.replace('-', '_')}.pth", "\n".join(directories))
            records.write(record)

            for included_file in self.recurse_forced_files(self.get_forced_inclusion_map(build_data)):
                record = archive.add_file(included_file)
                records.write(record)

            self.write_data(archive, records, build_data, build_data["dependencies"])

            records.write((f"{archive.metadata_directory}/RECORD", "", ""))
            archive.write_metadata("RECORD", records.construct())

        target = os.path.join(directory, f"{self.artifact_project_id}-{build_data['tag']}.whl")

        replace_file(archive.path, target)
        normalize_artifact_permissions(target)
        return target

    def write_data(
        self, archive: WheelArchive, records: RecordFile, build_data: dict[str, Any], extra_dependencies: Sequence[str]
    ) -> None:
        self.add_shared_data(archive, records, build_data)
        self.add_shared_scripts(archive, records, build_data)

        # Ensure metadata is written last, see https://peps.python.org/pep-0427/#recommended-archiver-features
        self.write_metadata(archive, records, build_data, extra_dependencies=extra_dependencies)

    def add_shared_data(self, archive: WheelArchive, records: RecordFile, build_data: dict[str, Any]) -> None:
        shared_data = dict(self.config.shared_data)
        shared_data.update(normalize_inclusion_map(build_data["shared_data"], self.root))

        for shared_file in self.recurse_explicit_files(shared_data):
            record = archive.add_shared_file(shared_file)
            records.write(record)

    def add_shared_scripts(self, archive: WheelArchive, records: RecordFile, build_data: dict[str, Any]) -> None:
        import re
        from io import BytesIO

        # https://packaging.python.org/en/latest/specifications/binary-distribution-format/#recommended-installer-features
        shebang = re.compile(rb"^#!.*(?:pythonw?|pypyw?)[0-9.]*(.*)", flags=re.DOTALL)

        shared_scripts = dict(self.config.shared_scripts)
        shared_scripts.update(normalize_inclusion_map(build_data["shared_scripts"], self.root))

        for shared_script in self.recurse_explicit_files(shared_scripts):
            with open(shared_script.path, "rb") as f:
                content = BytesIO()
                for line in f:
                    # Ignore leading blank lines
                    if not line.strip():
                        continue

                    match = shebang.match(line)
                    if match is None:
                        content.write(line)
                    else:
                        content.write(b"#!python")
                        if remaining := match.group(1):
                            content.write(remaining)

                    content.write(f.read())
                    break

            record = archive.write_shared_script(shared_script, content.getvalue())
            records.write(record)

    def add_sboms(self, archive: WheelArchive, records: RecordFile, build_data: dict[str, Any]) -> None:
        sbom_files = self.config.sbom_files
        sbom_files.extend(build_data["sbom_files"])
        if not sbom_files:
            return

        for sbom_file in sbom_files:
            sbom_path = os.path.join(self.root, sbom_file)
            if not os.path.isfile(sbom_path):
                message = f"SBOM file not found: {sbom_file}"
                raise FileNotFoundError(message)

        sbom_map = {os.path.join(self.root, sbom_file): os.path.basename(sbom_file) for sbom_file in sbom_files}

        for included_file in self.recurse_explicit_files(sbom_map):
            record = archive.add_sbom_file(included_file)
            records.write(record)

    def write_metadata(
        self,
        archive: WheelArchive,
        records: RecordFile,
        build_data: dict[str, Any],
        extra_dependencies: Sequence[str] = (),
    ) -> None:
        # <<< IMPORTANT >>>
        # Ensure calls are ordered by the number of path components followed by the name of the components

        # METADATA
        self.write_project_metadata(archive, records, extra_dependencies=extra_dependencies)

        # WHEEL
        self.write_archive_metadata(archive, records, build_data)

        # entry_points.txt
        self.write_entry_points_file(archive, records)

        # licenses/
        self.add_licenses(archive, records)

        # sboms/
        self.add_sboms(archive, records, build_data)

        # extra_metadata/ - write last
        self.add_extra_metadata(archive, records, build_data)

    @staticmethod
    def write_archive_metadata(archive: WheelArchive, records: RecordFile, build_data: dict[str, Any]) -> None:
        from packaging.tags import parse_tag

        metadata = f"""\
Wheel-Version: 1.0
Generator: hatchling {__version__}
Root-Is-Purelib: {"true" if build_data["pure_python"] else "false"}
"""

        for tag in sorted(map(str, parse_tag(build_data["tag"]))):
            metadata += f"Tag: {tag}\n"

        record = archive.write_metadata("WHEEL", metadata)
        records.write(record)

    def write_entry_points_file(self, archive: WheelArchive, records: RecordFile) -> None:
        entry_points_file = self.construct_entry_points_file()
        if entry_points_file:
            record = archive.write_metadata("entry_points.txt", entry_points_file)
            records.write(record)

    def write_project_metadata(
        self, archive: WheelArchive, records: RecordFile, extra_dependencies: Sequence[str] = ()
    ) -> None:
        record = archive.write_metadata(
            "METADATA", self.config.core_metadata_constructor(self.metadata, extra_dependencies=extra_dependencies)
        )
        records.write(record)

    def add_licenses(self, archive: WheelArchive, records: RecordFile) -> None:
        for relative_path in self.metadata.core.license_files:
            license_file = os.path.normpath(os.path.join(self.root, relative_path))
            with open(license_file, "rb") as f:
                record = archive.write_metadata(f"licenses/{relative_path}", f.read())
                records.write(record)

    def add_extra_metadata(self, archive: WheelArchive, records: RecordFile, build_data: dict[str, Any]) -> None:
        extra_metadata = dict(self.config.extra_metadata)
        extra_metadata.update(normalize_inclusion_map(build_data["extra_metadata"], self.root))

        for extra_metadata_file in self.recurse_explicit_files(extra_metadata):
            record = archive.add_extra_metadata_file(extra_metadata_file)
            records.write(record)

    def construct_entry_points_file(self) -> str:
        core_metadata = self.metadata.core
        metadata_file = ""

        if core_metadata.scripts:
            metadata_file += "\n[console_scripts]\n"
            for name, object_ref in core_metadata.scripts.items():
                metadata_file += f"{name} = {object_ref}\n"

        if core_metadata.gui_scripts:
            metadata_file += "\n[gui_scripts]\n"
            for name, object_ref in core_metadata.gui_scripts.items():
                metadata_file += f"{name} = {object_ref}\n"

        if core_metadata.entry_points:
            for group, entry_points in core_metadata.entry_points.items():
                metadata_file += f"\n[{group}]\n"
                for name, object_ref in entry_points.items():
                    metadata_file += f"{name} = {object_ref}\n"

        return metadata_file.lstrip()

    def get_default_tag(self) -> str:
        known_major_versions = list(get_known_python_major_versions())
        max_version_part = 100
        supported_python_versions = []
        for major_version in known_major_versions:
            for minor_version in range(max_version_part):
                # Try an artificially high patch version to account for common cases like `>=3.11.4` or `>=3.10,<3.11`
                if self.metadata.core.python_constraint.contains(f"{major_version}.{minor_version}.{max_version_part}"):
                    supported_python_versions.append(f"py{major_version}")
                    break

        # Slow path, try all permutations to account for narrow support ranges like `<=3.11.4`
        if not supported_python_versions:
            for major_version in known_major_versions:
                for minor_version in range(max_version_part):
                    for patch_version in range(max_version_part):
                        if self.metadata.core.python_constraint.contains(
                            f"{major_version}.{minor_version}.{patch_version}"
                        ):
                            supported_python_versions.append(f"py{major_version}")
                            break
                    else:
                        continue
                    break

        return f"{'.'.join(supported_python_versions)}-none-any"

    def get_best_matching_tag(self) -> str:
        import sys

        from packaging.tags import sys_tags

        # Linux tag is after many/musl; packaging tools are required to skip
        # many/musl, see https://github.com/pypa/packaging/issues/160
        tag = next(iter(t for t in sys_tags() if "manylinux" not in t.platform and "musllinux" not in t.platform))
        tag_parts = [tag.interpreter, tag.abi, tag.platform]

        if sys.platform == "darwin":
            from hatchling.builders.macos import process_macos_plat_tag

            tag_parts[2] = process_macos_plat_tag(tag_parts[2], compat=self.config.macos_max_compat)

        return "-".join(tag_parts)

    def get_default_build_data(self) -> dict[str, Any]:  # noqa: PLR6301
        return {
            "infer_tag": False,
            "pure_python": True,
            "dependencies": [],
            "force_include_editable": {},
            "extra_metadata": {},
            "shared_data": {},
            "shared_scripts": {},
            "sbom_files": [],
        }

    def get_forced_inclusion_map(self, build_data: dict[str, Any]) -> dict[str, str]:
        if not build_data["force_include_editable"]:
            return self.config.get_force_include()

        return normalize_inclusion_map(build_data["force_include_editable"], self.root)

    @property
    def artifact_project_id(self) -> str:
        return (
            self.project_id
            if self.config.strict_naming
            else f"{self.normalize_file_name_component(self.metadata.core.raw_name)}-{self.metadata.version}"
        )

    @classmethod
    def get_config_class(cls) -> type[WheelBuilderConfig]:
        return WheelBuilderConfig


================================================
FILE: backend/src/hatchling/cli/__init__.py
================================================
import argparse

from hatchling.cli.build import build_command
from hatchling.cli.dep import dep_command
from hatchling.cli.metadata import metadata_command
from hatchling.cli.version import version_command


def hatchling() -> int:
    parser = argparse.ArgumentParser(prog="hatchling", allow_abbrev=False)
    subparsers = parser.add_subparsers()

    defaults = {"metavar": ""}

    build_command(subparsers, defaults)
    dep_command(subparsers, defaults)
    metadata_command(subparsers, defaults)
    version_command(subparsers, defaults)

    kwargs = vars(parser.parse_args())
    try:
        command = kwargs.pop("func")
    except KeyError:
        parser.print_help()
    else:
        command(**kwargs)

    return 0


================================================
FILE: backend/src/hatchling/cli/build/__init__.py
================================================
from __future__ import annotations

import argparse
from typing import Any


def build_impl(
    *,
    called_by_app: bool,  # noqa: ARG001
    directory: str,
    targets: list[str],
    hooks_only: bool,
    no_hooks: bool,
    clean: bool,
    clean_hooks_after: bool,
    clean_only: bool,
    show_dynamic_deps: bool,
) -> None:
    import os

    from hatchling.bridge.app import Application
    from hatchling.builders.constants import BuildEnvVars
    from hatchling.metadata.core import ProjectMetadata
    from hatchling.plugin.manager import PluginManager

    app = Application()

    if hooks_only and no_hooks:
        app.abort("Cannot use both --hooks-only and --no-hooks together")

    root = os.getcwd()
    plugin_manager = PluginManager()
    metadata = ProjectMetadata(root, plugin_manager)

    target_data: dict[str, Any] = {}
    if targets:
        for data in targets:
            target_name, _, version_data = data.partition(":")
            versions = version_data.split(",") if version_data else []
            target_data.setdefault(target_name, []).extend(versions)
    else:  # no cov
        target_data["sdist"] = []
        target_data["wheel"] = []

    builders = {}
    unknown_targets = []
    for target_name in target_data:
        builder_class = plugin_manager.builder.get(target_name)
        if builder_class is None:
            unknown_targets.append(target_name)
        else:
            builders[target_name] = builder_class

    if unknown_targets:
        app.abort(f"Unknown build targets: {', '.join(sorted(unknown_targets))}")

    # We guarantee that builds occur within the project directory
    root = os.getcwd()

    if no_hooks:
        os.environ[BuildEnvVars.NO_HOOKS] = "true"

    dynamic_dependencies: dict[str, None] = {}
    for i, (target_name, versions) in enumerate(target_data.items()):
        # Separate targets with a blank line
        if not (clean_only or show_dynamic_deps) and i != 0:  # no cov
            app.display_info()

        builder_class = builders[target_name]

        # Display name before instantiation in case of errors
        if not (clean_only or show_dynamic_deps) and len(target_data) > 1:
            app.display_mini_header(target_name)

        builder = builder_class(root, plugin_manager=plugin_manager, metadata=metadata, app=app.get_safe_application())
        if show_dynamic_deps:
            for dependency in builder.config.dynamic_dependencies:
                dynamic_dependencies[dependency] = None

            continue

        for artifact in builder.build(
            directory=directory,
            versions=versions,
            hooks_only=hooks_only,
            clean=clean,
            clean_hooks_after=clean_hooks_after,
            clean_only=clean_only,
        ):
            if os.path.isfile(artifact) and artifact.startswith(root):
                app.display_info(os.path.relpath(artifact, root))
            else:  # no cov
                app.display_info(artifact)

    if show_dynamic_deps:
        app.display(str(list(dynamic_dependencies)))


def build_command(subparsers: argparse._SubParsersAction, defaults: Any) -> None:
    parser = subparsers.add_parser("build")
    parser.add_argument(
        "-d", "--directory", dest="directory", help="The directory in which to build artifacts", **defaults
    )
    parser.add_argument(
        "-t",
        "--target",
        dest="targets",
        action="append",
        help="Comma-separated list of targets to build, overriding project defaults",
        **defaults,
    )
    parser.add_argument("--hooks-only", dest="hooks_only", action="store_true", default=None)
    parser.add_argument("--no-hooks", dest="no_hooks", action="store_true", default=None)
    parser.add_argument("-c", "--clean", dest="clean", action="store_true", default=None)
    parser.add_argument("--clean-hooks-after", dest="clean_hooks_after", action="store_true", default=None)
    parser.add_argument("--clean-only", dest="clean_only", action="store_true")
    parser.add_argument("--show-dynamic-deps", dest="show_dynamic_deps", action="store_true")
    parser.add_argument("--app", dest="called_by_app", action="store_true", help=argparse.SUPPRESS)
    parser.set_defaults(func=build_impl)


================================================
FILE: backend/src/hatchling/cli/dep/__init__.py
================================================
from __future__ import annotations

import sys
from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
    import argparse


def synced_impl(*, dependencies: list[str], python: str) -> None:
    import subprocess
    from ast import literal_eval

    from packaging.requirements import Requirement

    from hatchling.cli.dep.core import dependencies_in_sync

    sys_path = None
    if python:
        output = subprocess.check_output([python, "-c", "import sys;print([path for path in sys.path if path])"])
        sys_path = literal_eval(output.strip().decode("utf-8"))

    sys.exit(0 if dependencies_in_sync(list(map(Requirement, dependencies)), sys_path) else 1)


def synced_command(subparsers: argparse._SubParsersAction, defaults: Any) -> None:
    parser = subparsers.add_parser("synced")
    parser.add_argument("dependencies", nargs="+")
    parser.add_argument("-p", "--python", dest="python", **defaults)
    parser.set_defaults(func=synced_impl)


def dep_command(subparsers: argparse._SubParsersAction, defaults: Any) -> None:
    parser = subparsers.add_parser("dep")
    subparsers = parser.add_subparsers()

    synced_command(subparsers, defaults)


================================================
FILE: backend/src/hatchling/cli/dep/core.py
================================================
from __future__ import annotations

import re
import sys
from importlib.metadata import Distribution, DistributionFinder

from packaging.markers import default_environment
from packaging.requirements import Requirement


class DistributionCache:
    def __init__(self, sys_path: list[str]) -> None:
        self._resolver = Distribution.discover(context=DistributionFinder.Context(path=sys_path))
        self._distributions: dict[str, Distribution] = {}
        self._search_exhausted = False
        self._canonical_regex = re.compile(r"[-_.]+")

    def __getitem__(self, item: str) -> Distribution | None:
        item = self._canonical_regex.sub("-", item).lower()
        possible_distribution = self._distributions.get(item)
        if possible_distribution is not None:
            return possible_distribution

        # Be safe even though the code as-is will never rea
Download .txt
gitextract_qo3g_3ii/

├── .gitattributes
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── 1-hatch_bug_report.yml
│   │   └── 2-feature_request.yml
│   ├── dependabot.yml
│   └── workflows/
│       ├── auto-merge.yml
│       ├── build-distributions.yml
│       ├── build-hatch.yml
│       ├── build-hatchling.yml
│       ├── cli.yml
│       ├── docs-dev.yml
│       ├── docs-release.yml
│       └── test.yml
├── .gitignore
├── .linkcheckerrc
├── LICENSE.txt
├── README.md
├── backend/
│   ├── LICENSE.txt
│   ├── README.md
│   ├── pyproject.toml
│   ├── src/
│   │   └── hatchling/
│   │       ├── __about__.py
│   │       ├── __init__.py
│   │       ├── __main__.py
│   │       ├── bridge/
│   │       │   ├── __init__.py
│   │       │   └── app.py
│   │       ├── build.py
│   │       ├── builders/
│   │       │   ├── __init__.py
│   │       │   ├── app.py
│   │       │   ├── binary.py
│   │       │   ├── config.py
│   │       │   ├── constants.py
│   │       │   ├── custom.py
│   │       │   ├── hooks/
│   │       │   │   ├── __init__.py
│   │       │   │   ├── custom.py
│   │       │   │   ├── plugin/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── hooks.py
│   │       │   │   │   └── interface.py
│   │       │   │   └── version.py
│   │       │   ├── macos.py
│   │       │   ├── plugin/
│   │       │   │   ├── __init__.py
│   │       │   │   ├── hooks.py
│   │       │   │   └── interface.py
│   │       │   ├── sdist.py
│   │       │   ├── utils.py
│   │       │   └── wheel.py
│   │       ├── cli/
│   │       │   ├── __init__.py
│   │       │   ├── build/
│   │       │   │   └── __init__.py
│   │       │   ├── dep/
│   │       │   │   ├── __init__.py
│   │       │   │   └── core.py
│   │       │   ├── metadata/
│   │       │   │   └── __init__.py
│   │       │   └── version/
│   │       │       └── __init__.py
│   │       ├── dep/
│   │       │   ├── __init__.py
│   │       │   └── core.py
│   │       ├── licenses/
│   │       │   ├── __init__.py
│   │       │   └── supported.py
│   │       ├── metadata/
│   │       │   ├── __init__.py
│   │       │   ├── core.py
│   │       │   ├── custom.py
│   │       │   ├── plugin/
│   │       │   │   ├── __init__.py
│   │       │   │   ├── hooks.py
│   │       │   │   └── interface.py
│   │       │   ├── spec.py
│   │       │   └── utils.py
│   │       ├── ouroboros.py
│   │       ├── plugin/
│   │       │   ├── __init__.py
│   │       │   ├── exceptions.py
│   │       │   ├── manager.py
│   │       │   ├── specs.py
│   │       │   └── utils.py
│   │       ├── py.typed
│   │       ├── utils/
│   │       │   ├── __init__.py
│   │       │   ├── constants.py
│   │       │   ├── context.py
│   │       │   └── fs.py
│   │       └── version/
│   │           ├── __init__.py
│   │           ├── core.py
│   │           ├── scheme/
│   │           │   ├── __init__.py
│   │           │   ├── plugin/
│   │           │   │   ├── __init__.py
│   │           │   │   ├── hooks.py
│   │           │   │   └── interface.py
│   │           │   └── standard.py
│   │           └── source/
│   │               ├── __init__.py
│   │               ├── code.py
│   │               ├── env.py
│   │               ├── plugin/
│   │               │   ├── __init__.py
│   │               │   ├── hooks.py
│   │               │   └── interface.py
│   │               └── regex.py
│   └── tests/
│       ├── __init__.py
│       └── downstream/
│           ├── datadogpy/
│           │   ├── data.json
│           │   └── pyproject.toml
│           ├── hatch-showcase/
│           │   └── data.json
│           ├── integrate.py
│           └── requirements.txt
├── docs/
│   ├── .hooks/
│   │   ├── expand_blocks.py
│   │   ├── inject_version.py
│   │   ├── plugin_register.py
│   │   ├── render_default_test_env.py
│   │   ├── render_ruff_defaults.py
│   │   └── title_from_content.py
│   ├── .overrides/
│   │   └── partials/
│   │       └── copyright.html
│   ├── .snippets/
│   │   ├── abbrs.txt
│   │   └── links.txt
│   ├── assets/
│   │   ├── badge/
│   │   │   └── v0.json
│   │   └── css/
│   │       └── custom.css
│   ├── blog/
│   │   ├── .authors.yml
│   │   ├── index.md
│   │   └── posts/
│   │       ├── release-hatch-1100.md
│   │       ├── release-hatch-1160.md
│   │       ├── release-hatch-160.md
│   │       ├── release-hatch-180.md
│   │       └── release-hatch-190.md
│   ├── build.md
│   ├── cli/
│   │   ├── about.md
│   │   └── reference.md
│   ├── community/
│   │   ├── contributing.md
│   │   ├── highlights.md
│   │   └── users.md
│   ├── config/
│   │   ├── build.md
│   │   ├── context.md
│   │   ├── dependency.md
│   │   ├── environment/
│   │   │   ├── advanced.md
│   │   │   └── overview.md
│   │   ├── hatch.md
│   │   ├── internal/
│   │   │   ├── build.md
│   │   │   ├── static-analysis.md
│   │   │   └── testing.md
│   │   ├── metadata.md
│   │   └── project-templates.md
│   ├── environment.md
│   ├── history/
│   │   ├── hatch.md
│   │   └── hatchling.md
│   ├── how-to/
│   │   ├── config/
│   │   │   └── dynamic-metadata.md
│   │   ├── environment/
│   │   │   ├── dependency-resolution.md
│   │   │   ├── select-installer.md
│   │   │   └── workspace.md
│   │   ├── integrate/
│   │   │   └── vscode.md
│   │   ├── meta/
│   │   │   └── report-issues.md
│   │   ├── plugins/
│   │   │   └── testing-builds.md
│   │   ├── publish/
│   │   │   ├── auth.md
│   │   │   └── repo.md
│   │   ├── python/
│   │   │   └── custom.md
│   │   ├── run/
│   │   │   └── python-scripts.md
│   │   └── static-analysis/
│   │       └── behavior.md
│   ├── index.md
│   ├── install.md
│   ├── intro.md
│   ├── meta/
│   │   ├── authors.md
│   │   └── faq.md
│   ├── next-steps.md
│   ├── plugins/
│   │   ├── about.md
│   │   ├── build-hook/
│   │   │   ├── custom.md
│   │   │   ├── reference.md
│   │   │   └── version.md
│   │   ├── builder/
│   │   │   ├── binary.md
│   │   │   ├── custom.md
│   │   │   ├── reference.md
│   │   │   ├── sdist.md
│   │   │   └── wheel.md
│   │   ├── environment/
│   │   │   ├── reference.md
│   │   │   └── virtual.md
│   │   ├── environment-collector/
│   │   │   ├── custom.md
│   │   │   ├── default.md
│   │   │   └── reference.md
│   │   ├── metadata-hook/
│   │   │   ├── custom.md
│   │   │   └── reference.md
│   │   ├── publisher/
│   │   │   ├── package-index.md
│   │   │   └── reference.md
│   │   ├── utilities.md
│   │   ├── version-scheme/
│   │   │   ├── reference.md
│   │   │   └── standard.md
│   │   └── version-source/
│   │       ├── code.md
│   │       ├── env.md
│   │       ├── reference.md
│   │       └── regex.md
│   ├── publish.md
│   ├── tutorials/
│   │   ├── environment/
│   │   │   └── basic-usage.md
│   │   ├── python/
│   │   │   └── manage.md
│   │   └── testing/
│   │       └── overview.md
│   ├── version.md
│   └── why.md
├── hatch.toml
├── mkdocs.insiders.yml
├── mkdocs.yml
├── pyoxidizer.bzl
├── pyproject.toml
├── release/
│   ├── README.md
│   ├── macos/
│   │   ├── build_pkg.py
│   │   └── pkg/
│   │       └── distribution.xml
│   ├── unix/
│   │   └── make_scripts_portable.py
│   └── windows/
│       └── make_scripts_portable.py
├── ruff.toml
├── ruff_defaults.toml
├── scripts/
│   ├── bump.py
│   ├── generate_coverage_summary.py
│   ├── install_mkdocs_material_insiders.py
│   ├── release_github.py
│   ├── set_release_version.py
│   ├── update_distributions.py
│   ├── update_ruff.py
│   ├── utils.py
│   ├── validate_history.py
│   └── write_coverage_summary_report.py
├── src/
│   └── hatch/
│       ├── __init__.py
│       ├── __main__.py
│       ├── cli/
│       │   ├── __init__.py
│       │   ├── application.py
│       │   ├── build/
│       │   │   └── __init__.py
│       │   ├── clean/
│       │   │   └── __init__.py
│       │   ├── config/
│       │   │   └── __init__.py
│       │   ├── dep/
│       │   │   └── __init__.py
│       │   ├── env/
│       │   │   ├── __init__.py
│       │   │   ├── create.py
│       │   │   ├── find.py
│       │   │   ├── prune.py
│       │   │   ├── remove.py
│       │   │   ├── run.py
│       │   │   └── show.py
│       │   ├── fmt/
│       │   │   ├── __init__.py
│       │   │   └── core.py
│       │   ├── new/
│       │   │   ├── __init__.py
│       │   │   └── migrate.py
│       │   ├── project/
│       │   │   ├── __init__.py
│       │   │   └── metadata.py
│       │   ├── publish/
│       │   │   └── __init__.py
│       │   ├── python/
│       │   │   ├── __init__.py
│       │   │   ├── find.py
│       │   │   ├── install.py
│       │   │   ├── remove.py
│       │   │   ├── show.py
│       │   │   └── update.py
│       │   ├── run/
│       │   │   └── __init__.py
│       │   ├── self/
│       │   │   ├── __init__.py
│       │   │   ├── report.py
│       │   │   ├── restore.py
│       │   │   └── update.py
│       │   ├── shell/
│       │   │   └── __init__.py
│       │   ├── status/
│       │   │   └── __init__.py
│       │   ├── terminal.py
│       │   ├── test/
│       │   │   ├── __init__.py
│       │   │   └── core.py
│       │   └── version/
│       │       └── __init__.py
│       ├── config/
│       │   ├── __init__.py
│       │   ├── constants.py
│       │   ├── model.py
│       │   ├── user.py
│       │   └── utils.py
│       ├── dep/
│       │   ├── __init__.py
│       │   ├── core.py
│       │   └── sync.py
│       ├── env/
│       │   ├── __init__.py
│       │   ├── collectors/
│       │   │   ├── __init__.py
│       │   │   ├── custom.py
│       │   │   ├── default.py
│       │   │   └── plugin/
│       │   │       ├── __init__.py
│       │   │       ├── hooks.py
│       │   │       └── interface.py
│       │   ├── context.py
│       │   ├── internal/
│       │   │   ├── __init__.py
│       │   │   ├── build.py
│       │   │   ├── static_analysis.py
│       │   │   ├── test.py
│       │   │   └── uv.py
│       │   ├── plugin/
│       │   │   ├── __init__.py
│       │   │   ├── hooks.py
│       │   │   └── interface.py
│       │   ├── system.py
│       │   ├── utils.py
│       │   └── virtual.py
│       ├── errors/
│       │   └── __init__.py
│       ├── index/
│       │   ├── __init__.py
│       │   ├── core.py
│       │   ├── errors.py
│       │   └── publish.py
│       ├── plugin/
│       │   ├── __init__.py
│       │   ├── constants.py
│       │   ├── manager.py
│       │   ├── specs.py
│       │   └── utils.py
│       ├── project/
│       │   ├── __init__.py
│       │   ├── config.py
│       │   ├── constants.py
│       │   ├── core.py
│       │   ├── env.py
│       │   ├── frontend/
│       │   │   ├── __init__.py
│       │   │   ├── core.py
│       │   │   └── scripts/
│       │   │       ├── __init__.py
│       │   │       ├── build_deps.py
│       │   │       ├── core_metadata.py
│       │   │       └── standard.py
│       │   └── utils.py
│       ├── publish/
│       │   ├── __init__.py
│       │   ├── auth.py
│       │   ├── index.py
│       │   └── plugin/
│       │       ├── __init__.py
│       │       ├── hooks.py
│       │       └── interface.py
│       ├── py.typed
│       ├── python/
│       │   ├── __init__.py
│       │   ├── core.py
│       │   ├── distributions.py
│       │   └── resolve.py
│       ├── template/
│       │   ├── __init__.py
│       │   ├── default.py
│       │   ├── files_default.py
│       │   ├── files_feature_ci.py
│       │   ├── files_feature_cli.py
│       │   ├── files_feature_tests.py
│       │   └── plugin/
│       │       ├── __init__.py
│       │       ├── hooks.py
│       │       └── interface.py
│       ├── utils/
│       │   ├── __init__.py
│       │   ├── ci.py
│       │   ├── dep.py
│       │   ├── env.py
│       │   ├── fs.py
│       │   ├── metadata.py
│       │   ├── network.py
│       │   ├── platform.py
│       │   ├── runner.py
│       │   ├── shells.py
│       │   ├── structures.py
│       │   └── toml.py
│       └── venv/
│           ├── __init__.py
│           ├── core.py
│           └── utils.py
└── tests/
    ├── __init__.py
    ├── backend/
    │   ├── __init__.py
    │   ├── builders/
    │   │   ├── __init__.py
    │   │   ├── hooks/
    │   │   │   ├── __init__.py
    │   │   │   ├── test_custom.py
    │   │   │   └── test_version.py
    │   │   ├── plugin/
    │   │   │   ├── __init__.py
    │   │   │   └── test_interface.py
    │   │   ├── test_binary.py
    │   │   ├── test_config.py
    │   │   ├── test_custom.py
    │   │   ├── test_sdist.py
    │   │   ├── test_wheel.py
    │   │   └── utils.py
    │   ├── metadata/
    │   │   ├── __init__.py
    │   │   ├── test_build.py
    │   │   ├── test_core.py
    │   │   ├── test_custom_hook.py
    │   │   ├── test_hatch.py
    │   │   └── test_spec.py
    │   ├── test_build.py
    │   ├── utils/
    │   │   ├── __init__.py
    │   │   ├── test_context.py
    │   │   ├── test_fs.py
    │   │   └── test_macos.py
    │   └── version/
    │       ├── __init__.py
    │       ├── scheme/
    │       │   ├── __init__.py
    │       │   └── test_standard.py
    │       └── source/
    │           ├── __init__.py
    │           ├── test_code.py
    │           ├── test_env.py
    │           └── test_regex.py
    ├── cli/
    │   ├── __init__.py
    │   ├── build/
    │   │   ├── __init__.py
    │   │   └── test_build.py
    │   ├── clean/
    │   │   ├── __init__.py
    │   │   └── test_clean.py
    │   ├── config/
    │   │   ├── __init__.py
    │   │   ├── test_explore.py
    │   │   ├── test_find.py
    │   │   ├── test_restore.py
    │   │   ├── test_set.py
    │   │   └── test_show.py
    │   ├── dep/
    │   │   ├── __init__.py
    │   │   ├── show/
    │   │   │   ├── __init__.py
    │   │   │   ├── test_requirements.py
    │   │   │   └── test_table.py
    │   │   └── test_hash.py
    │   ├── env/
    │   │   ├── __init__.py
    │   │   ├── test_create.py
    │   │   ├── test_find.py
    │   │   ├── test_prune.py
    │   │   ├── test_remove.py
    │   │   ├── test_run.py
    │   │   └── test_show.py
    │   ├── fmt/
    │   │   ├── __init__.py
    │   │   └── test_fmt.py
    │   ├── new/
    │   │   ├── __init__.py
    │   │   └── test_new.py
    │   ├── project/
    │   │   ├── __init__.py
    │   │   └── test_metadata.py
    │   ├── publish/
    │   │   ├── __init__.py
    │   │   └── test_publish.py
    │   ├── python/
    │   │   ├── __init__.py
    │   │   ├── conftest.py
    │   │   ├── test_find.py
    │   │   ├── test_install.py
    │   │   ├── test_remove.py
    │   │   ├── test_show.py
    │   │   └── test_update.py
    │   ├── run/
    │   │   ├── __init__.py
    │   │   └── test_run.py
    │   ├── self/
    │   │   ├── __init__.py
    │   │   ├── test_report.py
    │   │   └── test_self.py
    │   ├── status/
    │   │   ├── __init__.py
    │   │   └── test_status.py
    │   ├── test/
    │   │   ├── __init__.py
    │   │   └── test_test.py
    │   ├── test_root.py
    │   └── version/
    │       ├── __init__.py
    │       └── test_version.py
    ├── config/
    │   ├── __init__.py
    │   └── test_model.py
    ├── conftest.py
    ├── dep/
    │   ├── __init__.py
    │   └── test_sync.py
    ├── env/
    │   ├── __init__.py
    │   ├── collectors/
    │   │   ├── __init__.py
    │   │   └── test_custom.py
    │   └── plugin/
    │       ├── __init__.py
    │       └── test_interface.py
    ├── helpers/
    │   ├── __init__.py
    │   ├── helpers.py
    │   └── templates/
    │       ├── __init__.py
    │       ├── licenses/
    │       │   └── __init__.py
    │       ├── new/
    │       │   ├── __init__.py
    │       │   ├── basic.py
    │       │   ├── default.py
    │       │   ├── feature_ci.py
    │       │   ├── feature_cli.py
    │       │   ├── feature_no_src_layout.py
    │       │   ├── licenses_empty.py
    │       │   ├── licenses_multiple.py
    │       │   ├── projects_urls_empty.py
    │       │   └── projects_urls_space_in_label.py
    │       ├── sdist/
    │       │   ├── __init__.py
    │       │   ├── standard_default.py
    │       │   ├── standard_default_build_script_artifacts.py
    │       │   ├── standard_default_build_script_extra_dependencies.py
    │       │   ├── standard_default_support_legacy.py
    │       │   ├── standard_default_vcs_git_exclusion_files.py
    │       │   ├── standard_default_vcs_mercurial_exclusion_files.py
    │       │   ├── standard_include.py
    │       │   └── standard_include_config_file.py
    │       └── wheel/
    │           ├── __init__.py
    │           ├── standard_default_build_script.py
    │           ├── standard_default_build_script_artifacts.py
    │           ├── standard_default_build_script_artifacts_with_src_layout.py
    │           ├── standard_default_build_script_configured_build_hooks.py
    │           ├── standard_default_build_script_extra_dependencies.py
    │           ├── standard_default_build_script_force_include.py
    │           ├── standard_default_build_script_force_include_no_duplication.py
    │           ├── standard_default_extra_metadata.py
    │           ├── standard_default_license_multiple.py
    │           ├── standard_default_license_single.py
    │           ├── standard_default_namespace_package.py
    │           ├── standard_default_python_constraint.py
    │           ├── standard_default_python_constraint_three_components.py
    │           ├── standard_default_sbom.py
    │           ├── standard_default_shared_data.py
    │           ├── standard_default_shared_scripts.py
    │           ├── standard_default_single_module.py
    │           ├── standard_default_symlink.py
    │           ├── standard_editable_exact.py
    │           ├── standard_editable_exact_extra_dependencies.py
    │           ├── standard_editable_exact_force_include.py
    │           ├── standard_editable_pth.py
    │           ├── standard_editable_pth_extra_dependencies.py
    │           ├── standard_editable_pth_force_include.py
    │           ├── standard_entry_points.py
    │           ├── standard_no_strict_naming.py
    │           ├── standard_only_packages_artifact_override.py
    │           ├── standard_tests.py
    │           └── utils.py
    ├── index/
    │   ├── __init__.py
    │   ├── server/
    │   │   ├── devpi/
    │   │   │   ├── Dockerfile
    │   │   │   └── entrypoint.sh
    │   │   ├── docker-compose.yaml
    │   │   └── nginx/
    │   │       └── nginx.conf
    │   └── test_core.py
    ├── project/
    │   ├── __init__.py
    │   ├── test_config.py
    │   ├── test_core.py
    │   ├── test_frontend.py
    │   └── test_utils.py
    ├── publish/
    │   ├── __init__.py
    │   └── plugin/
    │       ├── __init__.py
    │       └── test_interface.py
    ├── python/
    │   ├── __init__.py
    │   ├── test_core.py
    │   └── test_resolve.py
    ├── utils/
    │   ├── __init__.py
    │   ├── test_auth.py
    │   ├── test_fs.py
    │   ├── test_platform.py
    │   ├── test_runner.py
    │   └── test_structures.py
    ├── venv/
    │   ├── __init__.py
    │   ├── test_core.py
    │   └── test_utils.py
    └── workspaces/
        ├── __init__.py
        └── test_config.py
Download .txt
Showing preview only (327K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (3469 symbols across 290 files)

FILE: backend/src/hatchling/bridge/app.py
  class Application (line 8) | class Application:
    method __init__ (line 17) | def __init__(self) -> None:
    method verbosity (line 21) | def verbosity(self) -> int:
    method display (line 28) | def display(message: str = "", **kwargs: Any) -> None:  # noqa: ARG004
    method display_info (line 32) | def display_info(self, message: str = "", **kwargs: Any) -> None:  # n...
    method display_waiting (line 39) | def display_waiting(self, message: str = "", **kwargs: Any) -> None:  ...
    method display_success (line 46) | def display_success(self, message: str = "", **kwargs: Any) -> None:  ...
    method display_warning (line 53) | def display_warning(self, message: str = "", **kwargs: Any) -> None:  ...
    method display_error (line 60) | def display_error(self, message: str = "", **kwargs: Any) -> None:  # ...
    method display_debug (line 67) | def display_debug(self, message: str = "", level: int = 1, **kwargs: A...
    method display_mini_header (line 79) | def display_mini_header(self, message: str = "", **kwargs: Any) -> Non...
    method abort (line 83) | def abort(self, message: str = "", code: int = 1, **kwargs: Any) -> No...
    method get_safe_application (line 92) | def get_safe_application(self) -> SafeApplication:
  class SafeApplication (line 96) | class SafeApplication:
    method __init__ (line 97) | def __init__(self, app: Application) -> None:
  function _display (line 110) | def _display(message: str, *, always: bool = False) -> None:

FILE: backend/src/hatchling/build.py
  function get_requires_for_build_sdist (line 17) | def get_requires_for_build_sdist(config_settings: dict[str, Any] | None ...
  function build_sdist (line 27) | def build_sdist(sdist_directory: str, config_settings: dict[str, Any] | ...
  function get_requires_for_build_wheel (line 37) | def get_requires_for_build_wheel(config_settings: dict[str, Any] | None ...
  function build_wheel (line 47) | def build_wheel(
  function get_requires_for_build_editable (line 61) | def get_requires_for_build_editable(config_settings: dict[str, Any] | No...
  function build_editable (line 72) | def build_editable(
  function prepare_metadata_for_build_wheel (line 101) | def prepare_metadata_for_build_wheel(
  function prepare_metadata_for_build_editable (line 121) | def prepare_metadata_for_build_editable(

FILE: backend/src/hatchling/builders/app.py
  class AppBuilder (line 8) | class AppBuilder(BinaryBuilder):
    method build_bootstrap (line 11) | def build_bootstrap(

FILE: backend/src/hatchling/builders/binary.py
  class BinaryBuilderConfig (line 14) | class BinaryBuilderConfig(BuilderConfig):
    method __init__ (line 17) | def __init__(self, *args: Any, **kwargs: Any) -> None:
    method scripts (line 25) | def scripts(self) -> list[str]:
    method python_version (line 50) | def python_version(self) -> str:
    method pyapp_version (line 72) | def pyapp_version(self) -> str:
  class BinaryBuilder (line 85) | class BinaryBuilder(BuilderInterface):
    method get_version_api (line 92) | def get_version_api(self) -> dict[str, Callable]:
    method get_default_versions (line 95) | def get_default_versions(self) -> list[str]:  # noqa: PLR6301
    method clean (line 98) | def clean(
    method build_bootstrap (line 109) | def build_bootstrap(
    method cargo_build (line 188) | def cargo_build(self, *args: Any, **kwargs: Any) -> None:
    method get_config_class (line 201) | def get_config_class(cls) -> type[BinaryBuilderConfig]:

FILE: backend/src/hatchling/builders/config.py
  class BuilderConfig (line 21) | class BuilderConfig:
    method __init__ (line 22) | def __init__(
    method builder (line 46) | def builder(self) -> BuilderInterface:
    method root (line 50) | def root(self) -> str:
    method plugin_name (line 54) | def plugin_name(self) -> str:
    method build_config (line 58) | def build_config(self) -> dict[str, Any]:
    method target_config (line 62) | def target_config(self) -> dict[str, Any]:
    method include_path (line 65) | def include_path(self, relative_path: str, *, explicit: bool = False, ...
    method path_is_included (line 76) | def path_is_included(self, relative_path: str) -> bool:
    method path_is_excluded (line 82) | def path_is_excluded(self, relative_path: str) -> bool:
    method path_is_artifact (line 91) | def path_is_artifact(self, relative_path: str) -> bool:
    method path_is_build_artifact (line 97) | def path_is_build_artifact(self, relative_path: str) -> bool:
    method path_is_reserved (line 103) | def path_is_reserved(self, relative_path: str) -> bool:
    method directory_is_excluded (line 106) | def directory_is_excluded(self, name: str, relative_path: str) -> bool:
    method include_spec (line 118) | def include_spec(self) -> pathspec.GitIgnoreSpec | None:
    method exclude_spec (line 153) | def exclude_spec(self) -> pathspec.GitIgnoreSpec | None:
    method artifact_spec (line 187) | def artifact_spec(self) -> pathspec.GitIgnoreSpec | None:
    method hook_config (line 218) | def hook_config(self) -> dict[str, Any]:
    method directory (line 262) | def directory(self) -> str:
    method skip_excluded_dirs (line 277) | def skip_excluded_dirs(self) -> bool:
    method ignore_vcs (line 292) | def ignore_vcs(self) -> bool:
    method require_runtime_dependencies (line 307) | def require_runtime_dependencies(self) -> bool:
    method require_runtime_features (line 325) | def require_runtime_features(self) -> list[str]:
    method only_packages (line 361) | def only_packages(self) -> bool:
    method reproducible (line 379) | def reproducible(self) -> bool:
    method dev_mode_dirs (line 397) | def dev_mode_dirs(self) -> list[str]:
    method dev_mode_exact (line 430) | def dev_mode_exact(self) -> bool:
    method versions (line 445) | def versions(self) -> list[str]:
    method dependencies (line 486) | def dependencies(self) -> list[str]:
    method dynamic_dependencies (line 585) | def dynamic_dependencies(self) -> list[str]:
    method sources (line 606) | def sources(self) -> dict[str, str]:
    method packages (line 653) | def packages(self) -> list[str]:
    method force_include (line 678) | def force_include(self) -> dict[str, str]:
    method only_include (line 707) | def only_include(self) -> dict[str, str]:
    method get_distribution_path (line 740) | def get_distribution_path(self, relative_path: str) -> str:
    method vcs_exclusion_files (line 752) | def vcs_exclusion_files(self) -> dict[str, list[str]]:
    method load_vcs_exclusion_patterns (line 765) | def load_vcs_exclusion_patterns(self) -> list[str]:
    method normalize_build_directory (line 797) | def normalize_build_directory(self, build_directory: str) -> str:
    method default_include (line 803) | def default_include(self) -> list:  # noqa: PLR6301
    method default_exclude (line 806) | def default_exclude(self) -> list:  # noqa: PLR6301
    method default_packages (line 809) | def default_packages(self) -> list:  # noqa: PLR6301
    method default_only_include (line 812) | def default_only_include(self) -> list:  # noqa: PLR6301
    method default_global_exclude (line 815) | def default_global_exclude(self) -> list[str]:  # noqa: PLR6301
    method set_exclude_all (line 820) | def set_exclude_all(self) -> None:
    method get_force_include (line 823) | def get_force_include(self) -> dict[str, str]:
    method set_build_data (line 829) | def set_build_data(self, build_data: dict[str, Any]) -> Generator:
  function env_var_enabled (line 857) | def env_var_enabled(env_var: str, *, default: bool = False) -> bool:

FILE: backend/src/hatchling/builders/constants.py
  class BuildEnvVars (line 33) | class BuildEnvVars:

FILE: backend/src/hatchling/builders/custom.py
  class CustomBuilder (line 16) | class CustomBuilder(Generic[PluginManagerBound]):
    method __new__ (line 19) | def __new__(  # type: ignore[misc]

FILE: backend/src/hatchling/builders/hooks/custom.py
  class CustomBuildHook (line 11) | class CustomBuildHook:
    method __new__ (line 14) | def __new__(  # type: ignore[misc]

FILE: backend/src/hatchling/builders/hooks/plugin/hooks.py
  function hatch_register_build_hook (line 14) | def hatch_register_build_hook() -> list[type[BuildHookInterface]]:

FILE: backend/src/hatchling/builders/hooks/plugin/interface.py
  class BuildHookInterface (line 12) | class BuildHookInterface(Generic[BuilderConfigBound]):  # no cov
    method __init__ (line 40) | def __init__(
    method app (line 59) | def app(self) -> Application:
    method root (line 71) | def root(self) -> str:
    method config (line 78) | def config(self) -> dict[str, Any]:
    method metadata (line 90) | def metadata(self) -> ProjectMetadata:
    method build_config (line 95) | def build_config(self) -> BuilderConfigBound:
    method directory (line 102) | def directory(self) -> str:
    method target_name (line 109) | def target_name(self) -> str:
    method dependencies (line 115) | def dependencies(self) -> list[str]:  # noqa: PLR6301
    method clean (line 128) | def clean(self, versions: list[str]) -> None:
    method initialize (line 135) | def initialize(self, version: str, build_data: dict[str, Any]) -> None:
    method finalize (line 142) | def finalize(self, version: str, build_data: dict[str, Any], artifact_...

FILE: backend/src/hatchling/builders/hooks/version.py
  class VersionBuildHook (line 9) | class VersionBuildHook(BuildHookInterface):
    method __init__ (line 12) | def __init__(self, *args: Any, **kwargs: Any) -> None:
    method config_path (line 20) | def config_path(self) -> str:
    method config_template (line 36) | def config_template(self) -> str:
    method config_pattern (line 48) | def config_pattern(self) -> str | bool:
    method initialize (line 59) | def initialize(

FILE: backend/src/hatchling/builders/macos.py
  function process_macos_plat_tag (line 10) | def process_macos_plat_tag(plat: str, /, *, compat: bool) -> str:
  function normalize_macos_version (line 43) | def normalize_macos_version(version: str, *, arm: bool, compat: bool) ->...

FILE: backend/src/hatchling/builders/plugin/hooks.py
  function hatch_register_builder (line 17) | def hatch_register_builder() -> list[type[BuilderInterface]]:

FILE: backend/src/hatchling/builders/plugin/interface.py
  class IncludedFile (line 21) | class IncludedFile:
    method __init__ (line 24) | def __init__(self, path: str, relative_path: str, distribution_path: s...
  class BuilderInterface (line 30) | class BuilderInterface(ABC, Generic[BuilderConfigBound, PluginManagerBou...
    method __init__ (line 58) | def __init__(
    method build (line 81) | def build(
    method recurse_included_files (line 169) | def recurse_included_files(self) -> Iterable[IncludedFile]:
    method recurse_selected_project_files (line 181) | def recurse_selected_project_files(self) -> Iterable[IncludedFile]:
    method recurse_project_files (line 187) | def recurse_project_files(self) -> Iterable[IncludedFile]:
    method recurse_forced_files (line 209) | def recurse_forced_files(self, inclusion_map: dict[str, str]) -> Itera...
    method recurse_explicit_files (line 241) | def recurse_explicit_files(self, inclusion_map: dict[str, str]) -> Ite...
    method root (line 275) | def root(self) -> str:
    method plugin_manager (line 282) | def plugin_manager(self) -> PluginManagerBound:
    method metadata (line 291) | def metadata(self) -> ProjectMetadata:
    method app (line 300) | def app(self) -> Application:
    method raw_config (line 312) | def raw_config(self) -> dict[str, Any]:
    method project_config (line 319) | def project_config(self) -> dict[str, Any]:
    method hatch_config (line 326) | def hatch_config(self) -> dict[str, Any]:
    method config (line 333) | def config(self) -> BuilderConfigBound:
    method build_config (line 345) | def build_config(self) -> dict[str, Any]:
    method target_config (line 357) | def target_config(self) -> dict[str, Any]:
    method project_id (line 374) | def project_id(self) -> str:
    method get_build_hooks (line 380) | def get_build_hooks(self, directory: str) -> dict[str, BuildHookInterf...
    method get_version_api (line 397) | def get_version_api(self) -> dict[str, Callable]:
    method get_default_versions (line 409) | def get_default_versions(self) -> list[str]:
    method get_default_build_data (line 415) | def get_default_build_data(self) -> dict[str, Any]:  # noqa: PLR6301
    method set_build_data_defaults (line 421) | def set_build_data_defaults(self, build_data: dict[str, Any]) -> None:...
    method clean (line 425) | def clean(self, directory: str, versions: list[str]) -> None:
    method get_config_class (line 432) | def get_config_class(cls) -> type[BuilderConfig]:
    method normalize_file_name_component (line 439) | def normalize_file_name_component(file_name: str) -> str:

FILE: backend/src/hatchling/builders/sdist.py
  class SdistArchive (line 31) | class SdistArchive:
    method __init__ (line 32) | def __init__(self, name: str, *, reproducible: bool) -> None:
    method create_file (line 46) | def create_file(self, contents: str | bytes, *relative_paths: str) -> ...
    method normalize_tar_metadata (line 59) | def normalize_tar_metadata(self, tar_info: tarfile.TarInfo | None) -> ...
    method __getattr__ (line 74) | def __getattr__(self, name: str) -> Any:
    method __enter__ (line 79) | def __enter__(self) -> SdistArchive:  # noqa: PYI034
    method __exit__ (line 82) | def __exit__(
  class SdistBuilderConfig (line 90) | class SdistBuilderConfig(BuilderConfig):
    method __init__ (line 91) | def __init__(self, *args: Any, **kwargs: Any) -> None:
    method core_metadata_constructor (line 99) | def core_metadata_constructor(self) -> Callable[..., str]:
    method strict_naming (line 120) | def strict_naming(self) -> bool:
    method support_legacy (line 138) | def support_legacy(self) -> bool:
  class SdistBuilder (line 145) | class SdistBuilder(BuilderInterface):
    method get_version_api (line 152) | def get_version_api(self) -> dict[str, Callable]:
    method get_default_versions (line 155) | def get_default_versions(self) -> list[str]:  # noqa: PLR6301
    method clean (line 158) | def clean(  # noqa: PLR6301
    method build_standard (line 167) | def build_standard(self, directory: str, **build_data: Any) -> str:
    method artifact_project_id (line 211) | def artifact_project_id(self) -> str:
    method construct_setup_py_file (line 218) | def construct_setup_py_file(self, packages: list[str], extra_dependenc...
    method get_default_build_data (line 330) | def get_default_build_data(self) -> dict[str, Any]:
    method get_config_class (line 356) | def get_config_class(cls) -> type[SdistBuilderConfig]:

FILE: backend/src/hatchling/builders/utils.py
  function replace_file (line 13) | def replace_file(src: str, dst: str) -> None:
  function safe_walk (line 22) | def safe_walk(path: str) -> Iterable[tuple[str, list[str], list[str]]]:
  function get_known_python_major_versions (line 35) | def get_known_python_major_versions() -> map:
  function get_relative_path (line 39) | def get_relative_path(path: str, start: str) -> str:
  function normalize_relative_path (line 49) | def normalize_relative_path(path: str) -> str:
  function normalize_relative_directory (line 53) | def normalize_relative_directory(path: str) -> str:
  function normalize_inclusion_map (line 57) | def normalize_inclusion_map(inclusion_map: dict[str, str], root: str) ->...
  function normalize_archive_path (line 75) | def normalize_archive_path(path: str) -> str:
  function format_file_hash (line 82) | def format_file_hash(digest: bytes) -> str:
  function get_reproducible_timestamp (line 87) | def get_reproducible_timestamp() -> int:
  function normalize_file_permissions (line 97) | def normalize_file_permissions(st_mode: int) -> int:
  function normalize_artifact_permissions (line 114) | def normalize_artifact_permissions(path: str) -> None:
  function set_zip_info_mode (line 123) | def set_zip_info_mode(zip_info: ZipInfo, mode: int = 0o644) -> None:

FILE: backend/src/hatchling/builders/wheel.py
  class FileSelectionOptions (line 41) | class FileSelectionOptions(NamedTuple):
  class RecordFile (line 48) | class RecordFile:
    method __init__ (line 49) | def __init__(self) -> None:
    method write (line 53) | def write(self, record: Iterable[Any]) -> None:
    method construct (line 56) | def construct(self) -> str:
    method __enter__ (line 59) | def __enter__(self) -> RecordFile:  # noqa: PYI034
    method __exit__ (line 62) | def __exit__(
  class WheelArchive (line 68) | class WheelArchive:
    method __init__ (line 69) | def __init__(self, project_id: str, *, reproducible: bool) -> None:
    method get_reproducible_time_tuple (line 88) | def get_reproducible_time_tuple() -> TIME_TUPLE:
    method add_file (line 96) | def add_file(self, included_file: IncludedFile) -> tuple[str, str, str]:
    method write_metadata (line 128) | def write_metadata(self, relative_path: str, contents: str | bytes) ->...
    method write_shared_script (line 132) | def write_shared_script(self, included_file: IncludedFile, contents: s...
    method add_shared_file (line 146) | def add_shared_file(self, shared_file: IncludedFile) -> tuple[str, str...
    method add_extra_metadata_file (line 150) | def add_extra_metadata_file(self, extra_metadata_file: IncludedFile) -...
    method add_sbom_file (line 156) | def add_sbom_file(self, sbom_file: IncludedFile) -> tuple[str, str, str]:
    method write_file (line 161) | def write_file(
    method __enter__ (line 184) | def __enter__(self) -> WheelArchive:  # noqa: PYI034
    method __exit__ (line 187) | def __exit__(
  class WheelBuilderConfig (line 194) | class WheelBuilderConfig(BuilderConfig):
    method __init__ (line 195) | def __init__(self, *args: Any, **kwargs: Any) -> None:
    method default_file_selection_options (line 206) | def default_file_selection_options(self) -> FileSelectionOptions:
    method default_include (line 260) | def default_include(self) -> list[str]:
    method default_exclude (line 263) | def default_exclude(self) -> list[str]:
    method default_packages (line 266) | def default_packages(self) -> list[str]:
    method default_only_include (line 269) | def default_only_include(self) -> list[str]:
    method core_metadata_constructor (line 273) | def core_metadata_constructor(self) -> Callable[..., str]:
    method shared_data (line 294) | def shared_data(self) -> dict[str, str]:
    method shared_scripts (line 328) | def shared_scripts(self) -> dict[str, str]:
    method extra_metadata (line 362) | def extra_metadata(self) -> dict[str, str]:
    method sbom_files (line 396) | def sbom_files(self) -> list[str]:
    method strict_naming (line 415) | def strict_naming(self) -> bool:
    method macos_max_compat (line 433) | def macos_max_compat(self) -> bool:
    method bypass_selection (line 445) | def bypass_selection(self) -> bool:
    method get_raw_fs_path_name (line 456) | def get_raw_fs_path_name(directory: str, name: str) -> str:
    method get_raw_fs_path_name (line 468) | def get_raw_fs_path_name(directory: str, name: str) -> str:  # noqa: A...
  class WheelBuilder (line 472) | class WheelBuilder(BuilderInterface):
    method get_version_api (line 479) | def get_version_api(self) -> dict[str, Callable]:
    method get_default_versions (line 482) | def get_default_versions(self) -> list[str]:  # noqa: PLR6301
    method clean (line 485) | def clean(  # noqa: PLR6301
    method build_standard (line 494) | def build_standard(self, directory: str, **build_data: Any) -> str:
    method build_editable (line 520) | def build_editable(self, directory: str, **build_data: Any) -> str:
    method build_editable_detection (line 526) | def build_editable_detection(self, directory: str, **build_data: Any) ...
    method build_editable_explicit (line 610) | def build_editable_explicit(self, directory: str, **build_data: Any) -...
    method write_data (line 640) | def write_data(
    method add_shared_data (line 649) | def add_shared_data(self, archive: WheelArchive, records: RecordFile, ...
    method add_shared_scripts (line 657) | def add_shared_scripts(self, archive: WheelArchive, records: RecordFil...
    method add_sboms (line 689) | def add_sboms(self, archive: WheelArchive, records: RecordFile, build_...
    method write_metadata (line 707) | def write_metadata(
    method write_archive_metadata (line 736) | def write_archive_metadata(archive: WheelArchive, records: RecordFile,...
    method write_entry_points_file (line 751) | def write_entry_points_file(self, archive: WheelArchive, records: Reco...
    method write_project_metadata (line 757) | def write_project_metadata(
    method add_licenses (line 765) | def add_licenses(self, archive: WheelArchive, records: RecordFile) -> ...
    method add_extra_metadata (line 772) | def add_extra_metadata(self, archive: WheelArchive, records: RecordFil...
    method construct_entry_points_file (line 780) | def construct_entry_points_file(self) -> str:
    method get_default_tag (line 802) | def get_default_tag(self) -> str:
    method get_best_matching_tag (line 829) | def get_best_matching_tag(self) -> str:
    method get_default_build_data (line 846) | def get_default_build_data(self) -> dict[str, Any]:  # noqa: PLR6301
    method get_forced_inclusion_map (line 858) | def get_forced_inclusion_map(self, build_data: dict[str, Any]) -> dict...
    method artifact_project_id (line 865) | def artifact_project_id(self) -> str:
    method get_config_class (line 873) | def get_config_class(cls) -> type[WheelBuilderConfig]:

FILE: backend/src/hatchling/cli/__init__.py
  function hatchling (line 9) | def hatchling() -> int:

FILE: backend/src/hatchling/cli/build/__init__.py
  function build_impl (line 7) | def build_impl(
  function build_command (line 99) | def build_command(subparsers: argparse._SubParsersAction, defaults: Any)...

FILE: backend/src/hatchling/cli/dep/__init__.py
  function synced_impl (line 10) | def synced_impl(*, dependencies: list[str], python: str) -> None:
  function synced_command (line 26) | def synced_command(subparsers: argparse._SubParsersAction, defaults: Any...
  function dep_command (line 33) | def dep_command(subparsers: argparse._SubParsersAction, defaults: Any) -...

FILE: backend/src/hatchling/cli/dep/core.py
  class DistributionCache (line 11) | class DistributionCache:
    method __init__ (line 12) | def __init__(self, sys_path: list[str]) -> None:
    method __getitem__ (line 18) | def __getitem__(self, item: str) -> Distribution | None:
  function dependency_in_sync (line 44) | def dependency_in_sync(
  function dependencies_in_sync (line 123) | def dependencies_in_sync(

FILE: backend/src/hatchling/cli/metadata/__init__.py
  function metadata_impl (line 7) | def metadata_impl(
  function metadata_command (line 50) | def metadata_command(

FILE: backend/src/hatchling/cli/version/__init__.py
  function version_impl (line 7) | def version_impl(
  function version_command (line 47) | def version_command(subparsers: argparse._SubParsersAction, defaults: An...

FILE: backend/src/hatchling/metadata/core.py
  function load_toml (line 34) | def load_toml(path: str) -> dict[str, Any]:
  class ProjectMetadata (line 39) | class ProjectMetadata(Generic[PluginManagerBound]):
    method __init__ (line 40) | def __init__(
    method has_project_file (line 65) | def has_project_file(self) -> bool:
    method context (line 72) | def context(self) -> Context:
    method core_raw_metadata (line 81) | def core_raw_metadata(self) -> dict[str, Any]:
    method dynamic (line 112) | def dynamic(self) -> list[str]:
    method name (line 130) | def name(self) -> str:
    method version (line 144) | def version(self) -> str:
    method config (line 156) | def config(self) -> dict[str, Any]:
    method build (line 168) | def build(self) -> BuildMetadata:
    method core (line 180) | def core(self) -> CoreMetadata:
    method hatch (line 215) | def hatch(self) -> HatchMetadata:
    method _get_version (line 242) | def _get_version(self, core_metadata: CoreMetadata | None = None) -> str:
    method validate_fields (line 264) | def validate_fields(self) -> None:
  class BuildMetadata (line 269) | class BuildMetadata:
    method __init__ (line 274) | def __init__(self, root: str, config: dict[str, str | list[str]]) -> N...
    method requires_complex (line 284) | def requires_complex(self) -> list[Requirement]:
    method requires (line 311) | def requires(self) -> list[str]:
    method build_backend (line 318) | def build_backend(self) -> str:
    method backend_path (line 330) | def backend_path(self) -> list[str]:
  class CoreMetadata (line 347) | class CoreMetadata:
    method __init__ (line 352) | def __init__(
    method raw_name (line 397) | def raw_name(self) -> str:
    method name (line 427) | def name(self) -> str:
    method version (line 437) | def version(self) -> str:
    method description (line 469) | def description(self) -> str:
    method readme (line 493) | def readme(self) -> str:
    method readme_content_type (line 595) | def readme_content_type(self) -> str:
    method readme_path (line 605) | def readme_path(self) -> str:
    method requires_python (line 615) | def requires_python(self) -> str:
    method python_constraint (line 648) | def python_constraint(self) -> SpecifierSet:
    method license (line 657) | def license(self) -> str:
    method license_expression (line 722) | def license_expression(self) -> str:
    method license_files (line 732) | def license_files(self) -> list[str]:
    method authors (line 775) | def authors(self) -> list[str]:
    method authors_data (line 834) | def authors_data(self) -> dict[str, list[str]]:
    method maintainers (line 844) | def maintainers(self) -> list[str]:
    method maintainers_data (line 902) | def maintainers_data(self) -> dict[str, list[str]]:
    method keywords (line 912) | def keywords(self) -> list[str]:
    method classifiers (line 946) | def classifiers(self) -> list[str]:
    method urls (line 1012) | def urls(self) -> dict[str, str]:
    method scripts (line 1045) | def scripts(self) -> dict[str, str]:
    method gui_scripts (line 1079) | def gui_scripts(self) -> dict[str, str]:
    method entry_points (line 1113) | def entry_points(self) -> dict[str, dict[str, str]]:
    method dependencies_complex (line 1165) | def dependencies_complex(self) -> dict[str, Requirement]:
    method dependencies (line 1215) | def dependencies(self) -> list[str]:
    method optional_dependencies_complex (line 1225) | def optional_dependencies_complex(self) -> dict[str, dict[str, Require...
    method optional_dependencies (line 1329) | def optional_dependencies(self) -> dict[str, list[str]]:
    method dynamic (line 1341) | def dynamic(self) -> list[str]:
    method add_known_classifiers (line 1360) | def add_known_classifiers(self, classifiers: list[str]) -> None:
    method validate_fields (line 1363) | def validate_fields(self) -> None:
    method __classifier_is_private (line 1369) | def __classifier_is_private(classifier: str) -> bool:
  class HatchMetadata (line 1373) | class HatchMetadata(Generic[PluginManagerBound]):
    method __init__ (line 1374) | def __init__(self, root: str, config: dict[str, dict[str, Any]], plugi...
    method metadata (line 1385) | def metadata(self) -> HatchMetadataSettings:
    method build_config (line 1397) | def build_config(self) -> dict[str, Any]:
    method build_targets (line 1409) | def build_targets(self) -> dict[str, Any]:
    method version (line 1421) | def version(self) -> HatchVersionConfig:
  class HatchVersionConfig (line 1437) | class HatchVersionConfig(Generic[PluginManagerBound]):
    method __init__ (line 1438) | def __init__(self, root: str, config: dict[str, Any], plugin_manager: ...
    method cached (line 1450) | def cached(self) -> str:
    method source_name (line 1461) | def source_name(self) -> str:
    method scheme_name (line 1477) | def scheme_name(self) -> str:
    method source (line 1493) | def source(self) -> VersionSourceInterface:
    method scheme (line 1510) | def scheme(self) -> VersionSchemeInterface:
  class HatchMetadataSettings (line 1527) | class HatchMetadataSettings(Generic[PluginManagerBound]):
    method __init__ (line 1528) | def __init__(self, root: str, config: dict[str, Any], plugin_manager: ...
    method allow_direct_references (line 1539) | def allow_direct_references(self) -> bool:
    method allow_ambiguous_features (line 1551) | def allow_ambiguous_features(self) -> bool:
    method hook_config (line 1564) | def hook_config(self) -> dict[str, Any]:
    method hooks (line 1576) | def hooks(self) -> dict[str, MetadataHookInterface]:
  function _resolve_optional_dependencies (line 1596) | def _resolve_optional_dependencies(

FILE: backend/src/hatchling/metadata/custom.py
  class CustomMetadataHook (line 11) | class CustomMetadataHook:
    method __new__ (line 14) | def __new__(  # type: ignore[misc]

FILE: backend/src/hatchling/metadata/plugin/hooks.py
  function hatch_register_metadata_hook (line 13) | def hatch_register_metadata_hook() -> type[MetadataHookInterface]:

FILE: backend/src/hatchling/metadata/plugin/interface.py
  class MetadataHookInterface (line 6) | class MetadataHookInterface(ABC):  # no cov
    method __init__ (line 34) | def __init__(self, root: str, config: dict) -> None:
    method root (line 39) | def root(self) -> str:
    method config (line 46) | def config(self) -> dict:
    method update (line 57) | def update(self, metadata: dict) -> None:
    method get_known_classifiers (line 62) | def get_known_classifiers(self) -> list[str]:  # noqa: PLR6301

FILE: backend/src/hatchling/metadata/spec.py
  function get_core_metadata_constructors (line 52) | def get_core_metadata_constructors() -> dict[str, Callable]:
  function project_metadata_from_core_metadata (line 65) | def project_metadata_from_core_metadata(core_metadata: str) -> dict[str,...
  function construct_metadata_file_1_2 (line 202) | def construct_metadata_file_1_2(metadata: ProjectMetadata, extra_depende...
  function construct_metadata_file_2_1 (line 263) | def construct_metadata_file_2_1(metadata: ProjectMetadata, extra_depende...
  function construct_metadata_file_2_2 (line 340) | def construct_metadata_file_2_2(metadata: ProjectMetadata, extra_depende...
  function construct_metadata_file_2_3 (line 426) | def construct_metadata_file_2_3(metadata: ProjectMetadata, extra_depende...
  function construct_metadata_file_2_4 (line 512) | def construct_metadata_file_2_4(metadata: ProjectMetadata, extra_depende...

FILE: backend/src/hatchling/metadata/utils.py
  function is_valid_project_name (line 14) | def is_valid_project_name(project_name: str) -> bool:
  function normalize_project_name (line 19) | def normalize_project_name(project_name: str) -> str:
  function normalize_requirement (line 24) | def normalize_requirement(requirement: Requirement) -> None:
  function format_dependency (line 37) | def format_dependency(requirement: Requirement) -> str:
  function get_normalized_dependency (line 42) | def get_normalized_dependency(requirement: Requirement) -> str:
  function resolve_metadata_fields (line 47) | def resolve_metadata_fields(metadata: ProjectMetadata) -> dict[str, Any]:

FILE: backend/src/hatchling/ouroboros.py
  function read_dependencies (line 11) | def read_dependencies() -> list[str]:
  function get_requires_for_build_sdist (line 26) | def get_requires_for_build_sdist(  # type: ignore[no-redef]
  function get_requires_for_build_wheel (line 35) | def get_requires_for_build_wheel(  # type: ignore[no-redef]
  function get_requires_for_build_editable (line 44) | def get_requires_for_build_editable(  # type: ignore[no-redef]

FILE: backend/src/hatchling/plugin/exceptions.py
  class UnknownPluginError (line 1) | class UnknownPluginError(ValueError):

FILE: backend/src/hatchling/plugin/manager.py
  class PluginManager (line 11) | class PluginManager:
    method __init__ (line 12) | def __init__(self) -> None:
    method initialize (line 17) | def initialize(self) -> None:
    method __getattr__ (line 22) | def __getattr__(self, name: str) -> ClassRegister:
    method hatch_register_version_source (line 36) | def hatch_register_version_source(self) -> None:
    method hatch_register_version_scheme (line 41) | def hatch_register_version_scheme(self) -> None:
    method hatch_register_builder (line 46) | def hatch_register_builder(self) -> None:
    method hatch_register_build_hook (line 51) | def hatch_register_build_hook(self) -> None:
    method hatch_register_metadata_hook (line 56) | def hatch_register_metadata_hook(self) -> None:
  class ClassRegister (line 62) | class ClassRegister:
    method __init__ (line 63) | def __init__(self, registration_method: Callable, identifier: str, thi...
    method collect (line 68) | def collect(self, *, include_third_party: bool = True) -> dict:
    method get (line 95) | def get(self, name: str) -> type | None:
  class ThirdPartyPlugins (line 104) | class ThirdPartyPlugins:
    method __init__ (line 105) | def __init__(self, manager: pluggy.PluginManager) -> None:
    method load (line 109) | def load(self) -> None:

FILE: backend/src/hatchling/plugin/specs.py
  function hatch_register_version_source (line 7) | def hatch_register_version_source() -> None:
  function hatch_register_builder (line 12) | def hatch_register_builder() -> None:
  function hatch_register_build_hook (line 17) | def hatch_register_build_hook() -> None:
  function hatch_register_metadata_hook (line 22) | def hatch_register_metadata_hook() -> None:

FILE: backend/src/hatchling/plugin/utils.py
  function load_plugin_from_script (line 13) | def load_plugin_from_script(path: str, script_name: str, plugin_class: t...

FILE: backend/src/hatchling/utils/constants.py
  class VersionEnvVars (line 5) | class VersionEnvVars:

FILE: backend/src/hatchling/utils/context.py
  class ContextFormatter (line 16) | class ContextFormatter(ABC):
    method get_formatters (line 18) | def get_formatters(self) -> MutableMapping:
    method format_path (line 28) | def format_path(cls, path: str, modifier: str) -> str:
  class DefaultContextFormatter (line 55) | class DefaultContextFormatter(ContextFormatter):
    method __init__ (line 58) | def __init__(self, root: str) -> None:
    method get_formatters (line 61) | def get_formatters(self) -> MutableMapping:
    method __format_directory_separator (line 70) | def __format_directory_separator(self, value: str, data: str) -> str: ...
    method __format_path_separator (line 73) | def __format_path_separator(self, value: str, data: str) -> str:  # no...
    method __format_root (line 76) | def __format_root(self, value: str, data: str) -> str:  # noqa: ARG002
    method __format_home (line 79) | def __format_home(self, value: str, data: str) -> str:  # noqa: ARG002
    method __format_env (line 82) | def __format_env(self, value: str, data: str) -> str:  # noqa: ARG002,...
  class Context (line 98) | class Context:
    method __init__ (line 99) | def __init__(self, root: str) -> None:
    method format (line 109) | def format(self, *args: Any, **kwargs: Any) -> str:
    method add_context (line 112) | def add_context(self, context: DefaultContextFormatter) -> None:
    method apply_context (line 120) | def apply_context(self, context: DefaultContextFormatter) -> Iterator:
    method __add_formatters (line 127) | def __add_formatters(self, formatters: MutableMapping) -> None:
    method __remove_formatters (line 130) | def __remove_formatters(self) -> None:
  class ContextStringFormatter (line 135) | class ContextStringFormatter(string.Formatter):
    method __init__ (line 136) | def __init__(self, formatters: ChainMap) -> None:
    method vformat (line 141) | def vformat(self, format_string: str, args: Sequence[Any], kwargs: Map...
    method get_value (line 150) | def get_value(self, key: int | str, args: Sequence[Any], kwargs: Mappi...
    method format_field (line 161) | def format_field(self, value: Any, format_spec: str) -> Any:
    method parse (line 168) | def parse(self, format_string: str) -> Iterable:

FILE: backend/src/hatchling/utils/fs.py
  function locate_file (line 6) | def locate_file(root: str, file_name: str, *, boundary: str | None = Non...
  function path_to_uri (line 22) | def path_to_uri(path: str) -> str:

FILE: backend/src/hatchling/version/core.py
  class VersionFile (line 15) | class VersionFile:
    method __init__ (line 16) | def __init__(self, root: str, relative_path: str) -> None:
    method read (line 21) | def read(self, *, pattern: str | bool) -> str:
    method set_version (line 45) | def set_version(self, version: str) -> None:
    method write (line 50) | def write(self, version: str, template: str = DEFAULT_TEMPLATE) -> None:

FILE: backend/src/hatchling/version/scheme/plugin/hooks.py
  function hatch_register_version_scheme (line 13) | def hatch_register_version_scheme() -> type[VersionSchemeInterface]:

FILE: backend/src/hatchling/version/scheme/plugin/interface.py
  class VersionSchemeInterface (line 8) | class VersionSchemeInterface(ABC):  # no cov
    method __init__ (line 36) | def __init__(self, root: str, config: dict) -> None:
    method root (line 41) | def root(self) -> str:
    method config (line 48) | def config(self) -> dict:
    method validate_bump (line 57) | def validate_bump(self) -> bool:
    method update (line 80) | def update(self, desired_version: str, original_version: str, version_...

FILE: backend/src/hatchling/version/scheme/standard.py
  class StandardScheme (line 11) | class StandardScheme(VersionSchemeInterface):
    method update (line 18) | def update(
  function reset_version_parts (line 71) | def reset_version_parts(version: Version, **kwargs: Any) -> Version:
  function update_release (line 101) | def update_release(original_version: Version, new_release_parts: list[in...
  function parse_letter_version (line 108) | def parse_letter_version(*args: Any, **kwargs: Any) -> tuple[Literal["a"...

FILE: backend/src/hatchling/version/source/code.py
  class CodeSource (line 8) | class CodeSource(VersionSourceInterface):
    method get_version_data (line 11) | def get_version_data(self) -> dict:
    method set_version (line 62) | def set_version(self, version: str, version_data: dict) -> None:

FILE: backend/src/hatchling/version/source/env.py
  class EnvSource (line 8) | class EnvSource(VersionSourceInterface):
    method get_version_data (line 11) | def get_version_data(self) -> dict:
    method set_version (line 27) | def set_version(self, version: str, version_data: dict) -> None:

FILE: backend/src/hatchling/version/source/plugin/hooks.py
  function hatch_register_version_source (line 15) | def hatch_register_version_source() -> list[type[VersionSourceInterface]]:

FILE: backend/src/hatchling/version/source/plugin/interface.py
  class VersionSourceInterface (line 6) | class VersionSourceInterface(ABC):  # no cov
    method __init__ (line 34) | def __init__(self, root: str, config: dict) -> None:
    method root (line 39) | def root(self) -> str:
    method config (line 46) | def config(self) -> dict:
    method get_version_data (line 55) | def get_version_data(self) -> dict:
    method set_version (line 65) | def set_version(self, version: str, version_data: dict) -> None:

FILE: backend/src/hatchling/version/source/regex.py
  class RegexSource (line 5) | class RegexSource(VersionSourceInterface):
    method get_version_data (line 8) | def get_version_data(self) -> dict:
    method set_version (line 28) | def set_version(self, version: str, version_data: dict) -> None:  # no...

FILE: backend/tests/downstream/integrate.py
  function handle_remove_readonly (line 23) | def handle_remove_readonly(func, path, exc):  # no cov
  class EnvVars (line 32) | class EnvVars(dict):
    method __init__ (line 33) | def __init__(self, env_vars=None, ignore=None):
    method __enter__ (line 44) | def __enter__(self):
    method __exit__ (line 48) | def __exit__(self, exc_type, exc_value, traceback):
  function python_version_supported (line 53) | def python_version_supported(project_config):
  function download_file (line 63) | def download_file(url, file_name):
  function temp_dir (line 71) | def temp_dir():
  function get_venv_exe_dir (line 81) | def get_venv_exe_dir(venv_dir):
  function main (line 108) | def main():

FILE: docs/.hooks/expand_blocks.py
  function _code_tab_replace (line 16) | def _code_tab_replace(m):
  function _config_example_replace (line 26) | def _config_example_replace(m):
  class ExpandedBlocksPreprocessor (line 42) | class ExpandedBlocksPreprocessor(Preprocessor):
    method run (line 43) | def run(self, lines):  # noqa: PLR6301

FILE: docs/.hooks/inject_version.py
  function get_latest_version (line 12) | def get_latest_version():
  class VersionInjectionPreprocessor (line 29) | class VersionInjectionPreprocessor(Preprocessor):
    method run (line 30) | def run(self, lines):  # noqa: PLR6301

FILE: docs/.hooks/plugin_register.py
  function on_config (line 9) | def on_config(
  class GlobalExtension (line 16) | class GlobalExtension(Extension):
    method extendMarkdown (line 17) | def extendMarkdown(self, md):  # noqa: N802, PLR6301

FILE: docs/.hooks/render_default_test_env.py
  function test_env_config (line 16) | def test_env_config():
  function get_dependencies_toml (line 26) | def get_dependencies_toml():
  function get_matrix_toml (line 40) | def get_matrix_toml():
  function get_scripts_toml (line 46) | def get_scripts_toml():
  class TestEnvDefaultsPreprocessor (line 51) | class TestEnvDefaultsPreprocessor(Preprocessor):
    method run (line 52) | def run(self, lines):  # noqa: PLR6301

FILE: docs/.hooks/render_ruff_defaults.py
  function read_constants (line 21) | def read_constants(path: str, start: str) -> dict[str, Any]:
  function parse_rules (line 38) | def parse_rules(rules: tuple[str, ...]) -> defaultdict[str, list[str]]:
  function construct_collapsed_markdown_rule_list (line 54) | def construct_collapsed_markdown_rule_list(text: str, rules: defaultdict...
  function ruff_data (line 75) | def ruff_data():
  function get_ruff_version (line 88) | def get_ruff_version():
  function get_stable_rules_count (line 93) | def get_stable_rules_count():
  function get_preview_rules_count (line 98) | def get_preview_rules_count():
  function get_unselected_rules_count (line 103) | def get_unselected_rules_count():
  function get_selected_rules (line 108) | def get_selected_rules():
  function get_unselected_rules (line 118) | def get_unselected_rules():
  function get_per_file_ignored_rules (line 123) | def get_per_file_ignored_rules():
  class RuffDefaultsPreprocessor (line 136) | class RuffDefaultsPreprocessor(Preprocessor):
    method run (line 137) | def run(self, lines):  # noqa: PLR6301

FILE: docs/.hooks/title_from_content.py
  function on_page_markdown (line 1) | def on_page_markdown(

FILE: release/macos/build_pkg.py
  function run_command (line 34) | def run_command(command: list[str]) -> None:
  function main (line 40) | def main():

FILE: release/unix/make_scripts_portable.py
  function main (line 9) | def main():

FILE: release/windows/make_scripts_portable.py
  function select_entry_points (line 26) | def select_entry_points(ep, group):
  function fetch_launcher (line 30) | def fetch_launcher(launcher_name):
  function main (line 35) | def main():

FILE: scripts/bump.py
  function main (line 14) | def main():

FILE: scripts/generate_coverage_summary.py
  function main (line 14) | def main():

FILE: scripts/install_mkdocs_material_insiders.py
  function main (line 10) | def main():

FILE: scripts/release_github.py
  function main (line 10) | def main():

FILE: scripts/set_release_version.py
  function main (line 6) | def main():

FILE: scripts/update_distributions.py
  function parse_distributions (line 18) | def parse_distributions(contents: str, constant: str):
  function main (line 45) | def main():

FILE: scripts/update_ruff.py
  function get_lines_until (line 79) | def get_lines_until(file_path: Path, marker: str) -> list[str]:
  function main (line 93) | def main():

FILE: scripts/utils.py
  function get_latest_release (line 7) | def get_latest_release(project):

FILE: scripts/validate_history.py
  function main (line 12) | def main():

FILE: scripts/write_coverage_summary_report.py
  function main (line 8) | def main():

FILE: src/hatch/cli/__init__.py
  function hatch (line 95) | def hatch(
  function main (line 237) | def main():  # no cov

FILE: src/hatch/cli/application.py
  class Application (line 22) | class Application(Terminal):
    method __init__ (line 23) | def __init__(self, exit_func, *args, **kwargs):
    method plugins (line 40) | def plugins(self):
    method config (line 44) | def config(self) -> RootConfig:
    method get_environment (line 47) | def get_environment(self, env_name: str | None = None) -> EnvironmentI...
    method prepare_environment (line 50) | def prepare_environment(self, environment: EnvironmentInterface, *, ke...
    method run_shell_commands (line 53) | def run_shell_commands(self, context: ExecutionContext) -> None:
    method runner_context (line 88) | def runner_context(
    method execute_context (line 133) | def execute_context(self, context: ExecutionContext) -> None:
    method ensure_environment_plugin_dependencies (line 139) | def ensure_environment_plugin_dependencies(self) -> None:
    method ensure_plugin_dependencies (line 144) | def ensure_plugin_dependencies(self, dependencies: list[Dependency], *...
    method get_env_directory (line 179) | def get_env_directory(self, environment_type):
    method get_python_manager (line 191) | def get_python_manager(self, directory: str | None = None):
    method shell_data (line 201) | def shell_data(self) -> tuple[str, str]:
    method abort (line 206) | def abort(self, text="", code=1, **kwargs):

FILE: src/hatch/cli/build/__init__.py
  function build (line 52) | def build(app: Application, location, targets, hooks_only, no_hooks, ext...

FILE: src/hatch/cli/clean/__init__.py
  function clean (line 35) | def clean(ctx, location, targets, hooks_only, no_hooks, ext):

FILE: src/hatch/cli/config/__init__.py
  function config (line 7) | def config():
  function explore (line 13) | def explore(app):
  function find (line 20) | def find(app):
  function show (line 28) | def show(app, all_keys):
  function update (line 39) | def update(app):  # no cov
  function restore (line 47) | def restore(app):
  function set_value (line 57) | def set_value(app, key, value):

FILE: src/hatch/cli/dep/__init__.py
  function dep (line 5) | def dep():
  function hash_dependencies (line 13) | def hash_dependencies(app, project_only, env_only):
  function show (line 38) | def show():
  function table (line 48) | def table(app, project_only, env_only, show_lines, force_ascii):
  function requirements (line 118) | def requirements(app, project_only, env_only, features, all_features):

FILE: src/hatch/cli/env/__init__.py
  function env (line 12) | def env():

FILE: src/hatch/cli/env/create.py
  function create (line 17) | def create(app: Application, env_name: str):

FILE: src/hatch/cli/env/find.py
  function find (line 14) | def find(app: Application, env_name: str):

FILE: src/hatch/cli/env/prune.py
  function prune (line 13) | def prune(app: Application):

FILE: src/hatch/cli/env/remove.py
  function remove (line 14) | def remove(ctx: click.Context, env_name: str):

FILE: src/hatch/cli/env/run.py
  function filter_environments (line 14) | def filter_environments(environments, filter_data):
  function run (line 37) | def run(

FILE: src/hatch/cli/env/show.py
  function show (line 18) | def show(

FILE: src/hatch/cli/fmt/__init__.py
  function fmt (line 18) | def fmt(

FILE: src/hatch/cli/fmt/core.py
  class StaticAnalysisEnvironment (line 11) | class StaticAnalysisEnvironment:
    method __init__ (line 12) | def __init__(self, env: EnvironmentInterface) -> None:
    method config_path (line 16) | def config_path(self) -> str:
    method get_default_args (line 19) | def get_default_args(self) -> list[str]:
    method internal_config_file (line 30) | def internal_config_file(self) -> Path:
    method construct_config_file (line 33) | def construct_config_file(self, *, preview: bool) -> str:
    method write_config_file (line 80) | def write_config_file(self, *, preview: bool) -> None:
    method internal_user_config_file (line 118) | def internal_user_config_file(self) -> Path | None:
    method user_config_file (line 125) | def user_config_file(self) -> Path | None:
    method user_config (line 134) | def user_config(self) -> dict[str, Any]:
    method linter_preview (line 143) | def linter_preview(self) -> bool:
    method formatter_preview (line 147) | def formatter_preview(self) -> bool:
    method get_config (line 150) | def get_config(self, section: str) -> dict[str, Any]:

FILE: src/hatch/cli/new/__init__.py
  function new (line 12) | def new(app, name, location, interactive, feature_cli, initialize, setup...

FILE: src/hatch/cli/new/migrate.py
  function _apply_env_vars (line 9) | def _apply_env_vars(kwargs):
  function _parse_dependencies (line 17) | def _parse_dependencies(dependency_definition):
  function _collapse_data (line 27) | def _collapse_data(output, data):
  function _parse_setup_cfg (line 38) | def _parse_setup_cfg(kwargs):
  function setup (line 123) | def setup(**kwargs):
  function __getattr__ (line 327) | def __getattr__(name):
  function migrate (line 334) | def migrate(root, setuptools_options, sys_paths):

FILE: src/hatch/cli/project/__init__.py
  function project (line 7) | def project():

FILE: src/hatch/cli/project/metadata.py
  function metadata (line 14) | def metadata(app: Application, field: str | None):

FILE: src/hatch/cli/publish/__init__.py
  function publish (line 63) | def publish(

FILE: src/hatch/cli/python/__init__.py
  function python (line 11) | def python():

FILE: src/hatch/cli/python/find.py
  function find (line 16) | def find(app: Application, *, name: str, parent: bool, directory: str | ...

FILE: src/hatch/cli/python/install.py
  function ensure_path_public (line 11) | def ensure_path_public(path: str, shells: list[str]) -> bool:
  function install (line 29) | def install(app: Application, *, names: tuple[str, ...], private: bool, ...

FILE: src/hatch/cli/python/remove.py
  function remove (line 15) | def remove(app: Application, *, names: tuple[str, ...], directory: str |...

FILE: src/hatch/cli/python/show.py
  function show (line 15) | def show(app: Application, *, force_ascii: bool, directory: str | None):

FILE: src/hatch/cli/python/update.py
  function update (line 17) | def update(ctx: click.Context, *, names: tuple[str, ...], directory: str...

FILE: src/hatch/cli/run/__init__.py
  function run (line 17) | def run(ctx: click.Context, args: tuple[str, ...]):

FILE: src/hatch/cli/self/__init__.py
  function self_command (line 11) | def self_command():

FILE: src/hatch/cli/self/report.py
  function get_install_source (line 11) | def get_install_source(platform_name: str) -> str:
  function report (line 69) | def report(app: Application, *, no_open: bool) -> None:

FILE: src/hatch/cli/self/restore.py
  function restore (line 16) | def restore(app: Application, *, args: tuple[str, ...]):  # noqa: ARG001

FILE: src/hatch/cli/self/update.py
  function update (line 16) | def update(app: Application, *, args: tuple[str, ...]):  # noqa: ARG001

FILE: src/hatch/cli/shell/__init__.py
  function shell (line 19) | def shell(app: Application, env_name: str | None, name: str, path: str):...

FILE: src/hatch/cli/status/__init__.py
  function status (line 6) | def status(app):

FILE: src/hatch/cli/terminal.py
  class TerminalStatus (line 20) | class TerminalStatus(ABC):
    method stop (line 22) | def stop(self) -> None: ...
    method __enter__ (line 24) | def __enter__(self) -> TerminalStatus:  # noqa: PYI034
    method __exit__ (line 28) | def __exit__(self, exc_type, exc_val, exc_tb): ...
  class NullStatus (line 31) | class NullStatus(TerminalStatus):
    method stop (line 32) | def stop(self):
    method __exit__ (line 35) | def __exit__(self, exc_type, exc_value, traceback):
  class BorrowedStatus (line 39) | class BorrowedStatus(TerminalStatus):
    method __init__ (line 40) | def __init__(
    method stop (line 67) | def stop(self) -> None:
    method __call__ (line 81) | def __call__(self, message: str, final_text: str = "") -> BorrowedStatus:
    method __enter__ (line 85) | def __enter__(self) -> BorrowedStatus:  # noqa: PYI034
    method __exit__ (line 104) | def __exit__(self, exc_type, exc_val, exc_tb):
    method __active (line 126) | def __active(self) -> bool:
    method __output (line 129) | def __output(self, text):
  class Terminal (line 137) | class Terminal:
    method __init__ (line 138) | def __init__(self, *, verbosity: int, enable_color: bool | None, inter...
    method kv_separator (line 166) | def kv_separator(self) -> Text:
    method style_success (line 169) | def style_success(self, text: str) -> Text:
    method style_error (line 172) | def style_error(self, text: str) -> Text:
    method style_warning (line 175) | def style_warning(self, text: str) -> Text:
    method style_waiting (line 178) | def style_waiting(self, text: str) -> Text:
    method style_info (line 181) | def style_info(self, text: str) -> Text:
    method style_debug (line 184) | def style_debug(self, text: str) -> Text:
    method initialize_styles (line 187) | def initialize_styles(self, styles: dict):  # no cov
    method display (line 220) | def display(self, text="", **kwargs):
    method display_critical (line 223) | def display_critical(self, text="", **kwargs):
    method display_error (line 232) | def display_error(self, text="", *, stderr=True, indent=None, link=Non...
    method display_warning (line 238) | def display_warning(self, text="", *, stderr=True, indent=None, link=N...
    method display_info (line 244) | def display_info(self, text="", *, stderr=True, indent=None, link=None...
    method display_success (line 250) | def display_success(self, text="", *, stderr=True, indent=None, link=N...
    method display_waiting (line 256) | def display_waiting(self, text="", *, stderr=True, indent=None, link=N...
    method display_debug (line 262) | def display_debug(self, text="", level=1, *, stderr=True, indent=None,...
    method display_mini_header (line 272) | def display_mini_header(self, text, *, stderr=False, indent=None, link...
    method display_header (line 280) | def display_header(self, title=""):
    method display_syntax (line 283) | def display_syntax(self, *args, **kwargs):
    method display_markdown (line 289) | def display_markdown(self, text, **kwargs):  # no cov
    method display_pair (line 294) | def display_pair(self, key, value):
    method display_table (line 297) | def display_table(self, title, columns, *, show_lines=False, column_op...
    method status (line 330) | def status(self) -> BorrowedStatus:
    method status_if (line 342) | def status_if(self, *args, condition: bool, **kwargs) -> TerminalStatus:
    method _output (line 345) | def _output(self, text="", style=None, *, stderr=False, indent=None, l...
    method output (line 354) | def output(self, *args, stderr=False, **kwargs):
    method prompt (line 369) | def prompt(text, **kwargs):
    method confirm (line 373) | def confirm(text, **kwargs):

FILE: src/hatch/cli/test/__init__.py
  function test (line 26) | def test(

FILE: src/hatch/cli/test/core.py
  class PatchedCoverageConfig (line 12) | class PatchedCoverageConfig:
    method __init__ (line 13) | def __init__(self, project_root: Path, data_dir: Path) -> None:
    method user_config_path (line 18) | def user_config_path(self) -> Path:
    method internal_config_path (line 27) | def internal_config_path(self) -> Path:
    method write_config_file (line 30) | def write_config_file(self) -> None:
    method _write_ini (line 54) | def _write_ini(self, cfg: ConfigParser) -> None:

FILE: src/hatch/cli/version/__init__.py
  function version (line 20) | def version(app: Application, *, desired_version: str | None, force: bool):

FILE: src/hatch/config/constants.py
  class AppEnvVars (line 1) | class AppEnvVars:
  class ConfigEnvVars (line 15) | class ConfigEnvVars:
  class PublishEnvVars (line 22) | class PublishEnvVars:
  class PythonEnvVars (line 33) | class PythonEnvVars:
  class VersionEnvVars (line 39) | class VersionEnvVars:

FILE: src/hatch/config/model.py
  class ConfigurationError (line 6) | class ConfigurationError(Exception):
    method __init__ (line 7) | def __init__(self, *args, location):
    method __str__ (line 11) | def __str__(self):
  function parse_config (line 15) | def parse_config(obj):
  class LazilyParsedConfig (line 26) | class LazilyParsedConfig:
    method __init__ (line 27) | def __init__(self, config: dict, steps: tuple = ()):
    method parse_fields (line 31) | def parse_fields(self):
    method raise_error (line 37) | def raise_error(self, message, *, extra_steps=()):
  class RootConfig (line 44) | class RootConfig(LazilyParsedConfig):
    method __init__ (line 45) | def __init__(self, *args, **kwargs):
    method mode (line 58) | def mode(self):
    method mode (line 76) | def mode(self, value):
    method project (line 81) | def project(self):
    method project (line 95) | def project(self, value):
    method shell (line 100) | def shell(self):
    method shell (line 117) | def shell(self, value):
    method dirs (line 122) | def dirs(self):
    method dirs (line 138) | def dirs(self, value):
    method projects (line 143) | def projects(self):
    method projects (line 166) | def projects(self, value):
    method publish (line 171) | def publish(self):
    method publish (line 189) | def publish(self, value):
    method template (line 194) | def template(self):
    method template (line 210) | def template(self, value):
    method terminal (line 215) | def terminal(self):
    method terminal (line 231) | def terminal(self, value):
  class ShellConfig (line 236) | class ShellConfig(LazilyParsedConfig):
    method __init__ (line 237) | def __init__(self, *args, **kwargs):
    method name (line 245) | def name(self):
    method name (line 259) | def name(self, value):
    method path (line 264) | def path(self):
    method path (line 278) | def path(self, value):
    method args (line 283) | def args(self):
    method args (line 301) | def args(self, value):
  class DirsConfig (line 306) | class DirsConfig(LazilyParsedConfig):
    method __init__ (line 307) | def __init__(self, *args, **kwargs):
    method project (line 317) | def project(self):
    method project (line 335) | def project(self, value):
    method env (line 340) | def env(self):
    method env (line 358) | def env(self, value):
    method python (line 363) | def python(self):
    method python (line 377) | def python(self, value):
    method data (line 382) | def data(self):
    method data (line 398) | def data(self, value):
    method cache (line 403) | def cache(self):
    method cache (line 419) | def cache(self, value):
  class ProjectConfig (line 424) | class ProjectConfig(LazilyParsedConfig):
    method __init__ (line 425) | def __init__(self, *args, **kwargs):
    method location (line 431) | def location(self):
    method location (line 445) | def location(self, value):
  class TemplateConfig (line 450) | class TemplateConfig(LazilyParsedConfig):
    method __init__ (line 451) | def __init__(self, *args, **kwargs):
    method name (line 460) | def name(self):
    method name (line 486) | def name(self, value):
    method email (line 491) | def email(self):
    method email (line 517) | def email(self, value):
    method licenses (line 522) | def licenses(self):
    method licenses (line 538) | def licenses(self, value):
    method plugins (line 543) | def plugins(self):
    method plugins (line 563) | def plugins(self, value):
  class LicensesConfig (line 568) | class LicensesConfig(LazilyParsedConfig):
    method __init__ (line 569) | def __init__(self, *args, **kwargs):
    method headers (line 576) | def headers(self):
    method headers (line 590) | def headers(self, value):
    method default (line 595) | def default(self):
    method default (line 613) | def default(self, value):
  class TerminalConfig (line 618) | class TerminalConfig(LazilyParsedConfig):
    method __init__ (line 619) | def __init__(self, *args, **kwargs):
    method styles (line 625) | def styles(self):
    method styles (line 641) | def styles(self, value):
  class StylesConfig (line 646) | class StylesConfig(LazilyParsedConfig):
    method __init__ (line 647) | def __init__(self, *args, **kwargs):
    method info (line 659) | def info(self):
    method info (line 673) | def info(self, value):
    method success (line 678) | def success(self):
    method success (line 692) | def success(self, value):
    method error (line 697) | def error(self):
    method error (line 711) | def error(self, value):
    method warning (line 716) | def warning(self):
    method warning (line 730) | def warning(self, value):
    method waiting (line 735) | def waiting(self):
    method waiting (line 749) | def waiting(self, value):
    method debug (line 754) | def debug(self):
    method debug (line 768) | def debug(self, value):
    method spinner (line 773) | def spinner(self):
    method spinner (line 787) | def spinner(self, value):

FILE: src/hatch/config/user.py
  class ConfigFile (line 10) | class ConfigFile:
    method __init__ (line 11) | def __init__(self, path: Path | None = None):
    method path (line 16) | def path(self):
    method path (line 23) | def path(self, value):
    method save (line 26) | def save(self, content=None):
    method load (line 35) | def load(self):
    method read (line 38) | def read(self) -> str:
    method read_scrubbed (line 41) | def read_scrubbed(self) -> str:
    method restore (line 48) | def restore(self):
    method update (line 59) | def update(self):  # no cov
    method get_default_location (line 64) | def get_default_location(cls) -> Path:

FILE: src/hatch/config/utils.py
  function save_toml_document (line 14) | def save_toml_document(document: TOMLDocument, path: Path):
  function create_toml_document (line 19) | def create_toml_document(config: dict) -> InlineTable:

FILE: src/hatch/dep/core.py
  class Dependency (line 12) | class Dependency(Requirement):
    method __init__ (line 13) | def __init__(self, s: str, *, editable: bool = False) -> None:
    method editable (line 23) | def editable(self) -> bool:
    method path (line 27) | def path(self) -> Path | None:

FILE: src/hatch/dep/sync.py
  class InstalledDistributions (line 13) | class InstalledDistributions:
    method __init__ (line 14) | def __init__(self, *, sys_path: list[str] | None = None, environment: ...
    method dependencies_in_sync (line 24) | def dependencies_in_sync(self, dependencies: list[Dependency]) -> bool:
    method missing_dependencies (line 27) | def missing_dependencies(self, dependencies: list[Dependency]) -> list...
    method dependency_in_sync (line 30) | def dependency_in_sync(self, dependency: Dependency, *, environment: d...
    method __getitem__ (line 120) | def __getitem__(self, item: str) -> Distribution | None:
  function dependencies_in_sync (line 144) | def dependencies_in_sync(

FILE: src/hatch/env/collectors/custom.py
  class CustomEnvironmentCollector (line 11) | class CustomEnvironmentCollector:
    method __new__ (line 14) | def __new__(  # type: ignore[misc]

FILE: src/hatch/env/collectors/default.py
  class DefaultEnvironmentCollector (line 6) | class DefaultEnvironmentCollector(EnvironmentCollectorInterface):
    method get_initial_config (line 9) | def get_initial_config(self):  # noqa: PLR6301

FILE: src/hatch/env/collectors/plugin/hooks.py
  function hatch_register_environment_collector (line 14) | def hatch_register_environment_collector() -> list[type[EnvironmentColle...

FILE: src/hatch/env/collectors/plugin/interface.py
  class EnvironmentCollectorInterface (line 4) | class EnvironmentCollectorInterface:
    method __init__ (line 32) | def __init__(self, root, config):
    method root (line 37) | def root(self):
    method config (line 44) | def config(self) -> dict:
    method get_initial_config (line 52) | def get_initial_config(self) -> dict[str, dict]:  # noqa: PLR6301
    method finalize_config (line 58) | def finalize_config(self, config: dict[str, dict]):
    method finalize_environments (line 66) | def finalize_environments(self, config: dict[str, dict]):

FILE: src/hatch/env/context.py
  class EnvironmentContextFormatterBase (line 7) | class EnvironmentContextFormatterBase(ContextFormatter, ABC):
    method formatters (line 9) | def formatters(self):
  class EnvironmentContextFormatter (line 13) | class EnvironmentContextFormatter(EnvironmentContextFormatterBase):
    method __init__ (line 14) | def __init__(self, environment):
    method formatters (line 18) | def formatters(self):  # noqa: PLR6301
    method get_formatters (line 28) | def get_formatters(self):
    method __format_args (line 39) | def __format_args(self, value, data):  # noqa: PLR6301
    method __format_env_name (line 45) | def __format_env_name(self, value, data):  # noqa: ARG002
    method __format_env_type (line 48) | def __format_env_type(self, value, data):  # noqa: ARG002
    method __format_matrix (line 51) | def __format_matrix(self, value, data):  # noqa: ARG002
    method __format_verbosity (line 66) | def __format_verbosity(self, value, data):  # noqa: ARG002

FILE: src/hatch/env/internal/__init__.py
  function get_internal_env_config (line 8) | def get_internal_env_config() -> dict[str, Any]:
  function is_isolated_environment (line 25) | def is_isolated_environment(env_name: str, config: dict[str, Any]) -> bool:
  function is_default_environment (line 43) | def is_default_environment(env_name: str, config: dict[str, Any]) -> bool:

FILE: src/hatch/env/internal/build.py
  function get_default_config (line 6) | def get_default_config() -> dict[str, Any]:

FILE: src/hatch/env/internal/static_analysis.py
  function get_default_config (line 6) | def get_default_config() -> dict[str, Any]:

FILE: src/hatch/env/internal/test.py
  function get_default_config (line 6) | def get_default_config() -> dict[str, Any]:

FILE: src/hatch/env/internal/uv.py
  function get_default_config (line 6) | def get_default_config() -> dict[str, Any]:

FILE: src/hatch/env/plugin/hooks.py
  function hatch_register_environment (line 7) | def hatch_register_environment():

FILE: src/hatch/env/plugin/interface.py
  class EnvironmentInterface (line 24) | class EnvironmentInterface(ABC):
    method __init__ (line 52) | def __init__(
    method matrix_variables (line 79) | def matrix_variables(self):
    method app (line 83) | def app(self):
    method context (line 90) | def context(self):
    method verbosity (line 94) | def verbosity(self):
    method root (line 98) | def root(self):
    method metadata (line 105) | def metadata(self):
    method name (line 109) | def name(self) -> str:
    method platform (line 116) | def platform(self):
    method data_directory (line 123) | def data_directory(self):
    method isolated_data_directory (line 132) | def isolated_data_directory(self):
    method config (line 140) | def config(self) -> dict:
    method project_root (line 149) | def project_root(self) -> str:
    method sep (line 157) | def sep(self) -> str:
    method pathsep (line 164) | def pathsep(self) -> str:
    method system_python (line 171) | def system_python(self) -> str:
    method env_vars (line 188) | def env_vars(self) -> dict[str, str]:
    method env_include (line 215) | def env_include(self) -> list[str]:
    method env_exclude (line 235) | def env_exclude(self) -> list[str]:
    method environment_dependencies_complex (line 255) | def environment_dependencies_complex(self) -> list[Dependency]:
    method environment_dependencies (line 280) | def environment_dependencies(self) -> list[str]:
    method project_dependencies_complex (line 287) | def project_dependencies_complex(self) -> list[Dependency]:
    method project_dependencies (line 333) | def project_dependencies(self) -> list[str]:
    method local_dependencies_complex (line 343) | def local_dependencies_complex(self) -> list[Dependency]:
    method dependencies_complex (line 360) | def dependencies_complex(self) -> list[Dependency]:
    method dependencies (line 404) | def dependencies(self) -> list[str]:
    method all_dependencies_complex (line 414) | def all_dependencies_complex(self) -> list[Dependency]:
    method all_dependencies (line 437) | def all_dependencies(self) -> list[str]:
    method platforms (line 441) | def platforms(self) -> list[str]:
    method skip_install (line 463) | def skip_install(self) -> bool:
    method dev_mode (line 478) | def dev_mode(self) -> bool:
    method builder (line 493) | def builder(self) -> bool:
    method features (line 508) | def features(self):
    method dependency_groups (line 544) | def dependency_groups(self):
    method description (line 580) | def description(self) -> str:
    method scripts (line 595) | def scripts(self):
    method pre_install_commands (line 641) | def pre_install_commands(self):
    method post_install_commands (line 655) | def post_install_commands(self):
    method workspace (line 669) | def workspace(self) -> Workspace:
    method activate (line 677) | def activate(self):
    method deactivate (line 687) | def deactivate(self):
    method find (line 698) | def find(self):
    method create (line 708) | def create(self):
    method remove (line 716) | def remove(self):
    method exists (line 726) | def exists(self) -> bool:
    method install_project (line 734) | def install_project(self):
    method install_project_dev_mode (line 742) | def install_project_dev_mode(self):
    method dependencies_in_sync (line 751) | def dependencies_in_sync(self) -> bool:
    method sync_dependencies (line 760) | def sync_dependencies(self):
    method dependency_hash (line 769) | def dependency_hash(self):
    method app_status_creation (line 784) | def app_status_creation(self):
    method app_status_pre_installation (line 792) | def app_status_pre_installation(self):
    method app_status_post_installation (line 800) | def app_status_post_installation(self):
    method app_status_project_installation (line 808) | def app_status_project_installation(self):
    method app_status_dependency_state_check (line 820) | def app_status_dependency_state_check(self):
    method app_status_dependency_installation_check (line 833) | def app_status_dependency_installation_check(self):
    method app_status_dependency_synchronization (line 841) | def app_status_dependency_synchronization(self):
    method fs_context (line 849) | def fs_context(self) -> Generator[FileSystemContext, None, None]:
    method enter_shell (line 859) | def enter_shell(
    method run_shell_command (line 875) | def run_shell_command(self, command: str, **kwargs):
    method command_context (line 887) | def command_context(self):
    method resolve_commands (line 899) | def resolve_commands(self, commands: list[str]):
    method expand_command (line 907) | def expand_command(self, command):
    method construct_pip_install_command (line 924) | def construct_pip_install_command(self, args: list[str]):
    method join_command_args (line 937) | def join_command_args(self, args: list[str]):
    method apply_features (line 944) | def apply_features(self, requirement: str):
    method check_compatibility (line 955) | def check_compatibility(self):
    method get_env_vars (line 968) | def get_env_vars(self) -> EnvVars:
    method get_env_var_option (line 978) | def get_env_var_option(self, option: str) -> str:
    method get_context (line 984) | def get_context(self):
    method get_option_types (line 994) | def get_option_types() -> dict:
    method apply_context (line 1002) | def apply_context(self):
    method __enter__ (line 1006) | def __enter__(self):
    method __exit__ (line 1010) | def __exit__(self, exc_type, exc_value, traceback):
  class FileSystemContext (line 1014) | class FileSystemContext:
    method __init__ (line 1019) | def __init__(self, env: EnvironmentInterface, *, local_path: Path, env...
    method env (line 1025) | def env(self) -> EnvironmentInterface:
    method local_path (line 1032) | def local_path(self) -> Path:
    method env_path (line 1039) | def env_path(self) -> str:
    method join (line 1046) | def join(self, relative_path: str) -> FileSystemContext:
    method sync_env (line 1057) | def sync_env(self):
    method sync_local (line 1063) | def sync_local(self):
  class Workspace (line 1071) | class Workspace:
    method __init__ (line 1072) | def __init__(self, env: EnvironmentInterface, config: dict[str, Any]):
    method parallel (line 1077) | def parallel(self) -> bool:
    method get_dependencies (line 1085) | def get_dependencies(self) -> list[str]:
    method members (line 1127) | def members(self) -> list[WorkspaceMember]:
  class WorkspaceMember (line 1291) | class WorkspaceMember:
    method __init__ (line 1292) | def __init__(self, project: Project, *, features: tuple[str]):
    method name (line 1298) | def name(self) -> str:
    method has_static_dependencies (line 1302) | def has_static_dependencies(self) -> bool:
    method get_dependencies (line 1305) | def get_dependencies(self) -> tuple[list[str], dict[str, list[str]]]:
    method last_modified (line 1309) | def last_modified(self) -> float:
    method get_editable_requirement (line 1318) | def get_editable_requirement(self, *, editable: bool = True) -> str:
  function expand_script_commands (line 1326) | def expand_script_commands(env_name, script_name, commands, config, seen...
  function find_members (line 1362) | def find_members(root, relative_components):
  function _recurse_members (line 1378) | def _recurse_members(root, matcher_index, matchers):

FILE: src/hatch/env/system.py
  class SystemEnvironment (line 7) | class SystemEnvironment(EnvironmentInterface):
    method __init__ (line 10) | def __init__(self, *args, **kwargs):
    method find (line 16) | def find(self):
    method create (line 19) | def create(self):
    method remove (line 22) | def remove(self):
    method exists (line 25) | def exists(self):
    method install_project (line 28) | def install_project(self):
    method install_project_dev_mode (line 31) | def install_project_dev_mode(self):
    method dependencies_in_sync (line 36) | def dependencies_in_sync(self):
    method sync_dependencies (line 47) | def sync_dependencies(self):

FILE: src/hatch/env/utils.py
  function get_env_var (line 8) | def get_env_var(*, plugin_name: str, option: str) -> str:
  function get_env_var_option (line 12) | def get_env_var_option(*, plugin_name: str, option: str, default: str = ...
  function ensure_valid_environment (line 16) | def ensure_valid_environment(env_config: dict):
  function get_verbosity_flag (line 52) | def get_verbosity_flag(verbosity: int, *, adjustment=0) -> str:
  function add_verbosity_flag (line 63) | def add_verbosity_flag(command: list[str], verbosity: int, *, adjustment...

FILE: src/hatch/env/virtual.py
  class VirtualEnvironment (line 32) | class VirtualEnvironment(EnvironmentInterface):
    method __init__ (line 35) | def __init__(self, *args, **kwargs):
    method use_uv (line 88) | def use_uv(self) -> bool:
    method installer (line 92) | def installer(self) -> str:
    method explicit_uv_path (line 96) | def explicit_uv_path(self) -> str:
    method virtual_env_cls (line 100) | def virtual_env_cls(self) -> type[VirtualEnv]:
    method expose_uv (line 103) | def expose_uv(self):
    method uv_path (line 110) | def uv_path(self) -> str:
    method distributions (line 136) | def distributions(self) -> InstalledDistributions:
    method missing_dependencies (line 142) | def missing_dependencies(self) -> list[Dependency]:
    method get_option_types (line 146) | def get_option_types() -> dict:
    method activate (line 149) | def activate(self):
    method deactivate (line 152) | def deactivate(self):
    method find (line 155) | def find(self):
    method create (line 158) | def create(self):
    method remove (line 175) | def remove(self):
    method exists (line 185) | def exists(self):
    method install_project (line 188) | def install_project(self):
    method install_project_dev_mode (line 192) | def install_project_dev_mode(self):
    method dependencies_in_sync (line 198) | def dependencies_in_sync(self):
    method sync_dependencies (line 202) | def sync_dependencies(self):
    method command_context (line 242) | def command_context(self):
    method construct_pip_install_command (line 246) | def construct_pip_install_command(self, args: list[str]):
    method enter_shell (line 258) | def enter_shell(self, name: str, path: str, args: Iterable[str]):
    method check_compatibility (line 268) | def check_compatibility(self):
    method _preferred_python_version (line 287) | def _preferred_python_version(self):
    method parent_python (line 296) | def parent_python(self):
    method python_manager (line 306) | def python_manager(self) -> PythonManager:
    method get_interpreter_resolver_env (line 311) | def get_interpreter_resolver_env(self) -> dict[str, str]:
    method upgrade_possible_internal_python (line 323) | def upgrade_possible_internal_python(self, python_path: str) -> None:
    method _interpreter_is_compatible (line 335) | def _interpreter_is_compatible(self, interpreter: PythonInfo) -> bool:
    method _get_concrete_interpreter_path (line 342) | def _get_concrete_interpreter_path(self, python_version: str = "") -> ...
    method _resolve_external_interpreter_path (line 362) | def _resolve_external_interpreter_path(self, python_version: str) -> s...
    method _resolve_internal_interpreter_path (line 369) | def _resolve_internal_interpreter_path(self, python_version: str) -> s...
    method _find_existing_interpreter (line 378) | def _find_existing_interpreter(self, python_version: str = "") -> str ...
    method _get_available_distribution (line 386) | def _get_available_distribution(self, python_version: str = "") -> str...
    method _is_stable_path (line 422) | def _is_stable_path(self, executable: str) -> bool:
    method _python_sources (line 444) | def _python_sources(self) -> list[str]:
    method _python_resolvers (line 447) | def _python_resolvers(self) -> dict[str, Callable[[str], str | None]]:
    method _python_constraint (line 454) | def _python_constraint(self) -> SpecifierSet:
    method safe_activation (line 463) | def safe_activation(self):

FILE: src/hatch/errors/__init__.py
  class HatchError (line 1) | class HatchError(Exception):
  class PythonDistributionUnknownError (line 5) | class PythonDistributionUnknownError(HatchError):
  class PythonDistributionResolutionError (line 9) | class PythonDistributionResolutionError(HatchError):

FILE: src/hatch/index/core.py
  class IndexURLs (line 17) | class IndexURLs:
    method __init__ (line 18) | def __init__(self, repo: str):
  class PackageIndex (line 34) | class PackageIndex:
    method __init__ (line 35) | def __init__(self, repo: str, *, user="", auth="", ca_cert=None, clien...
    method client (line 52) | def client(self) -> httpx.Client:
    method upload_artifact (line 68) | def upload_artifact(self, artifact: Path, data: dict):
    method get_simple_api (line 104) | def get_simple_api(self, project: str) -> httpx.Response:

FILE: src/hatch/index/errors.py
  class ArtifactMetadataError (line 1) | class ArtifactMetadataError(Exception):

FILE: src/hatch/index/publish.py
  function get_wheel_form_data (line 19) | def get_wheel_form_data(artifact):
  function get_sdist_form_data (line 54) | def get_sdist_form_data(artifact):
  function parse_headers (line 84) | def parse_headers(metadata_file_contents):

FILE: src/hatch/plugin/manager.py
  class PluginManager (line 4) | class PluginManager(_PluginManager):
    method initialize (line 5) | def initialize(self):
    method hatch_register_environment (line 12) | def hatch_register_environment(self):
    method hatch_register_environment_collector (line 17) | def hatch_register_environment_collector(self):
    method hatch_register_publisher (line 22) | def hatch_register_publisher(self):
    method hatch_register_template (line 27) | def hatch_register_template(self):

FILE: src/hatch/plugin/specs.py
  function hatch_register_environment (line 5) | def hatch_register_environment():
  function hatch_register_environment_collector (line 10) | def hatch_register_environment_collector():
  function hatch_register_version_scheme (line 15) | def hatch_register_version_scheme():
  function hatch_register_publisher (line 20) | def hatch_register_publisher():
  function hatch_register_template (line 25) | def hatch_register_template():

FILE: src/hatch/plugin/utils.py
  function load_plugin_from_script (line 9) | def load_plugin_from_script(

FILE: src/hatch/project/config.py
  class ProjectConfig (line 19) | class ProjectConfig:
    method __init__ (line 20) | def __init__(self, root, config, plugin_manager=None):
    method build (line 39) | def build(self):
    method env (line 48) | def env(self):
    method env_requires_complex (line 60) | def env_requires_complex(self) -> list[Dependency]:
    method env_requires (line 87) | def env_requires(self):
    method env_collectors (line 94) | def env_collectors(self):
    method matrices (line 114) | def matrices(self):
    method matrix_variables (line 121) | def matrix_variables(self):
    method internal_envs (line 128) | def internal_envs(self):
    method internal_matrices (line 135) | def internal_matrices(self):
    method envs (line 142) | def envs(self):
    method publish (line 445) | def publish(self):
    method scripts (line 462) | def scripts(self):
    method finalize_env_overrides (line 502) | def finalize_env_overrides(self, option_types):
  class BuildConfig (line 519) | class BuildConfig:
    method __init__ (line 520) | def __init__(self, config: dict[str, Any]) -> None:
    method directory (line 525) | def directory(self) -> str:
    method dependencies (line 534) | def dependencies(self) -> list[str]:
    method hook_config (line 548) | def hook_config(self) -> dict[str, dict[str, Any]]:
    method __target_config (line 562) | def __target_config(self) -> dict[str, Any]:
    method target (line 570) | def target(self, target: str) -> BuildTargetConfig:
  class BuildTargetConfig (line 584) | class BuildTargetConfig:
    method __init__ (line 585) | def __init__(self, name: str, config: dict[str, Any], global_config: B...
    method directory (line 591) | def directory(self) -> str:
    method dependencies (line 600) | def dependencies(self) -> list[str]:
    method hook_config (line 618) | def hook_config(self) -> dict[str, dict[str, Any]]:
  function expand_script_commands (line 634) | def expand_script_commands(script_name, commands, config, seen, active):
  function _populate_default_env_values (line 668) | def _populate_default_env_values(env_name, data, config, seen, active):
  function finalize_hook_config (line 712) | def finalize_hook_config(hook_config: dict[str, dict[str, Any]]) -> dict...
  function env_var_enabled (line 729) | def env_var_enabled(env_var: str, *, default: bool = False) -> bool:

FILE: src/hatch/project/constants.py
  class BuildEnvVars (line 7) | class BuildEnvVars:

FILE: src/hatch/project/core.py
  class Project (line 23) | class Project:
    method __init__ (line 24) | def __init__(self, path: Path, *, name: str | None = None, config=None...
    method plugin_manager (line 47) | def plugin_manager(self):
    method config (line 56) | def config(self):
    method root (line 65) | def root(self) -> Path | None:
    method location (line 73) | def location(self) -> Path:
    method set_path (line 76) | def set_path(self, path: Path) -> None:
    method set_app (line 79) | def set_app(self, app: Application) -> None:
    method app (line 83) | def app(self) -> Application:
    method build_env (line 93) | def build_env(self) -> EnvironmentInterface:
    method build_frontend (line 102) | def build_frontend(self) -> BuildFrontend:
    method env_metadata (line 108) | def env_metadata(self) -> EnvironmentMetadata:
    method dependency_groups (line 112) | def dependency_groups(self) -> dict[str, Any]:
    method get_environment (line 142) | def get_environment(self, env_name: str | None = None) -> EnvironmentI...
    method managed_environment (line 185) | def managed_environment(
    method prepare_environment (line 198) | def prepare_environment(self, environment: EnvironmentInterface, *, ke...
    method prepare_build_environment (line 250) | def prepare_build_environment(self, *, targets: list[str] | None = Non...
    method get_dependencies (line 293) | def get_dependencies(self) -> tuple[list[str], dict[str, list[str]]]:
    method has_static_dependencies (line 316) | def has_static_dependencies(self) -> bool:
    method expand_environments (line 320) | def expand_environments(self, env_name: str) -> list[str]:
    method from_config (line 336) | def from_config(cls, config: RootConfig, project: str) -> Project | None:
    method find_project_root (line 356) | def find_project_root(self) -> Path | None:
    method ensure_cwd (line 375) | def ensure_cwd(self) -> Generator[Path, None, None]:
    method canonicalize_name (line 385) | def canonicalize_name(name: str, *, strict=True) -> str:
    method metadata (line 393) | def metadata(self):
    method raw_config (line 402) | def raw_config(self):
    method save_config (line 419) | def save_config(self, config):
    method initialize (line 426) | def initialize(project_file_path, template_config):

FILE: src/hatch/project/env.py
  function apply_overrides (line 35) | def apply_overrides(env_name, source, condition, condition_value, option...
  function _apply_override_to_mapping (line 67) | def _apply_override_to_mapping(env_name, option, data, source, condition...
  function _apply_override_to_array (line 132) | def _apply_override_to_array(env_name, option, data, source, condition, ...
  function _apply_override_to_string (line 179) | def _apply_override_to_string(
  function _apply_override_to_boolean (line 244) | def _apply_override_to_boolean(
  function _apply_override_to_workspace (line 309) | def _apply_override_to_workspace(env_name, option, data, source, conditi...
  function _resolve_condition (line 334) | def _resolve_condition(env_name, option, source, condition, condition_va...
  class EnvironmentMetadata (line 409) | class EnvironmentMetadata:
    method __init__ (line 410) | def __init__(self, data_dir: Path, project_path: Path):
    method dependency_hash (line 414) | def dependency_hash(self, environment: EnvironmentInterface) -> str:
    method update_dependency_hash (line 417) | def update_dependency_hash(self, environment: EnvironmentInterface, de...
    method reset (line 422) | def reset(self, environment: EnvironmentInterface) -> None:
    method _read (line 425) | def _read(self, environment: EnvironmentInterface) -> dict[str, Any]:
    method _write (line 434) | def _write(self, environment: EnvironmentInterface, metadata: dict[str...
    method _metadata_file (line 441) | def _metadata_file(self, environment: EnvironmentInterface) -> Path:
    method _storage_dir (line 450) | def _storage_dir(self) -> Path:

FILE: src/hatch/project/frontend/core.py
  class BuildFrontend (line 15) | class BuildFrontend:
    method __init__ (line 16) | def __init__(self, project: Project, env: EnvironmentInterface) -> None:
    method scripts (line 23) | def scripts(self) -> StandardBuildFrontendScripts:
    method hatch (line 27) | def hatch(self) -> HatchBuildFrontend:
    method build_sdist (line 30) | def build_sdist(self, directory: Path) -> Path:
    method build_wheel (line 54) | def build_wheel(self, directory: Path) -> Path:
    method get_requires (line 78) | def get_requires(self, build: Literal["sdist", "wheel", "editable"]) -...
    method get_core_metadata (line 100) | def get_core_metadata(self, *, editable: bool = False) -> dict[str, Any]:
  class HatchBuildFrontend (line 128) | class HatchBuildFrontend:
    method __init__ (line 129) | def __init__(self, project: Project, env: EnvironmentInterface) -> None:
    method scripts (line 135) | def scripts(self) -> HatchBuildFrontendScripts:
    method get_build_deps (line 138) | def get_build_deps(self, targets: list[str]) -> list[str]:
    method get_core_metadata (line 160) | def get_core_metadata(self) -> dict[str, Any]:
    method get_required_build_deps (line 182) | def get_required_build_deps(self, targets: list[str]) -> list[str]:
  class BuildFrontendScripts (line 204) | class BuildFrontendScripts:
    method __init__ (line 205) | def __init__(self, project: Project, env: EnvironmentInterface) -> None:
    method inject_data (line 210) | def inject_data(script: str, data: dict[str, Any]) -> str:
  class StandardBuildFrontendScripts (line 215) | class StandardBuildFrontendScripts(BuildFrontendScripts):
    method get_runner_script (line 216) | def get_runner_script(
    method get_requires (line 237) | def get_requires(
    method prepare_metadata (line 251) | def prepare_metadata(self, *, output_dir: str, project_root: str, edit...
    method build_wheel (line 259) | def build_wheel(self, *, output_dir: str, project_root: str, editable:...
    method build_sdist (line 267) | def build_sdist(self, *, output_dir: str, project_root: str) -> str:
  class HatchBuildFrontendScripts (line 276) | class HatchBuildFrontendScripts(BuildFrontendScripts):
    method get_build_deps (line 277) | def get_build_deps(self, *, output_dir: str, project_root: str, target...
    method get_core_metadata (line 287) | def get_core_metadata(self, *, output_dir: str, project_root: str) -> ...
  function hook_caller_script (line 298) | def hook_caller_script() -> str:
  function runner_script (line 306) | def runner_script() -> str:
  function hatch_build_deps_script (line 314) | def hatch_build_deps_script() -> str:
  function hatch_core_metadata_script (line 322) | def hatch_core_metadata_script() -> str:

FILE: src/hatch/project/frontend/scripts/build_deps.py
  function main (line 13) | def main() -> None:

FILE: src/hatch/project/frontend/scripts/core_metadata.py
  function main (line 13) | def main() -> None:

FILE: src/hatch/project/frontend/scripts/standard.py
  function main (line 13) | def main() -> int:

FILE: src/hatch/project/utils.py
  function parse_script_command (line 9) | def parse_script_command(command: str) -> tuple[str, str, bool]:
  function format_script_commands (line 20) | def format_script_commands(*, commands: list[str], args: str, ignore_exi...
  function parse_inline_script_metadata (line 30) | def parse_inline_script_metadata(script: str) -> dict[str, Any] | None:

FILE: src/hatch/publish/auth.py
  class AuthenticationCredentials (line 6) | class AuthenticationCredentials:
    method __init__ (line 7) | def __init__(
    method password (line 28) | def password(self) -> str:
    method username (line 34) | def username(self) -> str:
    method __get_password (line 39) | def __get_password(self) -> str:
    method __get_username (line 60) | def __get_username(self) -> str:
    method _read_previous_working_user_data (line 76) | def _read_previous_working_user_data(self) -> str | None:
    method _read_pypirc (line 85) | def _read_pypirc(self) -> str | None:
    method write_updated_data (line 104) | def write_updated_data(self):

FILE: src/hatch/publish/index.py
  class IndexPublisher (line 14) | class IndexPublisher(PublisherInterface):
    method get_repos (line 17) | def get_repos(self):
    method publish (line 48) | def publish(self, artifacts: list, options: dict):
  function recurse_artifacts (line 150) | def recurse_artifacts(artifacts: list, root) -> Iterable[Path]:
  function parse_artifacts (line 162) | def parse_artifacts(artifact_payload):

FILE: src/hatch/publish/plugin/hooks.py
  function hatch_register_publisher (line 6) | def hatch_register_publisher():

FILE: src/hatch/publish/plugin/interface.py
  class PublisherInterface (line 6) | class PublisherInterface(ABC):
    method __init__ (line 34) | def __init__(self, app, root, cache_dir, project_config, plugin_config):
    method app (line 44) | def app(self):
    method root (line 51) | def root(self):
    method cache_dir (line 58) | def cache_dir(self):
    method project_config (line 65) | def project_config(self) -> dict:
    method plugin_config (line 74) | def plugin_config(self) -> dict:
    method disable (line 85) | def disable(self):
    method publish (line 109) | def publish(self, artifacts: list[str], options: dict):

FILE: src/hatch/python/core.py
  class InstalledDistribution (line 14) | class InstalledDistribution:
    method __init__ (line 15) | def __init__(self, path: Path, distribution: Distribution, metadata: d...
    method path (line 21) | def path(self) -> Path:
    method name (line 25) | def name(self) -> str:
    method python_path (line 29) | def python_path(self) -> Path:
    method version (line 33) | def version(self) -> str:
    method metadata (line 37) | def metadata(self) -> dict[str, Any]:
    method needs_update (line 40) | def needs_update(self) -> bool:
    method metadata_filename (line 45) | def metadata_filename(cls) -> str:
  class PythonManager (line 49) | class PythonManager:
    method __init__ (line 50) | def __init__(self, directory: Path) -> None:
    method directory (line 54) | def directory(self) -> Path:
    method get_installed (line 57) | def get_installed(self) -> dict[str, InstalledDistribution]:
    method install (line 82) | def install(self, identifier: str) -> InstalledDistribution:
    method remove (line 125) | def remove(dist: InstalledDistribution) -> None:

FILE: src/hatch/python/resolve.py
  function custom_env_var (line 24) | def custom_env_var(prefix: str, name: str) -> str:
  function get_custom_source (line 28) | def get_custom_source(name: str) -> str | None:
  function get_custom_version (line 32) | def get_custom_version(name: str) -> str | None:
  function get_custom_path (line 36) | def get_custom_path(name: str) -> str | None:
  class Distribution (line 40) | class Distribution(ABC):
    method __init__ (line 41) | def __init__(self, name: str, source: str) -> None:
    method name (line 46) | def name(self) -> str:
    method source (line 50) | def source(self) -> str:
    method archive_name (line 54) | def archive_name(self) -> str:
    method unpack (line 57) | def unpack(self, archive: Path, directory: Path) -> None:
    method __unpack_tarfile (line 74) | def __unpack_tarfile(archive: Path, directory: Path, mode: Literal["r:...
    method version (line 87) | def version(self) -> Version:
    method python_path (line 92) | def python_path(self) -> str:
  class CPythonStandaloneDistribution (line 96) | class CPythonStandaloneDistribution(Distribution):
    method version (line 98) | def version(self) -> Version:
    method python_path (line 113) | def python_path(self) -> str:
  class PyPyOfficialDistribution (line 129) | class PyPyOfficialDistribution(Distribution):
    method version (line 131) | def version(self) -> Version:
    method python_path (line 142) | def python_path(self) -> str:
  function get_distribution (line 158) | def get_distribution(name: str, source: str = "", variant_cpu: str = "",...
  function get_compatible_distributions (line 194) | def get_compatible_distributions() -> dict[str, Distribution]:
  function _guess_linux_variant_cpu (line 207) | def _guess_linux_variant_cpu() -> str:
  function _get_default_variant_cpu (line 244) | def _get_default_variant_cpu(name: str, system: str, arch: str) -> str:
  function _get_default_variant_gil (line 268) | def _get_default_variant_gil() -> str:
  function _get_distribution_class (line 272) | def _get_distribution_class(source: str) -> type[Distribution]:

FILE: src/hatch/template/__init__.py
  class File (line 10) | class File:
    method __init__ (line 11) | def __init__(self, path: Path | None, contents: str = ""):
    method write (line 16) | def write(self, root):
  function find_template_files (line 25) | def find_template_files(module):

FILE: src/hatch/template/default.py
  class DefaultTemplate (line 7) | class DefaultTemplate(TemplateInterface):
    method __init__ (line 10) | def __init__(self, *args, **kwargs):
    method initialize_config (line 17) | def initialize_config(self, config):
    method get_files (line 76) | def get_files(self, config):
    method finalize_files (line 109) | def finalize_files(self, config, files):
  function get_license_text (line 121) | def get_license_text(config, license_id, license_text, creation_time):

FILE: src/hatch/template/files_default.py
  class PackageRoot (line 5) | class PackageRoot(File):
    method __init__ (line 6) | def __init__(
  class MetadataFile (line 14) | class MetadataFile(File):
    method __init__ (line 15) | def __init__(
  class Readme (line 23) | class Readme(File):
    method __init__ (line 43) | def __init__(
  class PyProject (line 75) | class PyProject(File):
    method __init__ (line 111) | def __init__(self, template_config: dict, plugin_config: dict):

FILE: src/hatch/template/files_feature_ci.py
  class CommandLinePackage (line 5) | class CommandLinePackage(File):
    method __init__ (line 51) | def __init__(

FILE: src/hatch/template/files_feature_cli.py
  class PackageEntryPoint (line 5) | class PackageEntryPoint(File):
    method __init__ (line 15) | def __init__(
  class CommandLinePackage (line 23) | class CommandLinePackage(File):
    method __init__ (line 36) | def __init__(

FILE: src/hatch/template/files_feature_tests.py
  class TestsPackageRoot (line 5) | class TestsPackageRoot(File):
    method __init__ (line 6) | def __init__(

FILE: src/hatch/template/plugin/hooks.py
  function hatch_register_template (line 6) | def hatch_register_template():

FILE: src/hatch/template/plugin/interface.py
  class TemplateInterface (line 1) | class TemplateInterface:
    method __init__ (line 5) | def __init__(self, plugin_config: dict, cache_dir, creation_time):
    method initialize_config (line 10) | def initialize_config(self, config):
    method get_files (line 16) | def get_files(self, config):  # noqa: ARG002, PLR6301
    method finalize_files (line 20) | def finalize_files(self, config, files):

FILE: src/hatch/utils/ci.py
  function running_in_ci (line 4) | def running_in_ci() -> bool:

FILE: src/hatch/utils/dep.py
  function normalize_marker_quoting (line 13) | def normalize_marker_quoting(text: str) -> str:
  function get_normalized_dependencies (line 18) | def get_normalized_dependencies(requirements: list[Requirement]) -> list...
  function hash_dependencies (line 23) | def hash_dependencies(requirements: list[Dependency]) -> str:
  function get_complex_dependencies (line 37) | def get_complex_dependencies(dependencies: list[str]) -> dict[str, Depen...
  function get_complex_features (line 47) | def get_complex_features(features: dict[str, list[str]]) -> dict[str, di...
  function get_complex_dependency_group (line 59) | def get_complex_dependency_group(

FILE: src/hatch/utils/env.py
  class PythonInfo (line 10) | class PythonInfo:
    method __init__ (line 11) | def __init__(self, platform: Platform, executable: str = "python") -> ...
    method dep_check_data (line 20) | def dep_check_data(self) -> dict[str, Any]:
    method environment (line 31) | def environment(self) -> dict[str, str]:
    method sys_path (line 38) | def sys_path(self) -> list[str]:

FILE: src/hatch/utils/fs.py
  function disk_sync (line 33) | def disk_sync(fd: FileDescriptorLike) -> None:
  class Path (line 37) | class Path(_PathBase):
    method long_id (line 39) | def long_id(self) -> str:
    method id (line 51) | def id(self) -> str:
    method ensure_dir_exists (line 54) | def ensure_dir_exists(self) -> None:
    method ensure_parent_dir_exists (line 57) | def ensure_parent_dir_exists(self) -> None:
    method expand (line 60) | def expand(self) -> Path:
    method remove (line 63) | def remove(self) -> None:
    method move (line 71) | def move(self, target):
    method wait_for_dir_removed (line 80) | def wait_for_dir_removed(self, timeout: int = 5) -> None:
    method write_atomic (line 94) | def write_atomic(self, data: str | bytes, *args: Any, **kwargs: Any) -...
    method as_cwd (line 106) | def as_cwd(self, *args: Any, **kwargs: Any) -> Generator[Path, None, N...
    method temp_hide (line 120) | def temp_hide(self) -> Generator[Path, None, None]:
    method from_uri (line 137) | def from_uri(cls, path: str) -> Path:
    method from_uri (line 143) | def from_uri(cls, path: str) -> Path:
  function temp_directory (line 148) | def temp_directory() -> Generator[Path, None, None]:
  function temp_chdir (line 156) | def temp_chdir(env_vars: dict[str, str] | None = None) -> Generator[Path...

FILE: src/hatch/utils/metadata.py
  function normalize_project_name (line 6) | def normalize_project_name(name: str) -> str:

FILE: src/hatch/utils/network.py
  function streaming_response (line 23) | def streaming_response(*args: Any, **kwargs: Any) -> Generator[httpx.Res...
  function download_file (line 45) | def download_file(path: Path, *args: Any, **kwargs: Any) -> None:

FILE: src/hatch/utils/platform.py
  function get_platform_name (line 18) | def get_platform_name() -> str:
  function normalize_platform_name (line 24) | def normalize_platform_name(platform_name: str) -> str:
  class Platform (line 29) | class Platform:
    method __init__ (line 30) | def __init__(self, display_func: Callable = print) -> None:
    method modules (line 47) | def modules(self) -> LazilyLoadedModules:
    method format_for_subprocess (line 54) | def format_for_subprocess(self, command: str | list[str], *, shell: bo...
    method exit_with_code (line 76) | def exit_with_code(code: str | int | None) -> None:
    method _run_command_integrated (line 79) | def _run_command_integrated(
    method run_command (line 90) | def run_command(self, command: str | list[str], *, shell: bool = False...
    method check_command (line 103) | def check_command(self, command: str | list[str], *, shell: bool = Fal...
    method check_command_output (line 114) | def check_command_output(self, command: str | list[str], *, shell: boo...
    method capture_process (line 132) | def capture_process(self, command: str | list[str], *, shell: bool = F...
    method populate_default_popen_kwargs (line 148) | def populate_default_popen_kwargs(self, kwargs: dict[str, Any], *, she...
    method stream_process_output (line 178) | def stream_process_output(process: Popen) -> Iterable[str]:
    method default_shell (line 184) | def default_shell(self) -> str:
    method join_command_args (line 200) | def join_command_args(self) -> Callable[[list[str]], str]:
    method format_file_uri (line 210) | def format_file_uri(self) -> Callable[[str], str]:
    method windows (line 220) | def windows(self) -> bool:
    method macos (line 227) | def macos(self) -> bool:
    method linux (line 234) | def linux(self) -> bool:
    method exit_with_command (line 240) | def exit_with_command(self, command: list[str]) -> None:
    method name (line 252) | def name(self) -> str:
    method display_name (line 266) | def display_name(self) -> str:
    method home (line 280) | def home(self) -> Path:
  class LazilyLoadedModules (line 292) | class LazilyLoadedModules:
    method __getattr__ (line 293) | def __getattr__(self, name: str) -> ModuleType:

FILE: src/hatch/utils/runner.py
  class ExecutionContext (line 9) | class ExecutionContext:
    method __init__ (line 10) | def __init__(
    method add_shell_command (line 29) | def add_shell_command(self, command: str | list[str]) -> None:
  function parse_matrix_variables (line 33) | def parse_matrix_variables(specs: tuple[str, ...]) -> dict[str, set[str]]:
  function select_environments (line 48) | def select_environments(

FILE: src/hatch/utils/shells.py
  function detect_shell (line 16) | def detect_shell(platform: Platform) -> tuple[str, str]:
  class ShellManager (line 26) | class ShellManager:
    method __init__ (line 27) | def __init__(self, environment: EnvironmentInterface) -> None:
    method enter_cmd (line 30) | def enter_cmd(self, path: str, args: Iterable[str], exe_dir: Path) -> ...
    method enter_powershell (line 33) | def enter_powershell(self, path: str, args: Iterable[str], exe_dir: Pa...
    method enter_pwsh (line 44) | def enter_pwsh(self, path: str, args: Iterable[str], exe_dir: Path) ->...
    method enter_xonsh (line 47) | def enter_xonsh(self, path: str, args: Iterable[str], exe_dir: Path) -...
    method enter_bash (line 64) | def enter_bash(self, path: str, args: Iterable[str], exe_dir: Path) ->...
    method enter_fish (line 75) | def enter_fish(self, path: str, args: Iterable[str], exe_dir: Path) ->...
    method enter_zsh (line 78) | def enter_zsh(self, path: str, args: Iterable[str], exe_dir: Path) -> ...
    method enter_ash (line 81) | def enter_ash(self, path: str, args: Iterable[str], exe_dir: Path) -> ...
    method enter_nu (line 84) | def enter_nu(self, path: str, args: Iterable[str], exe_dir: Path) -> N...
    method enter_tcsh (line 89) | def enter_tcsh(self, path: str, args: Iterable[str], exe_dir: Path) ->...
    method enter_csh (line 92) | def enter_csh(self, path: str, args: Iterable[str], exe_dir: Path) -> ...
    method spawn_linux_shell (line 97) | def spawn_linux_shell(
    method spawn_linux_shell (line 109) | def spawn_linux_shell(

FILE: src/hatch/utils/structures.py
  class EnvVars (line 11) | class EnvVars(dict):
    method __init__ (line 12) | def __init__(
    method __enter__ (line 36) | def __enter__(self) -> None:
    method __exit__ (line 40) | def __exit__(

FILE: src/hatch/utils/toml.py
  function load_toml_data (line 12) | def load_toml_data(data: str) -> dict[str, Any]:
  function load_toml_file (line 16) | def load_toml_file(path: str) -> dict[str, Any]:

FILE: src/hatch/venv/core.py
  class VirtualEnv (line 10) | class VirtualEnv:
    method __init__ (line 13) | def __init__(self, directory, platform, verbosity=0):
    method activate (line 22) | def activate(self):
    method deactivate (line 36) | def deactivate(self):
    method create (line 45) | def create(self, python, *, allow_system_packages=False):
    method remove (line 61) | def remove(self):
    method exists (line 64) | def exists(self):
    method executables_directory (line 68) | def executables_directory(self):
    method environment (line 96) | def environment(self):
    method sys_path (line 100) | def sys_path(self):
    method __enter__ (line 103) | def __enter__(self):
    method __exit__ (line 107) | def __exit__(self, exc_type, exc_value, traceback):
  class TempVirtualEnv (line 111) | class TempVirtualEnv(VirtualEnv):
    method __init__ (line 112) | def __init__(self, parent_python, platform, verbosity=0):
    method remove (line 119) | def remove(self):
    method __enter__ (line 123) | def __enter__(self):
    method __exit__ (line 127) | def __exit__(self, exc_type, exc_value, traceback):
  class UVVirtualEnv (line 132) | class UVVirtualEnv(VirtualEnv):
    method create (line 133) | def create(self, python, *, allow_system_packages=False):
  class TempUVVirtualEnv (line 142) | class TempUVVirtualEnv(TempVirtualEnv, UVVirtualEnv): ...

FILE: src/hatch/venv/utils.py
  function get_random_venv_name (line 5) | def get_random_venv_name():

FILE: tests/backend/builders/hooks/test_custom.py
  function test_no_path (line 9) | def test_no_path(isolation):
  function test_path_not_string (line 16) | def test_path_not_string(isolation):
  function test_nonexistent (line 23) | def test_nonexistent(isolation):
  function test_default (line 30) | def test_default(temp_dir, helpers):
  function test_explicit_path (line 52) | def test_explicit_path(temp_dir, helpers):
  function test_no_subclass (line 75) | def test_no_subclass(temp_dir, helpers):

FILE: tests/backend/builders/hooks/test_version.py
  class TestConfigPath (line 9) | class TestConfigPath:
    method test_correct (line 10) | def test_correct(self, isolation):
    method test_missing (line 16) | def test_missing(self, isolation):
    method test_not_string (line 23) | def test_not_string(self, isolation):
  class TestConfigTemplate (line 31) | class TestConfigTemplate:
    method test_correct (line 32) | def test_correct(self, isolation):
    method test_not_string (line 38) | def test_not_string(self, isolation):
  class TestConfigPattern (line 46) | class TestConfigPattern:
    method test_correct (line 47) | def test_correct(self, isolation):
    method test_not_string (line 53) | def test_not_string(self, isolation):
  class TestTemplate (line 61) | class TestTemplate:
    method test_default (line 62) | def test_default(self, temp_dir, helpers):
    method test_create_necessary_directories (line 102) | def test_create_necessary_directories(self, temp_dir, helpers):
    method test_custom (line 142) | def test_custom(self, temp_dir, helpers):
  class TestPattern (line 180) | class TestPattern:
    method test_default (line 181) | def test_default(self, temp_dir, helpers):
    method test_custom (line 224) | def test_custom(self, temp_dir, helpers):

FILE: tests/backend/builders/plugin/test_interface.py
  class TestClean (line 12) | class TestClean:
    method test_default (line 13) | def test_default(self, isolation):
  class TestPluginManager (line 18) | class TestPluginManager:
    method test_default (line 19) | def test_default(self, isolation):
    method test_reuse (line 24) | def test_reuse(self, isolation):
  class TestRawConfig (line 31) | class TestRawConfig:
    method test_default (line 32) | def test_default(self, isolation):
    method test_reuse (line 37) | def test_reuse(self, isolation):
    method test_read (line 43) | def test_read(self, temp_dir):
  class TestMetadata (line 53) | class TestMetadata:
    method test_base (line 54) | def test_base(self, isolation):
    method test_core (line 61) | def test_core(self, isolation):
    method test_hatch (line 67) | def test_hatch(self, isolation):
    method test_build_config (line 73) | def test_build_config(self, isolation):
    method test_build_config_not_table (line 79) | def test_build_config_not_table(self, isolation):
    method test_target_config (line 86) | def test_target_config(self, isolation):
    method test_target_config_not_table (line 93) | def test_target_config_not_table(self, isolation):
  class TestProjectID (line 102) | class TestProjectID:
    method test_normalization (line 103) | def test_normalization(self, isolation):
  class TestBuildValidation (line 110) | class TestBuildValidation:
    method test_unknown_version (line 111) | def test_unknown_version(self, isolation):
    method test_invalid_metadata (line 123) | def test_invalid_metadata(self, isolation):
  class TestHookConfig (line 138) | class TestHookConfig:
    method test_unknown (line 139) | def test_unknown(self, isolation):
  class TestDirectoryRecursion (line 147) | class TestDirectoryRecursion:
    method test_infinite_loop_prevention (line 149) | def test_infinite_loop_prevention(self, temp_dir):
    method test_only_include (line 169) | def test_only_include(self, temp_dir):
    method test_no_duplication_force_include_only (line 184) | def test_no_duplication_force_include_only(self, temp_dir):
    method test_no_duplication_force_include_and_selection (line 220) | def test_no_duplication_force_include_and_selection(self, temp_dir):
    method test_no_duplication_force_include_with_sources (line 254) | def test_no_duplication_force_include_with_sources(self, temp_dir):
    method test_exists (line 291) | def test_exists(self, temp_dir):
    method test_order (line 316) | def test_order(self, temp_dir):

FILE: tests/backend/builders/test_binary.py
  class ExpectedEnvVars (line 19) | class ExpectedEnvVars:
    method __init__ (line 20) | def __init__(self, env_vars: dict):
    method __eq__ (line 23) | def __eq__(self, other):
    method __hash__ (line 26) | def __hash__(self):  # no cov
  function cargo_install (line 30) | def cargo_install(*args: Any, **_kwargs: Any) -> subprocess.CompletedPro...
  function test_class (line 55) | def test_class():
  function test_class_legacy (line 59) | def test_class_legacy():
  function test_default_versions (line 63) | def test_default_versions(isolation):
  class TestScripts (line 69) | class TestScripts:
    method test_unset (line 70) | def test_unset(self, isolation):
    method test_default (line 76) | def test_default(self, isolation):
    method test_specific (line 88) | def test_specific(self, isolation):
    method test_not_array (line 101) | def test_not_array(self, isolation):
    method test_script_not_string (line 115) | def test_script_not_string(self, isolation):
    method test_unknown_script (line 131) | def test_unknown_script(self, isolation):
  class TestPythonVersion (line 146) | class TestPythonVersion:
    method test_default_no_source (line 147) | def test_default_no_source(self, isolation):
    method test_default_explicit_source (line 153) | def test_default_explicit_source(self, isolation):
    method test_set (line 160) | def test_set(self, isolation):
    method test_not_string (line 172) | def test_not_string(self, isolation):
    method test_compatibility (line 185) | def test_compatibility(self, isolation):
    method test_incompatible (line 197) | def test_incompatible(self, isolation):
  class TestPyAppVersion (line 213) | class TestPyAppVersion:
    method test_default (line 214) | def test_default(self, isolation):
    method test_set (line 220) | def test_set(self, isolation):
    method test_not_string (line 232) | def test_not_string(self, isolation):
  class TestBuildBootstrap (line 246) | class TestBuildBootstrap:
    method test_default (line 247) | def test_default(self, hatch, temp_dir, mocker):
    method test_default_build_target (line 287) | def test_default_build_target(self, hatch, temp_dir, mocker):
    method test_scripts (line 329) | def test_scripts(self, hatch, temp_dir, mocker):
    method test_scripts_build_target (line 373) | def test_scripts_build_target(self, hatch, temp_dir, mocker):
    method test_custom_cargo (line 419) | def test_custom_cargo(self, hatch, temp_dir, mocker):
    method test_no_cargo (line 459) | def test_no_cargo(self, hatch, temp_dir, mocker):
    method test_python_version (line 483) | def test_python_version(self, hatch, temp_dir, mocker):
    method test_pyapp_version (line 527) | def test_pyapp_version(self, hatch, temp_dir, mocker):
    method test_verbosity (line 567) | def test_verbosity(self, hatch, temp_dir, mocker):
    method test_local_build_with_build_target (line 609) | def test_local_build_with_build_target(self, hatch, temp_dir, mocker):
    method test_local_build_no_build_target (line 651) | def test_local_build_no_build_target(self, hatch, temp_dir, mocker):
    method test_legacy (line 691) | def test_legacy(self, hatch, temp_dir, mocker):

FILE: tests/backend/builders/test_config.py
  class TestDirectory (line 14) | class TestDirectory:
    method test_default (line 15) | def test_default(self, isolation):
    method test_target (line 20) | def test_target(self, isolation):
    method test_target_not_boolean (line 27) | def test_target_not_boolean(self, isolation):
    method test_global (line 35) | def test_global(self, isolation):
    method test_global_not_boolean (line 42) | def test_global_not_boolean(self, isolation):
    method test_target_overrides_global (line 50) | def test_target_overrides_global(self, isolation):
    method test_absolute_path (line 57) | def test_absolute_path(self, isolation):
  class TestSkipExcludedDirs (line 66) | class TestSkipExcludedDirs:
    method test_default (line 67) | def test_default(self, isolation):
    method test_target (line 72) | def test_target(self, isolation):
    method test_target_not_boolean (line 79) | def test_target_not_boolean(self, isolation):
    method test_global (line 89) | def test_global(self, isolation):
    method test_global_not_boolean (line 96) | def test_global_not_boolean(self, isolation):
    method test_target_overrides_global (line 104) | def test_target_overrides_global(self, isolation):
  class TestIgnoreVCS (line 116) | class TestIgnoreVCS:
    method test_default (line 117) | def test_default(self, isolation):
    method test_target (line 122) | def test_target(self, isolation):
    method test_target_not_boolean (line 129) | def test_target_not_boolean(self, isolation):
    method test_global (line 137) | def test_global(self, isolation):
    method test_global_not_boolean (line 144) | def test_global_not_boolean(self, isolation):
    method test_target_overrides_global (line 152) | def test_target_overrides_global(self, isolation):
  class TestRequireRuntimeDependencies (line 160) | class TestRequireRuntimeDependencies:
    method test_default (line 161) | def test_default(self, isolation):
    method test_target (line 166) | def test_target(self, isolation):
    method test_target_not_boolean (line 173) | def test_target_not_boolean(self, isolation):
    method test_global (line 184) | def test_global(self, isolation):
    method test_global_not_boolean (line 191) | def test_global_not_boolean(self, isolation):
    method test_target_overrides_global (line 199) | def test_target_overrides_global(self, isolation):
  class TestRequireRuntimeFeatures (line 216) | class TestRequireRuntimeFeatures:
    method test_default (line 217) | def test_default(self, isolation):
    method test_target (line 222) | def test_target(self, isolation):
    method test_target_not_array (line 232) | def test_target_not_array(self, isolation):
    method test_target_feature_not_string (line 242) | def test_target_feature_not_string(self, isolation):
    method test_target_feature_empty_string (line 253) | def test_target_feature_empty_string(self, isolation):
    method test_target_feature_unknown (line 266) | def test_target_feature_unknown(self, isolation):
    method test_global (line 283) | def test_global(self, isolation):
    method test_global_not_array (line 292) | def test_global_not_array(self, isolation):
    method test_global_feature_not_string (line 299) | def test_global_feature_not_string(self, isolation):
    method test_global_feature_empty_string (line 308) | def test_global_feature_empty_string(self, isolation):
    method test_global_feature_unknown (line 318) | def test_global_feature_unknown(self, isolation):
    method test_target_overrides_global (line 334) | def test_target_overrides_global(self, isolation):
  class TestOnlyPackages (line 352) | class TestOnlyPackages:
    method test_default (line 353) | def test_default(self, isolation):
    method test_target (line 358) | def test_target(self, isolation):
    method test_target_not_boolean (line 365) | def test_target_not_boolean(self, isolation):
    method test_global (line 373) | def test_global(self, isolation):
    method test_global_not_boolean (line 380) | def test_global_not_boolean(self, isolation):
    method test_target_overrides_global (line 388) | def test_target_overrides_global(self, isolation):
  class TestReproducible (line 396) | class TestReproducible:
    method test_default (line 397) | def test_default(self, isolation):
    method test_target (line 402) | def test_target(self, isolation):
    method test_target_not_boolean (line 409) | def test_target_not_boolean(self, isolation):
    method test_global (line 417) | def test_global(self, isolation):
    method test_global_not_boolean (line 424) | def test_global_not_boolean(self, isolation):
    method test_target_overrides_global (line 432) | def test_target_overrides_global(self, isolation):
  class TestDevModeDirs (line 440) | class TestDevModeDirs:
    method test_default (line 441) | def test_default(self, isolation):
    method test_global_invalid_type (line 446) | def test_global_invalid_type(self, isolation):
    method test_global (line 453) | def test_global(self, isolation):
    method test_global_pattern_not_string (line 459) | def test_global_pattern_not_string(self, isolation):
    method test_global_pattern_empty_string (line 466) | def test_global_pattern_empty_string(self, isolation):
    method test_target (line 475) | def test_target(self, isolation):
    method test_target_pattern_not_string (line 482) | def test_target_pattern_not_string(self, isolation):
    method test_target_pattern_empty_string (line 492) | def test_target_pattern_empty_string(self, isolation):
    method test_target_overrides_global (line 503) | def test_target_overrides_global(self, isolation):
  class TestDevModeExact (line 513) | class TestDevModeExact:
    method test_default (line 514) | def test_default(self, isolation):
    method test_target (line 519) | def test_target(self, isolation):
    method test_target_not_boolean (line 526) | def test_target_not_boolean(self, isolation):
    method test_global (line 534) | def test_global(self, isolation):
    method test_global_not_boolean (line 541) | def test_global_not_boolean(self, isolation):
    method test_target_overrides_global (line 549) | def test_target_overrides_global(self, isolation):
  class TestPackages (line 557) | class TestPackages:
    method test_default (line 558) | def test_default(self, isolation):
    method test_global_invalid_type (line 563) | def test_global_invalid_type(self, isolation):
    method test_global (line 570) | def test_global(self, isolation):
    method test_global_package_not_string (line 577) | def test_global_package_not_string(self, isolation):
    method test_global_package_empty_string (line 584) | def test_global_package_empty_string(self, isolation):
    method test_target (line 593) | def test_target(self, isolation):
    method test_target_package_not_string (line 601) | def test_target_package_not_string(self, isolation):
    method test_target_package_empty_string (line 611) | def test_target_package_empty_string(self, isolation):
    method test_target_overrides_global (line 621) | def test_target_overrides_global(self, isolation):
    method test_no_source (line 631) | def test_no_source(self, isolation):
  class TestSources (line 639) | class TestSources:
    method test_default (line 640) | def test_default(self, isolation):
    method test_global_invalid_type (line 646) | def test_global_invalid_type(self, isolation):
    method test_global_array (line 653) | def test_global_array(self, isolation):
    method test_global_array_source_not_string (line 661) | def test_global_array_source_not_string(self, isolation):
    method test_global_array_source_empty_string (line 668) | def test_global_array_source_empty_string(self, isolation):
    method test_global_mapping (line 675) | def test_global_mapping(self, isolation):
    method test_global_mapping_source_empty_string (line 683) | def test_global_mapping_source_empty_string(self, isolation):
    method test_global_mapping_path_empty_string (line 692) | def test_global_mapping_path_empty_string(self, isolation):
    method test_global_mapping_replacement_not_string (line 700) | def test_global_mapping_replacement_not_string(self, isolation):
    method test_target_invalid_type (line 709) | def test_target_invalid_type(self, isolation):
    method test_target_array (line 719) | def test_target_array(self, isolation):
    method test_target_array_source_not_string (line 728) | def test_target_array_source_not_string(self, isolation):
    method test_target_array_source_empty_string (line 738) | def test_target_array_source_empty_string(self, isolation):
    method test_target_mapping (line 748) | def test_target_mapping(self, isolation):
    method test_target_mapping_source_empty_string (line 757) | def test_target_mapping_source_empty_string(self, isolation):
    method test_target_mapping_path_empty_string (line 766) | def test_target_mapping_path_empty_string(self, isolation):
    method test_target_mapping_replacement_not_string (line 775) | def test_target_mapping_replacement_not_string(self, isolation):
    method test_target_overrides_global (line 786) | def test_target_overrides_global(self, isolation):
    method test_no_source (line 796) | def test_no_source(self, isolation):
    method test_compatible_with_packages (line 804) | def test_compatible_with_packages(self, isolation):
  class TestForceInclude (line 813) | class TestForceInclude:
    method test_default (line 814) | def test_default(self, isolation):
    method test_global_invalid_type (line 819) | def test_global_invalid_type(self, isolation):
    method test_global_absolute (line 826) | def test_global_absolute(self, isolation):
    method test_global_relative (line 832) | def test_global_relative(self, isolation):
    method test_global_source_empty_string (line 838) | def test_global_source_empty_string(self, isolation):
    method test_global_relative_path_not_string (line 847) | def test_global_relative_path_not_string(self, isolation):
    method test_global_relative_path_empty_string (line 856) | def test_global_relative_path_empty_string(self, isolation):
    method test_target_invalid_type (line 866) | def test_target_invalid_type(self, isolation):
    method test_target_absolute (line 874) | def test_target_absolute(self, isolation):
    method test_target_relative (line 885) | def test_target_relative(self, isolation):
    method test_target_source_empty_string (line 892) | def test_target_source_empty_string(self, isolation):
    method test_target_relative_path_not_string (line 903) | def test_target_relative_path_not_string(self, isolation):
    method test_target_relative_path_empty_string (line 914) | def test_target_relative_path_empty_string(self, isolation):
    method test_order (line 928) | def test_order(self, isolation):
  class TestOnlyInclude (line 951) | class TestOnlyInclude:
    method test_default (line 952) | def test_default(self, isolation):
    method test_global_invalid_type (line 957) | def test_global_invalid_type(self, isolation):
    method test_global_path_not_string (line 964) | def test_global_path_not_string(self, isolation):
    method test_global_not_relative (line 972) | def test_global_not_relative(self, isolation, path):
    method test_global_duplicate (line 981) | def test_global_duplicate(self, isolation):
    method test_global_correct (line 990) | def test_global_correct(self, isolation):
    method test_target_invalid_type (line 996) | def test_target_invalid_type(self, isolation):
    method test_target_path_not_string (line 1004) | def test_target_path_not_string(self, isolation):
    method test_target_not_relative (line 1015) | def test_target_not_relative(self, isolation, path):
    method test_target_duplicate (line 1025) | def test_target_duplicate(self, isolation):
    method test_target_correct (line 1036) | def test_target_correct(self, isolation):
  class TestVersions (line 1044) | class TestVersions:
    method test_default_known (line 1045) | def test_default_known(self, isolation):
    method test_default_override (line 1052) | def test_default_override(self, isolation):
    method test_invalid_type (line 1059) | def test_invalid_type(self, isolation):
    method test_correct (line 1069) | def test_correct(self, isolation):
    method test_empty_default (line 1077) | def test_empty_default(self, isolation):
    method test_version_not_string (line 1085) | def test_version_not_string(self, isolation):
    method test_version_empty_string (line 1095) | def test_version_empty_string(self, isolation):
    method test_unknown_version (line 1105) | def test_unknown_version(self, isolation):
  class TestHookConfig (line 1117) | class TestHookConfig:
    method test_default (line 1118) | def test_default(self, isolation):
    method test_target_not_table (line 1123) | def test_target_not_table(self, isolation):
    method test_target_hook_not_table (line 1131) | def test_target_hook_not_table(self, isolation):
    method test_global_not_table (line 1139) | def test_global_not_table(self, isolation):
    method test_global_hook_not_table (line 1146) | def test_global_hook_not_table(self, isolation):
    method test_global (line 1153) | def test_global(self, isolation):
    method test_order (line 1159) | def test_order(self, isolation):
    method test_target_overrides_global (line 1172) | def test_target_overrides_global(self, isolation):
    method test_env_var_no_hooks (line 1185) | def test_env_var_no_hooks(self, isolation):
    method test_enable_by_default (line 1192) | def test_enable_by_default(self, isolation):
    method test_env_var_all_override_enable_by_default (line 1210) | def test_env_var_all_override_enable_by_default(self, isolation):
    method test_env_var_specific_override_enable_by_default (line 1233) | def test_env_var_specific_override_enable_by_default(self, isolation):
  class TestDependencies (line 1256) | class TestDependencies:
    method test_default (line 1257) | def test_default(self, isolation):
    method test_target_not_array (line 1262) | def test_target_not_array(self, isolation):
    method test_target_dependency_not_string (line 1270) | def test_target_dependency_not_string(self, isolation):
    method test_global_not_array (line 1280) | def test_global_not_array(self, isolation):
    method test_global_dependency_not_string (line 1288) | def test_global_dependency_not_string(self, isolation):
    method test_hook_require_runtime_dependencies_not_boolean (line 1296) | def test_hook_require_runtime_dependencies_not_boolean(self, isolation):
    method test_hook_require_runtime_features_not_array (line 1306) | def test_hook_require_runtime_features_not_array(self, isolation):
    method test_hook_require_runtime_features_feature_not_string (line 1314) | def test_hook_require_runtime_features_feature_not_string(self, isolat...
    method test_hook_require_runtime_features_feature_empty_string (line 1324) | def test_hook_require_runtime_features_feature_empty_string(self, isol...
    method test_hook_require_runtime_features_feature_unknown (line 1335) | def test_hook_require_runtime_features_feature_unknown(self, isolation):
    method test_hook_dependencies_not_array (line 1352) | def test_hook_dependencies_not_array(self, isolation):
    method test_hook_dependency_not_string (line 1360) | def test_hook_dependency_not_string(self, isolation):
    method test_correct (line 1370) | def test_correct(self, isolation):
    method test_require_runtime_dependencies (line 1387) | def test_require_runtime_dependencies(self, isolation):
    method test_require_runtime_features (line 1406) | def test_require_runtime_features(self, isolation):
    method test_env_var_no_hooks (line 1425) | def test_env_var_no_hooks(self, isolation):
    method test_hooks_enable_by_default (line 1445) | def test_hooks_enable_by_default(self, isolation):
    method test_hooks_env_var_all_override_enable_by_default (line 1464) | def test_hooks_env_var_all_override_enable_by_default(self, isolation):
    method test_hooks_env_var_specific_override_enable_by_default (line 1484) | def test_hooks_env_var_specific_override_enable_by_default(self, isola...
    method test_hooks_require_runtime_dependencies (line 1504) | def test_hooks_require_runtime_dependencies(self, isolation):
    method test_hooks_require_runtime_dependencies_disabled (line 1523) | def test_hooks_require_runtime_dependencies_disabled(self, isolation):
    method test_hooks_require_runtime_features (line 1546) | def test_hooks_require_runtime_features(self, isolation):
    method test_hooks_require_runtime_features_disabled (line 1565) | def test_hooks_require_runtime_features_disabled(self, isolation):
  class TestFileSelectionDefaults (line 1589) | class TestFileSelectionDefaults:
    method test_include (line 1590) | def test_include(self, isolation):
    method test_exclude (line 1595) | def test_exclude(self, isolation):
    method test_packages (line 1600) | def test_packages(self, isolation):
    method test_only_include (line 1605) | def test_only_include(self, isolation):
    method test_global_exclude (line 1610) | def test_global_exclude(self, isolation):
  class TestPatternInclude (line 1616) | class TestPatternInclude:
    method test_default (line 1617) | def test_default(self, isolation):
    method test_global_becomes_spec (line 1622) | def test_global_becomes_spec(self, isolation):
    method test_global_invalid_type (line 1628) | def test_global_invalid_type(self, isolation):
    method test_global (line 1636) | def test_global(self, isolation, separator, platform):
    method test_global_pattern_not_string (line 1647) | def test_global_pattern_not_string(self, isolation):
    method test_global_pattern_empty_string (line 1654) | def test_global_pattern_empty_string(self, isolation):
    method test_global_packages_included (line 1664) | def test_global_packages_included(self, isolation, separator, platform):
    method test_target (line 1676) | def test_target(self, isolation, separator, platform):
    method test_target_pattern_not_string (line 1688) | def test_target_pattern_not_string(self, isolation):
    method test_target_pattern_empty_string (line 1698) | def test_target_pattern_empty_string(self, isolation):
    method test_target_overrides_global (line 1709) | def test_target_overrides_global(self, isolation, separator, platform):
    method test_target_packages_included (line 1721) | def test_target_packages_included(self, isolation, separator, platform):
  class TestPatternExclude (line 1734) | class TestPatternExclude:
    method test_default (line 1736) | def test_default(self, isolation, separator, platform):
    method test_global_invalid_type (line 1745) | def test_global_invalid_type(self, isolation):
    method test_global (line 1753) | def test_global(self, isolation, separator, platform):
    method test_global_pattern_not_string (line 1764) | def test_global_pattern_not_string(self, isolation):
    method test_global_pattern_empty_string (line 1771) | def test_global_pattern_empty_string(self, isolation):
    method test_target (line 1781) | def test_target(self, isolation, separator, platform):
    method test_target_pattern_not_string (line 1793) | def test_target_pattern_not_string(self, isolation):
    method test_target_pattern_empty_string (line 1803) | def test_target_pattern_empty_string(self, isolation):
    method test_target_overrides_global (line 1814) | def test_target_overrides_global(self, isolation, separator, platform):
    method test_vcs_git (line 1826) | def test_vcs_git(self, temp_dir, separator, platform):
    method test_ignore_vcs_git (line 1843) | def test_ignore_vcs_git(self, temp_dir, separator, platform):
    method test_vcs_git_boundary (line 1858) | def test_vcs_git_boundary(self, temp_dir, separator, platform):
    method test_vcs_git_exclude_whitelisted_file (line 1877) | def test_vcs_git_exclude_whitelisted_file(self, temp_dir, separator, p...
    method test_vcs_mercurial (line 1892) | def test_vcs_mercurial(self, temp_dir, separator, platform):
    method test_ignore_vcs_mercurial (line 1909) | def test_ignore_vcs_mercurial(self, temp_dir, separator, platform):
    method test_vcs_mercurial_boundary (line 1924) | def test_vcs_mercurial_boundary(self, temp_dir, separator, platform):
    method test_override_default_global_exclude_patterns (line 1942) | def test_override_default_global_exclude_patterns(self, isolation):
  class TestPatternArtifacts (line 1950) | class TestPatternArtifacts:
    method test_default (line 1951) | def test_default(self, isolation):
    method test_global_becomes_spec (line 1956) | def test_global_becomes_spec(self, isolation):
    method test_global_invalid_type (line 1962) | def test_global_invalid_type(self, isolation):
    method test_global (line 1970) | def test_global(self, isolation, separator, platform):
    method test_global_pattern_not_string (line 1981) | def test_global_pattern_not_string(self, isolation):
    method test_global_pattern_empty_string (line 1988) | def test_global_pattern_empty_string(self, isolation):
    method test_target (line 1998) | def test_target(self, isolation, separator, platform):
    method test_target_pattern_not_string (line 2010) | def test_target_pattern_not_string(self, isolation):
    method test_target_pattern_empty_string (line 2020) | def test_target_pattern_empty_string(self, isolation):
    method test_target_overrides_global (line 2031) | def test_target_overrides_global(self, isolation, separator, platform):
  class TestPatternMatching (line 2043) | class TestPatternMatching:
    method test_include_explicit (line 2044) | def test_include_explicit(self, isolation):
    method test_no_include_greedy (line 2051) | def test_no_include_greedy(self, isolation):
    method test_exclude_precedence (line 2057) | def test_exclude_precedence(self, isolation):
    method test_artifact_super_precedence (line 2064) | def test_artifact_super_precedence(self, isolation):

FILE: tests/backend/builders/test_custom.py
  function test_target_config_not_table (line 10) | def test_target_config_not_table(isolation):
  function test_no_path (line 17) | def test_no_path(isolation):
  function test_path_not_string (line 30) | def test_path_not_string(isolation):
  function test_nonexistent (line 37) | def test_nonexistent(isolation):
  function test_default (line 44) | def test_default(hatch, helpers, temp_dir, config_file):
  function test_explicit_path (line 122) | def test_explicit_path(hatch, helpers, temp_dir, config_file):
  function test_no_subclass (line 201) | def test_no_subclass(hatch, helpers, temp_dir):
  function test_multiple_subclasses (line 249) | def test_multiple_subclasses(hatch, helpers, temp_dir):
  function test_dynamic_dependencies (line 297) | def test_dynamic_dependencies(hatch, helpers, temp_dir, config_file):

FILE: tests/backend/builders/test_sdist.py
  function test_class (line 13) | def test_class():
  function test_default_versions (line 17) | def test_default_versions(isolation):
  class TestSupportLegacy (line 23) | class TestSupportLegacy:
    method test_default (line 24) | def test_default(self, isolation):
    method test_target (line 29) | def test_target(self, isolation):
  class TestCoreMetadataConstructor (line 36) | class TestCoreMetadataConstructor:
    method test_default (line 37) | def test_default(self, isolation):
    method test_not_string (line 43) | def test_not_string(self, isolation):
    method test_unknown (line 52) | def test_unknown(self, isolation):
  class TestStrictNaming (line 66) | class TestStrictNaming:
    method test_default (line 67) | def test_default(self, isolation):
    method test_target (line 72) | def test_target(self, isolation):
    method test_target_not_boolean (line 78) | def test_target_not_boolean(self, isolation):
    method test_global (line 85) | def test_global(self, isolation):
    method test_global_not_boolean (line 91) | def test_global_not_boolean(self, isolation):
    method test_target_overrides_global (line 98) | def test_target_overrides_global(self, isolation):
  class TestConstructSetupPyFile (line 105) | class TestConstructSetupPyFile:
    method test_default (line 106) | def test_default(self, helpers, isolation):
    method test_packages (line 121) | def test_packages(self, helpers, isolation):
    method test_description (line 140) | def test_description(self, helpers, isolation):
    method test_readme (line 160) | def test_readme(self, helpers, isolation):
    method test_authors_name (line 186) | def test_authors_name(self, helpers, isolation):
    method test_authors_email (line 206) | def test_authors_email(self, helpers, isolation):
    method test_authors_name_and_email (line 226) | def test_authors_name_and_email(self, helpers, isolation):
    method test_authors_multiple (line 248) | def test_authors_multiple(self, helpers, isolation):
    method test_maintainers_name (line 268) | def test_maintainers_name(self, helpers, isolation):
    method test_maintainers_email (line 288) | def test_maintainers_email(self, helpers, isolation):
    method test_maintainers_name_and_email (line 308) | def test_maintainers_name_and_email(self, helpers, isolation):
    method test_maintainers_multiple (line 330) | def test_maintainers_multiple(self, helpers, isolation):
    method test_classifiers (line 350) | def test_classifiers(self, helpers, isolation):
    method test_dependencies (line 377) | def test_dependencies(self, helpers, isolation):
    method test_dependencies_extra (line 400) | def test_dependencies_extra(self, helpers, isolation):
    method test_optional_dependencies (line 424) | def test_optional_dependencies(self, helpers, isolation):
    method test_scripts (line 462) | def test_scripts(self, helpers, isolation):
    method test_gui_scripts (line 487) | def test_gui_scripts(self, helpers, isolation):
    method test_entry_points (line 514) | def test_entry_points(self, helpers, isolation):
    method test_all (line 552) | def test_all(self, helpers, isolation):
  class TestBuildStandard (line 637) | class TestBuildStandard:
    method test_default (line 638) | def test_default(self, hatch, helpers, temp_dir, config_file):
    method test_default_no_reproducible (line 688) | def test_default_no_reproducible(self, hatch, helpers, temp_dir, confi...
    method test_default_support_legacy (line 739) | def test_default_support_legacy(self, hatch, helpers, temp_dir, config...
    method test_default_build_script_artifacts (line 787) | def test_default_build_script_artifacts(self, hatch, helpers, temp_dir...
    method test_default_build_script_extra_dependencies (line 861) | def test_default_build_script_extra_dependencies(self, hatch, helpers,...
    method test_include_project_file (line 936) | def test_include_project_file(self, hatch, helpers, temp_dir, config_f...
    method test_project_file_always_included (line 988) | def test_project_file_always_included(self, hatch, helpers, temp_dir, ...
    method test_config_file_always_included (line 1049) | def test_config_file_always_included(self, hatch, helpers, temp_dir, c...
    method test_include_readme (line 1112) | def test_include_readme(self, hatch, helpers, temp_dir, config_file):
    method test_readme_always_included (line 1162) | def test_readme_always_included(self, hatch, helpers, temp_dir, config...
    method test_include_license_files (line 1219) | def test_include_license_files(self, hatch, helpers, temp_dir, config_...
    method test_license_files_always_included (line 1269) | def test_license_files_always_included(self, hatch, helpers, temp_dir,...
    method test_default_vcs_git_exclusion_files (line 1326) | def test_default_vcs_git_exclusion_files(self, hatch, helpers, temp_di...
    method test_default_vcs_mercurial_exclusion_files (line 1384) | def test_default_vcs_mercurial_exclusion_files(self, hatch, helpers, t...
    method test_no_strict_naming (line 1456) | def test_no_strict_naming(self, hatch, helpers, temp_dir, config_file):
    method test_file_permissions_normalized (line 1506) | def test_file_permissions_normalized(self, hatch, temp_dir, config_file):

FILE: tests/backend/builders/test_wheel.py
  function sys_tags (line 22) | def sys_tags():
  function get_python_versions_tag (line 35) | def get_python_versions_tag():
  function extract_zip (line 39) | def extract_zip(zip_path: Path, target: Path) -> None:
  function test_class (line 47) | def test_class():
  function test_default_versions (line 51) | def test_default_versions(isolation):
  class TestDefaultFileSelection (line 57) | class TestDefaultFileSelection:
    method test_already_defined (line 58) | def test_already_defined(self, temp_dir):
    method test_flat_layout (line 83) | def test_flat_layout(self, temp_dir):
    method test_src_layout (line 110) | def test_src_layout(self, temp_dir):
    method test_single_module (line 133) | def test_single_module(self, temp_dir):
    method test_namespace (line 152) | def test_namespace(self, temp_dir):
    method test_default_error (line 168) | def test_default_error(self, temp_dir):
    method test_bypass_selection_option (line 198) | def test_bypass_selection_option(self, temp_dir):
    method test_force_include_option_considered_selection (line 210) | def test_force_include_option_considered_selection(self, temp_dir):
    method test_force_include_build_data_considered_selection (line 222) | def test_force_include_build_data_considered_selection(self, temp_dir):
    method test_artifacts_build_data_considered_selection (line 233) | def test_artifacts_build_data_considered_selection(self, temp_dir):
    method test_unnormalized_name_with_unnormalized_directory (line 244) | def test_unnormalized_name_with_unnormalized_directory(self, temp_dir):
    method test_unnormalized_name_with_normalized_directory (line 254) | def test_unnormalized_name_with_normalized_directory(self, temp_dir):
  class TestCoreMetadataConstructor (line 265) | class TestCoreMetadataConstructor:
    method test_default (line 266) | def test_default(self, isolation):
    method test_not_string (line 272) | def test_not_string(self, isolation):
    method test_unknown (line 281) | def test_unknown(self, isolation):
  class TestSharedData (line 295) | class TestSharedData:
    method test_default (line 296) | def test_default(self, isolation):
    method test_invalid_type (line 301) | def test_invalid_type(self, isolation):
    method test_absolute (line 308) | def test_absolute(self, isolation):
    method test_relative (line 318) | def test_relative(self, isolation):
    method test_source_empty_string (line 324) | def test_source_empty_string(self, isolation):
    method test_relative_path_not_string (line 334) | def test_relative_path_not_string(self, isolation):
    method test_relative_path_empty_string (line 344) | def test_relative_path_empty_string(self, isolation):
    method test_order (line 357) | def test_order(self, isolation):
  class TestSharedScripts (line 384) | class TestSharedScripts:
    method test_default (line 385) | def test_default(self, isolation):
    method test_invalid_type (line 390) | def test_invalid_type(self, isolation):
    method test_absolute (line 397) | def test_absolute(self, isolation):
    method test_relative (line 407) | def test_relative(self, isolation):
    method test_source_empty_string (line 413) | def test_source_empty_string(self, isolation):
    method test_relative_path_not_string (line 423) | def test_relative_path_not_string(self, isolation):
    method test_relative_path_empty_string (line 433) | def test_relative_path_empty_string(self, isolation):
    method test_order (line 446) | def test_order(self, isolation):
  class TestExtraMetadata (line 473) | class TestExtraMetadata:
    method test_default (line 474) | def test_default(self, isolation):
    method test_invalid_type (line 479) | def test_invalid_type(self, isolation):
    method test_absolute (line 486) | def test_absolute(self, isolation):
    method test_relative (line 496) | def test_relative(self, isolation):
    method test_source_empty_string (line 502) | def test_source_empty_string(self, isolation):
    method test_relative_path_not_string (line 512) | def test_relative_path_not_string(self, isolation):
    method test_relative_path_empty_string (line 522) | def test_relative_path_empty_string(self, isolation):
    method test_order (line 535) | def test_order(self, isolation):
  class TestStrictNaming (line 562) | class TestStrictNaming:
    method test_default (line 563) | def test_default(self, isolation):
    method test_target (line 568) | def test_target(self, isolation):
    method test_target_not_boolean (line 574) | def test_target_not_boolean(self, isolation):
    method test_global (line 581) | def test_global(self, isolation):
    method test_global_not_boolean (line 587) | def test_global_not_boolean(self, isolation):
    method test_target_overrides_global (line 594) | def test_target_overrides_global(self, isolation):
  class TestMacOSMaxCompat (line 601) | class TestMacOSMaxCompat:
    method test_default (line 602) | def test_default(self, isolation):
    method test_correct (line 607) | def test_correct(self, isolation):
    method test_not_boolean (line 613) | def test_not_boolean(self, isolation):
  class TestBypassSelection (line 623) | class TestBypassSelection:
    method test_default (line 624) | def test_default(self, isolation):
    method test_correct (line 629) | def test_correct(self, isolation):
    method test_not_boolean (line 635) | def test_not_boolean(self, isolation):
  class TestConstructEntryPointsFile (line 645) | class TestConstructEntryPointsFile:
    method test_default (line 646) | def test_default(self, isolation):
    method test_scripts (line 652) | def test_scripts(self, isolation, helpers):
    method test_gui_scripts (line 664) | def test_gui_scripts(self, isolation, helpers):
    method test_entry_points (line 676) | def test_entry_points(self, isolation, helpers):
    method test_all (line 699) | def test_all(self, isolation, helpers):
  class TestBuildStandard (line 733) | class TestBuildStandard:
    method test_default_auto_detection (line 734) | def test_default_auto_detection(self, hatch, helpers, temp_dir, config...
    method test_default_reproducible_timestamp (line 796) | def test_default_reproducible_timestamp(self, hatch, helpers, temp_dir...
    method test_default_no_reproducible (line 849) | def test_default_no_reproducible(self, hatch, helpers, temp_dir, confi...
    method test_default_multiple_licenses (line 902) | def test_default_multiple_licenses(self, hatch, helpers, config_file, ...
    method test_default_include (line 955) | def test_default_include(self, hatch, helpers, temp_dir, config_file):
    method test_default_only_packages (line 1005) | def test_default_only_packages(self, hatch, helpers, temp_dir, config_...
    method test_default_only_packages_artifact_override (line 1061) | def test_default_only_packages_artifact_override(self, hatch, helpers,...
    method test_default_python_constraint (line 1125) | def test_default_python_constraint(
    method test_default_build_script_default_tag (line 1176) | def test_default_build_script_default_tag(self, hatch, helpers, temp_d...
    method test_default_build_script_set_tag (line 1243) | def test_default_build_script_set_tag(self, hatch, helpers, temp_dir, ...
    method test_default_build_script_known_artifacts (line 1311) | def test_default_build_script_known_artifacts(self, hatch, helpers, te...
    method test_default_build_script_configured_build_hooks (line 1393) | def test_default_build_script_configured_build_hooks(self, hatch, help...
    method test_default_build_script_extra_dependencies (line 1475) | def test_default_build_script_extra_dependencies(self, hatch, helpers,...
    method test_default_build_script_dynamic_artifacts (line 1558) | def test_default_build_script_dynamic_artifacts(self, hatch, helpers, ...
    method test_default_build_script_dynamic_force_include (line 1640) | def test_default_build_script_dynamic_force_include(self, hatch, helpe...
    method test_default_build_script_dynamic_force_include_duplicate (line 1725) | def test_default_build_script_dynamic_force_include_duplicate(self, ha...
    method test_default_build_script_dynamic_artifacts_with_src_layout (line 1811) | def test_default_build_script_dynamic_artifacts_with_src_layout(self, ...
    method test_default_shared_data (line 1892) | def test_default_shared_data(self, hatch, helpers, temp_dir, config_fi...
    method test_default_shared_data_from_build_data (line 1952) | def test_default_shared_data_from_build_data(self, hatch, helpers, tem...
    method test_default_shared_scripts (line 2027) | def test_default_shared_scripts(self, hatch, platform, helpers, temp_d...
    method test_default_shared_scripts_from_build_data (line 2138) | def test_default_shared_scripts_from_build_data(self, hatch, platform,...
    method test_default_extra_metadata (line 2264) | def test_default_extra_metadata(self, hatch, helpers, temp_dir, config...
    method test_default_extra_metadata_build_data (line 2322) | def test_default_extra_metadata_build_data(self, hatch, helpers, temp_...
    method test_default_symlink (line 2396) | def test_default_symlink(self, hatch, helpers, temp_dir, config_file):
    method test_editable_default (line 2482) | def test_editable_default(self, hatch, helpers, temp_dir):
    method test_editable_default_extra_dependencies (line 2539) | def test_editable_default_extra_dependencies(self, hatch, helpers, tem...
    method test_editable_default_force_include (line 2611) | def test_editable_default_force_include(self, hatch, helpers, temp_dir):
    method test_editable_default_force_include_option (line 2684) | def test_editable_default_force_include_option(self, hatch, helpers, t...
    method test_editable_default_symlink (line 2748) | def test_editable_default_symlink(self, hatch, helpers, temp_dir):
    method test_editable_exact (line 2808) | def test_editable_exact(self, hatch, helpers, temp_dir, config_file):
    method test_editable_exact_extra_dependencies (line 2868) | def test_editable_exact_extra_dependencies(self, hatch, helpers, temp_...
    method test_editable_exact_force_include (line 2947) | def test_editable_exact_force_include(self, hatch, helpers, temp_dir, ...
    method test_editable_exact_force_include_option (line 3027) | def test_editable_exact_force_include_option(self, hatch, helpers, tem...
    method test_editable_exact_force_include_build_data_precedence (line 3095) | def test_editable_exact_force_include_build_data_precedence(self, hatc...
    method test_editable_pth (line 3180) | def test_editable_pth(self, hatch, helpers, temp_dir):
    method test_default_namespace_package (line 3236) | def test_default_namespace_package(self, hatch, helpers, temp_dir, con...
    method test_default_entry_points (line 3292) | def test_default_entry_points(self, hatch, helpers, temp_dir, config_f...
    method test_explicit_selection_with_src_layout (line 3341) | def test_explicit_selection_with_src_layout(self, hatch, helpers, temp...
    method test_single_module (line 3398) | def test_single_module(self, hatch, helpers, temp_dir, config_file):
    method test_no_strict_naming (line 3443) | def test_no_strict_naming(self, hatch, helpers, temp_dir, config_file):
    method test_editable_sources_rewrite_error (line 3494) | def test_editable_sources_rewrite_error(self, hatch, temp_dir):
    method test_macos_archflags (line 3547) | def test_macos_archflags(self, hatch, helpers, temp_dir, config_file, ...
    method test_macos_max_compat (line 3633) | def test_macos_max_compat(self, hatch, helpers, temp_dir, config_file,...
    method test_file_permissions_normalized (line 3721) | def test_file_permissions_normalized(self, hatch, temp_dir, config_file):
  class TestSBOMFiles (line 3765) | class TestSBOMFiles:
    method test_single_sbom_file (line 3766) | def test_single_sbom_file(self, hatch, helpers, temp_dir, config_file):
    method test_multiple_sbom_files (line 3813) | def test_multiple_sbom_files(self, hatch, helpers, temp_dir, config_fi...
    method test_nested_sbom_file (line 3863) | def test_nested_sbom_file(self, hatch, helpers, temp_dir, config_file):
    method test_sbom_files_invalid_type (line 3911) | def test_sbom_files_invalid_type(self, isolation):
    method test_sbom_file_invalid_item (line 3921) | def test_sbom_file_invalid_item(self, isolation):
    method test_sbom_from_build_data (line 3933) | def test_sbom_from_build_data(self, hatch, helpers, temp_dir, config_f...

FILE: tests/backend/builders/utils.py
  class MockBuilder (line 4) | class MockBuilder(BuilderInterface):  # no cov
    method get_version_api (line 5) | def get_version_api(self):

FILE: tests/backend/metadata/test_build.py
  class TestRequires (line 7) | class TestRequires:
    method test_default (line 8) | def test_default(self, isolation):
    method test_not_array (line 13) | def test_not_array(self, isolation):
    method test_entry_not_string (line 19) | def test_entry_not_string(self, isolation):
    method test_invalid_specifier (line 25) | def test_invalid_specifier(self, isolation):
    method test_correct (line 31) | def test_correct(self, isolation):
    method test_correct_complex_type (line 36) | def test_correct_complex_type(self, isolation):
  class TestBuildBackend (line 43) | class TestBuildBackend:
    method test_default (line 44) | def test_default(self, isolation):
    method test_not_string (line 49) | def test_not_string(self, isolation):
    method test_correct (line 55) | def test_correct(self, isolation):
  class TestBackendPath (line 61) | class TestBackendPath:
    method test_default (line 62) | def test_default(self, isolation):
    method test_not_array (line 67) | def test_not_array(self, isolation):
    method test_entry_not_string (line 73) | def test_entry_not_string(self, isolation):
    method test_correct (line 79) | def test_correct(self, isolation):

FILE: tests/backend/metadata/test_core.py
  function latest_spec (line 15) | def latest_spec():
  class TestConfig (line 19) | class TestConfig:
    method test_default (line 20) | def test_default(self, isolation):
    method test_reuse (line 25) | def test_reuse(self, isolation):
    method test_read (line 31) | def test_read(self, temp_dir):
  class TestInterface (line 41) | class TestInterface:
    method test_types (line 42) | def test_types(self, isolation):
    method test_missing_core_metadata (line 49) | def test_missing_core_metadata(self, isolation):
    method test_core_metadata_not_table (line 55) | def test_core_metadata_not_table(self, isolation):
    method test_tool_metadata_not_table (line 61) | def test_tool_metadata_not_table(self, isolation):
    method test_hatch_metadata_not_table (line 67) | def test_hatch_metadata_not_table(self, isolation):
    method test_build_metadata_not_table (line 73) | def test_build_metadata_not_table(self, isolation):
  class TestDynamic (line 80) | class TestDynamic:
    method test_not_array (line 81) | def test_not_array(self, isolation):
    method test_entry_not_string (line 87) | def test_entry_not_string(self, isolation):
    method test_correct (line 93) | def test_correct(self, isolation):
    method test_cache_not_array (line 99) | def test_cache_not_array(self, isolation):
    method test_cache_entry_not_string (line 105) | def test_cache_entry_not_string(self, isolation):
    method test_cache_correct (line 111) | def test_cache_correct(self, temp_dir, helpers):
  class TestRawName (line 143) | class TestRawName:
    method test_dynamic (line 144) | def test_dynamic(self, isolation):
    method test_missing (line 152) | def test_missing(self, isolation):
    method test_not_string (line 158) | def test_not_string(self, isolation):
    method test_invalid (line 164) | def test_invalid(self, isolation):
    method test_correct (line 176) | def test_correct(self, isolation):
  class TestName (line 183) | class TestName:
    method test_normalization (line 185) | def test_normalization(self, isolation, name):
  class TestVersion (line 191) | class TestVersion:
    method test_dynamic (line 192) | def test_dynamic(self, isolation):
    method test_static_missing (line 201) | def test_static_missing(self, isolation):
    method test_static_not_string (line 210) | def test_static_not_string(self, isolation):
    method test_static_invalid (line 216) | def test_static_invalid(self, isolation):
    method test_static_normalization (line 225) | def test_static_normalization(self, isolation):
    method test_dynamic_missing (line 231) | def test_dynamic_missing(self, isolation):
    method test_dynamic_not_table (line 237) | def test_dynamic_not_table(self, isolation):
    method test_dynamic_source_empty (line 245) | def test_dynamic_source_empty(self, isolation):
    method test_dynamic_source_not_string (line 255) | def test_dynamic_source_not_string(self, isolation):
    method test_dynamic_unknown_source (line 263) | def test_dynamic_unknown_source(self, isolation):
    method test_dynamic_source_regex (line 273) | def test_dynamic_source_regex(self, temp_dir):
    method test_dynamic_source_regex_invalid (line 288) | def test_dynamic_source_regex_invalid(self, temp_dir):
    method test_dynamic_error (line 304) | def test_dynamic_error(self, isolation):
  class TestDescription (line 317) | class TestDescription:
    method test_dynamic (line 318) | def test_dynamic(self, isolation):
    method test_not_string (line 329) | def test_not_string(self, isolation):
    method test_default (line 335) | def test_default(self, isolation):
    method test_custom (line 340) | def test_custom(self, isolation):
    method test_normaliza (line 345) | def test_normaliza(self, isolation):
  class TestReadme (line 351) | class TestReadme:
    method test_dynamic (line 352) | def test_dynamic(self, isolation):
    method test_unknown_type (line 362) | def test_unknown_type(self, isolation, attribute):
    method test_default (line 368) | def test_default(self, isolation):
    method test_string_path_unknown_content_type (line 375) | def test_string_path_unknown_content_type(self, isolation):
    method test_string_path_nonexistent (line 383) | def test_string_path_nonexistent(self, isolation):
    method test_string_correct (line 392) | def test_string_correct(self, extension, content_type, temp_dir):
    method test_table_content_type_missing (line 403) | def test_table_content_type_missing(self, isolation):
    method test_table_content_type_not_string (line 409) | def test_table_content_type_not_string(self, isolation):
    method test_table_content_type_not_unknown (line 415) | def test_table_content_type_not_unknown(self, isolation):
    method test_table_multiple_options (line 427) | def test_table_multiple_options(self, isolation):
    method test_table_no_option (line 435) | def test_table_no_option(self, isolation):
    method test_table_file_not_string (line 441) | def test_table_file_not_string(self, isolation):
    method test_table_file_nonexistent (line 449) | def test_table_file_nonexistent(self, isolation):
    method test_table_file_correct (line 457) | def test_table_file_correct(self, temp_dir):
    method test_table_text_not_string (line 470) | def test_table_text_not_string(self, isolation):
    method test_table_text_correct (line 478) | def test_table_text_correct(self, isolation):
  class TestRequiresPython (line 488) | class TestRequiresPython:
    method test_dynamic (line 489) | def test_dynamic(self, isolation):
    method test_not_string (line 504) | def test_not_string(self, isolation, attribute):
    method test_invalid (line 510) | def test_invalid(self, isolation):
    method test_default (line 516) | def test_default(self, isolation):
    method test_custom (line 523) | def test_custom(self, isolation):
  class TestLicense (line 531) | class TestLicense:
    method test_dynamic (line 532) | def test_dynamic(self, isolation):
    method test_invalid_type (line 541) | def test_invalid_type(self, isolation):
    method test_default (line 547) | def test_default(self, isolation):
    method test_normalization (line 553) | def test_normalization(self, isolation):
    method test_invalid_expression (line 558) | def test_invalid_expression(self, isolation):
    method test_multiple_options (line 564) | def test_multiple_options(self, isolation):
    method test_no_option (line 570) | def test_no_option(self, isolation):
    method test_file_not_string (line 576) | def test_file_not_string(self, isolation):
    method test_file_nonexistent (line 582) | def test_file_nonexistent(self, isolation):
    method test_file_correct (line 588) | def test_file_correct(self, temp_dir):
    method test_text_not_string (line 597) | def test_text_not_string(self, isolation):
    method test_text_correct (line 603) | def test_text_correct(self, isolation):
  class TestLicenseFiles (line 609) | class TestLicenseFiles:
    method test_dynamic (line 610) | def test_dynamic(self, isolation):
    method test_not_array (line 623) | def test_not_array(self, isolation):
    method test_entry_not_string (line 629) | def test_entry_not_string(self, isolation):
    method test_default_globs_no_licenses (line 635) | def test_default_globs_no_licenses(self, isolation):
    method test_default_globs_with_licenses (line 640) | def test_default_globs_with_licenses(self, temp_dir):
    method test_globs_with_licenses (line 656) | def test_globs_with_licenses(self, temp_dir):
    method test_paths_with_licenses (line 669) | def test_paths_with_licenses(self, temp_dir):
  class TestAuthors (line 687) | class TestAuthors:
    method test_dynamic (line 688) | def test_dynamic(self, isolation):
    method test_not_array (line 697) | def test_not_array(self, isolation):
    method test_default (line 703) | def test_default(self, isolation):
    method test_not_table (line 708) | def test_not_table(self, isolation):
    method test_no_data (line 714) | def test_no_data(self, isolation):
    method test_name_not_string (line 722) | def test_name_not_string(self, isolation):
    method test_name_only (line 728) | def test_name_only(self, isolation):
    method test_email_not_string (line 735) | def test_email_not_string(self, isolation):
    method test_email_only (line 741) | def test_email_only(self, isolation):
    method test_name_and_email (line 748) | def test_name_and_email(self, isolation):
  class TestMaintainers (line 765) | class TestMaintainers:
    method test_dynamic (line 766) | def test_dynamic(self, isolation):
    method test_not_array (line 777) | def test_not_array(self, isolation):
    method test_default (line 783) | def test_default(self, isolation):
    method test_not_table (line 788) | def test_not_table(self, isolation):
    method test_no_data (line 794) | def test_no_data(self, isolation):
    method test_name_not_string (line 802) | def test_name_not_string(self, isolation):
    method test_name_only (line 808) | def test_name_only(self, isolation):
    method test_email_not_string (line 815) | def test_email_not_string(self, isolation):
    method test_email_only (line 821) | def test_email_only(self, isolation):
    method test_name_and_email (line 828) | def test_name_and_email(self, isolation):
  class TestKeywords (line 848) | class TestKeywords:
    method test_dynamic (line 849) | def test_dynamic(self, isolation):
    method test_not_array (line 858) | def test_not_array(self, isolation):
    method test_entry_not_string (line 864) | def test_entry_not_string(self, isolation):
    method test_correct (line 870) | def test_correct(self, isolation):
  class TestClassifiers (line 876) | class TestClassifiers:
    method test_dynamic (line 877) | def test_dynamic(self, isolation):
    method test_not_array (line 888) | def test_not_array(self, isolation):
    method test_entry_not_string (line 894) | def test_entry_not_string(self, isolation):
    method test_entry_unknown (line 900) | def test_entry_unknown(self, isolation, monkeypatch):
    method test_entry_unknown_no_verify (line 907) | def test_entry_unknown_no_verify(self, isolation, monkeypatch):
    method test_correct (line 931) | def test_correct(self, isolation):
  class TestURLs (line 953) | class TestURLs:
    method test_dynamic (line 954) | def test_dynamic(self, isolation):
    method test_not_table (line 963) | def test_not_table(self, isolation):
    method test_entry_not_string (line 969) | def test_entry_not_string(self, isolation):
    method test_correct (line 975) | def test_correct(self, isolation):
  class TestScripts (line 981) | class TestScripts:
    method test_dynamic (line 982) | def test_dynamic(self, isolation):
    method test_not_table (line 991) | def test_not_table(self, isolation):
    method test_entry_not_string (line 997) | def test_entry_not_string(self, isolation):
    method test_correct (line 1003) | def test_correct(self, isolation):
  class TestGUIScripts (line 1009) | class TestGUIScripts:
    method test_dynamic (line 1010) | def test_dynamic(self, isolation):
    method test_not_table (line 1021) | def test_not_table(self, isolation):
    method test_entry_not_string (line 1027) | def test_entry_not_string(self, isolation):
    method test_correct (line 1033) | def test_correct(self, isolation):
  class TestEntryPoints (line 1039) | class TestEntryPoints:
    method test_dynamic (line 1040) | def test_dynamic(self, isolation):
    method test_not_table (line 1053) | def test_not_table(self, isolation):
    method test_forbidden_fields (line 1060) | def test_forbidden_fields(self, isolation, field, expected):
    method test_data_not_table (line 1072) | def test_data_not_table(self, isolation):
    method test_data_entry_not_string (line 1078) | def test_data_entry_not_string(self, isolation):
    method test_data_empty (line 1086) | def test_data_empty(self, isolation):
    method test_default (line 1091) | def test_default(self, isolation):
    method test_correct (line 1096) | def test_correct(self, isolation):
  class TestDependencies (line 1110) | class TestDependencies:
    method test_dynamic (line 1111) | def test_dynamic(self, isolation):
    method test_not_array (line 1124) | def test_not_array(self, isolation):
    method test_entry_not_string (line 1130) | def test_entry_not_string(self, isolation):
    method test_invalid (line 1136) | def test_invalid(self, isolation):
    method test_direct_reference (line 1142) | def test_direct_reference(self, isolation):
    method test_direct_reference_allowed (line 1156) | def test_direct_reference_allowed(self, isolation):
    method test_context_formatting (line 1168) | def test_context_formatting(self, isolation, uri_slash_prefix):
    method test_correct (line 1181) | def test_correct(self, isolation):
  class TestOptionalDependencies (line 1209) | class TestOptionalDependencies:
    method test_dynamic (line 1210) | def test_dynamic(self, isolation):
    method test_not_table (line 1224) | def test_not_table(self, isolation):
    method test_invalid_name (line 1230) | def test_invalid_name(self, isolation):
    method test_definitions_not_array (line 1243) | def test_definitions_not_array(self, isolation):
    method test_entry_not_string (line 1251) | def test_entry_not_string(self, isolation):
    method test_invalid (line 1259) | def test_invalid(self, isolation):
    method test_conflict (line 1267) | def test_conflict(self, isolation):
    method test_recursive_circular (line 1281) | def test_recursive_circular(self, isolation):
    method test_recursive_unknown (line 1294) | def test_recursive_unknown(self, isolation):
    method test_allow_ambiguity (line 1307) | def test_allow_ambiguity(self, isolation):
    method test_direct_reference (line 1319) | def test_direct_reference(self, isolation):
    method test_context_formatting (line 1335) | def test_context_formatting(self, isolation, uri_slash_prefix):
    method test_direct_reference_allowed (line 1348) | def test_direct_reference_allowed(self, isolation):
    method test_correct (line 1363) | def test_correct(self, isolation):
  class TestHook (line 1405) | class TestHook:
    method test_unknown (line 1406) | def test_unknown(self, isolation):
    method test_custom (line 1416) | def test_custom(self, temp_dir, helpers):
    method test_custom_missing_dynamic (line 1467) | def test_custom_missing_dynamic(self, temp_dir, helpers):
  class TestHatchPersonalProjectConfigFile (line 1501) | class TestHatchPersonalProjectConfigFile:
    method test_correct (line 1502) | def test_correct(self, temp_dir, helpers):
    method test_precedence (line 1530) | def test_precedence(self, temp_dir, helpers):
  class TestMetadataConversion (line 1563) | class TestMetadataConversion:
    method test_required_only (line 1564) | def test_required_only(self, isolation, latest_spec):
    method test_dynamic (line 1571) | def test_dynamic(self, isolation, latest_spec):
    method test_description (line 1578) | def test_description(self, isolation, latest_spec):
    method test_urls (line 1585) | def test_urls(self, isolation, latest_spec):
    method test_authors (line 1592) | def test_authors(self, isolation, latest_spec):
    method test_maintainers (line 1603) | def test_maintainers(self, isolation, latest_spec):
    method test_keywords (line 1614) | def test_keywords(self, isolation, latest_spec):
    method test_classifiers (line 1621) | def test_classifiers(self, isolation, latest_spec):
    method test_license_files (line 1632) | def test_license_files(self, temp_dir, latest_spec):
    method test_license_expression (line 1648) | def test_license_expression(self, isolation, latest_spec):
    method test_license_legacy (line 1655) | def test_license_legacy(self, isolation, latest_spec):
    method test_readme (line 1662) | def test_readme(self, isolation, latest_spec):
    method test_requires_python (line 1673) | def test_requires_python(self, isolation, latest_spec):
    method test_dependencies (line 1680) | def test_dependencies(self, isolation, latest_spec):
  class TestSourceDistributionMetadata (line 1696) | class TestSourceDistributionMetadata:
    method test_basic_persistence (line 1697) | def test_basic_persistence(self, temp_dir, helpers):
    method test_metadata_hooks (line 1733) | def test_metadata_hooks(self, temp_dir, helpers):

FILE: tests/backend/metadata/test_custom_hook.py
  function test_no_path (line 9) | def test_no_path(isolation):
  function test_path_not_string (line 16) | def test_path_not_string(isolation):
  function test_nonexistent (line 23) | def test_nonexistent(isolation):
  function test_default (line 30) | def test_default(temp_dir, helpers):
  function test_explicit_path (line 55) | def test_explicit_path(temp_dir, helpers):
  function test_no_subclass (line 81) | def test_no_subclass(temp_dir, helpers):

FILE: tests/backend/metadata/test_hatch.py
  class TestBuildConfig (line 9) | class TestBuildConfig:
    method test_default (line 10) | def test_default(self, isolation):
    method test_not_table (line 16) | def test_not_table(self, isolation):
    method test_correct (line 23) | def test_correct(self, isolation):
  class TestBuildTargets (line 30) | class TestBuildTargets:
    method test_default (line 31) | def test_default(self, isolation):
    method test_not_table (line 37) | def test_not_table(self, isolation):
    method test_correct (line 44) | def test_correct(self, isolation):
  class TestVersionSourceName (line 51) | class TestVersionSourceName:
    method test_empty (line 52) | def test_empty(self, isolation):
    method test_not_table (line 58) | def test_not_table(self, isolation):
    method test_correct (line 62) | def test_correct(self, isolation):
    method test_default (line 67) | def test_default(self, isolation):
  class TestVersionSchemeName (line 73) | class TestVersionSchemeName:
    method test_missing (line 74) | def test_missing(self, isolation):
    method test_not_table (line 80) | def test_not_table(self, isolation):
    method test_correct (line 84) | def test_correct(self, isolation):
    method test_default (line 89) | def test_default(self, isolation):
  class TestVersionSource (line 95) | class TestVersionSource:
    method test_unknown (line 96) | def test_unknown(self, isolation):
    method test_cached (line 100) | def test_cached(self, isolation):
  class TestVersionScheme (line 107) | class TestVersionScheme:
    method test_unknown (line 108) | def test_unknown(self, isolation):
    method test_cached (line 112) | def test_cached(self, isolation):
  class TestMetadata (line 119) | class TestMetadata:
    method test_default (line 120) | def test_default(self, isolation):
    method test_not_table (line 126) | def test_not_table(self, isolation):
    method test_correct (line 133) | def test_correct(self, isolation):
  class TestMetadataAllowDirectReferences (line 140) | class TestMetadataAllowDirectReferences:
    method test_default (line 141) | def test_default(self, isolation):
    method test_not_boolean (line 147) | def test_not_boolean(self, isolation):
    method test_correct (line 154) | def test_correct(self, isolation):
  class TestMetadataAllowAmbiguousFeatures (line 161) | class TestMetadataAllowAmbiguousFeatures:
    method test_default (line 162) | def test_default(self, isolation):
    method test_not_boolean (line 168) | def test_not_boolean(self, isolation):
    method test_correct (line 175) | def test_correct(self, isolation):

FILE: tests/backend/metadata/test_spec.py
  class TestProjectMetadataFromCoreMetadata (line 11) | class TestProjectMetadataFromCoreMetadata:
    method test_missing_name (line 12) | def test_missing_name(self):
    method test_missing_version (line 19) | def test_missing_version(self):
    method test_dynamic (line 27) | def test_dynamic(self):
    method test_description (line 41) | def test_description(self):
    method test_urls (line 54) | def test_urls(self):
    method test_authors (line 68) | def test_authors(self):
    method test_maintainers (line 82) | def test_maintainers(self):
    method test_keywords (line 96) | def test_keywords(self):
    method test_classifiers (line 109) | def test_classifiers(self):
    method test_license_files (line 123) | def test_license_files(self):
    method test_license_expression (line 137) | def test_license_expression(self):
    method test_license_legacy (line 150) | def test_license_legacy(self):
    method test_readme (line 163) | def test_readme(self):
    method test_readme_default_content_type (line 178) | def test_readme_default_content_type(self):
    method test_requires_python (line 192) | def test_requires_python(self):
    method test_dependencies (line 205) | def test_dependencies(self):
  class TestCoreMetadataV12 (line 234) | class TestCoreMetadataV12:
    method test_default (line 235) | def test_default(self, constructor, isolation, helpers):
    method test_description (line 246) | def test_description(self, constructor, isolation, helpers):
    method test_urls (line 260) | def test_urls(self, constructor, isolation, helpers):
    method test_authors_name (line 277) | def test_authors_name(self, constructor, isolation, helpers):
    method test_authors_email (line 291) | def test_authors_email(self, constructor, isolation, helpers):
    method test_authors_name_and_email (line 307) | def test_authors_name_and_email(self, constructor, isolation, helpers):
    method test_authors_multiple (line 323) | def test_authors_multiple(self, constructor, isolation, helpers):
    method test_maintainers_name (line 339) | def test_maintainers_name(self, constructor, isolation, helpers):
    method test_maintainers_email (line 353) | def test_maintainers_email(self, constructor, isolation, helpers):
    method test_maintainers_name_and_email (line 369) | def test_maintainers_name_and_email(self, constructor, isolation, help...
    method test_maintainers_multiple (line 391) | def test_maintainers_multiple(self, constructor, isolation, helpers):
    method test_license (line 407) | def test_license(self, constructor, isolation, helpers):
    method test_license_expression (line 422) | def test_license_expression(self, constructor, isolation, helpers):
    method test_keywords_single (line 438) | def test_keywords_single(self, constructor, isolation, helpers):
    method test_keywords_multiple (line 452) | def test_keywords_multiple(self, constructor, isolation, helpers):
    method test_classifiers (line 466) | def test_classifiers(self, constructor, isolation, helpers):
    method test_requires_python (line 485) | def test_requires_python(self, constructor, isolation, helpers):
    method test_dependencies (line 499) | def test_dependencies(self, constructor, isolation, helpers):
    method test_extra_runtime_dependencies (line 516) | def test_extra_runtime_dependencies(self, constructor, isolation, help...
    method test_all (line 534) | def test_all(self, constructor, isolation, helpers):
  class TestCoreMetadataV21 (line 581) | class TestCoreMetadataV21:
    method test_default (line 582) | def test_default(self, constructor, isolation, helpers):
    method test_description (line 593) | def test_description(self, constructor, isolation, helpers):
    method test_urls (line 607) | def test_urls(self, constructor, isolation, helpers):
    method test_authors_name (line 624) | def test_authors_name(self, constructor, isolation, helpers):
    method test_authors_email (line 638) | def test_authors_email(self, constructor, isolation, helpers):
    method test_authors_name_and_email (line 654) | def test_authors_name_and_email(self, constructor, isolation, helpers):
    method test_authors_multiple (line 670) | def test_authors_multiple(self, constructor, isolation, helpers):
    method test_maintainers_name (line 686) | def test_maintainers_name(self, constructor, isolation, helpers):
    method test_maintainers_email (line 700) | def test_maintainers_email(self, constructor, isolation, helpers):
    method test_maintainers_name_and_email (line 716) | def test_maintainers_name_and_email(self, constructor, isolation, help...
    method test_maintainers_multiple (line 738) | def test_maintainers_multiple(self, constructor, isolation, helpers):
    method test_license (line 754) | def test_license(self, constructor, isolation, helpers):
    method test_license_expression (line 769) | def test_license_expression(self, constructor, isolation, helpers):
    method test_keywords_single (line 785) | def test_keywords_single(self, constructor, isolation, helpers):
    method test_keywords_multiple (line 799) | def test_keywords_multiple(self, constructor, isolation, helpers):
    method test_classifiers (line 813) | def test_classifiers(self, constructor, isolation, helpers):
    method test_requires_python (line 832) | def test_requires_python(self, constructor, isolation, helpers):
    method test_dependencies (line 846) | def test_dependencies(self, constructor, isolation, helpers):
    method test_optional_dependencies (line 863) | def test_optional_dependencies(self, constructor, isolation, helpers):
    method test_extra_runtime_dependencies (line 893) | def test_extra_runtime_dependencies(self, constructor, isolation, help...
    method test_readme (line 911) | def test_readme(self, constructor, isolation, helpers):
    method test_all (line 935) | def test_all(self, constructor, helpers, temp_dir):
  class TestCoreMetadataV22 (line 1002) | class TestCoreMetadataV22:
    method test_default (line 1003) | def test_default(self, constructor, isolation, helpers):
    method test_dynamic (line 1014) | def test_dynamic(self, constructor, isolation, helpers):
    method test_description (line 1032) | def test_description(self, constructor, isolation, helpers):
    method test_urls (line 1046) | def test_urls(self, constructor, isolation, helpers):
    method test_authors_name (line 1063) | def test_authors_name(self, constructor, isolation, helpers):
    method test_authors_email (line 1077) | def test_authors_email(self, constructor, isolation, helpers):
    method test_authors_name_and_email (line 1093) | def test_authors_name_and_email(self, constructor, isolation, helpers):
    method test_authors_multiple (line 1109) | def test_authors_multiple(self, constructor, isolation, helpers):
    method test_maintainers_name (line 1125) | def test_maintainers_name(self, constructor, isolation, helpers):
    method test_maintainers_email (line 1139) | def test_maintainers_email(self, constructor, isolation, helpers):
    method test_maintainers_name_and_email (line 1155) | def test_maintainers_name_and_email(self, constructor, isolation, help...
    method test_maintainers_multiple (line 1177) | def test_maintainers_multiple(self, constructor, isolation, helpers):
    method test_license (line 1193) | def test_license(self, constructor, isolation, helpers):
    method test_license_expression (line 1208) | def test_license_expression(self, constructor, isolation, helpers):
    method test_keywords_single (line 1224) | def test_keywords_single(self, constructor, isolation, helpers):
    method test_keywords_multiple (line 1238) | def test_keywords_multiple(self, constructor, isolation, helpers):
    method test_classifiers (line 1252) | def test_classifiers(self, constructor, isolation, helpers):
    method test_requires_python (line 1271) | def test_requires_python(self, constructor, isolation, helpers):
    method test_dependencies (line 1285) | def test_dependencies(self, constructor, isolation, helpers):
    method test_optional_dependencies (line 1302) | def test_optional_dependencies(self, constructor, isolation, helpers):
    method test_optional_complex_dependencies (line 1332) | def test_optional_complex_dependencies(self, constructor, isolation, h...
    method test_extra_runtime_dependencies (line 1362) | def test_extra_runtime_dependencies(self, constructor, isolation, help...
    method test_readme (line 1380) | def test_readme(self, constructor, isolation, helpers):
    method test_all (line 1404) | def test_all(self, constructor, helpers, temp_dir):
  class TestCoreMetadataV23 (line 1471) | class TestCoreMetadataV23:
    method test_default (line 1472) | def test_default(self, constructor, isolation, helpers):
    method test_description (line 1483) | def test_description(self, constructor, isolation, helpers):
    method test_dynamic (line 1497) | def test_dynamic(self, constructor, isolation, helpers):
    method test_urls (line 1515) | def test_urls(self, constructor, isolation, helpers):
    method test_authors_name (line 1532) | def test_authors_name(self, constructor, isolation, helpers):
    method test_authors_email (line 1546) | def test_authors_email(self, constructor, isolation, helpers):
    method test_authors_name_and_email (line 1562) | def test_authors_name_and_email(self, constructor, isolation, helpers):
    method test_authors_multiple (line 1578) | def test_authors_multiple(self, constructor, isolation, helpers):
    method test_maintainers_name (line 1594) | def test_maintainers_name(self, constructor, isolation, helpers):
    method test_maintainers_email (line 1608) | def test_maintainers_email(self, constructor, isolation, helpers):
    method test_maintainers_name_and_email (line 1624) | def test_maintainers_name_and_email(self, constructor, isolation, help...
    method test_maintainers_multiple (line 1646) | def test_maintainers_multiple(self, constructor, isolation, helpers):
    method test_license (line 1662) | def test_license(self, constructor, isolation, helpers):
    method test_license_expression (line 1677) | def test_license_expression(self, constructor, isolation, helpers):
    method test_keywords_single (line 1693) | def test_keywords_single(self, constructor, isolation, helpers):
    method test_keywords_multiple (line 1707) | def test_keywords_multiple(self, constructor, isolation, helpers):
    method test_classifiers (line 1721) | def test_classifiers(self, constructor, isolation, helpers):
    method test_requires_python (line 1740) | def test_requires_python(self, constructor, isolation, helpers):
    method test_dependencies (line 1754) | def test_dependencies(self, constructor, isolation, helpers):
    method test_optional_dependencies (line 1771) | def test_optional_dependencies(self, constructor, isolation, helpers):
    method test_extra_runtime_dependencies (line 1801) | def test_extra_runtime_dependencies(self, constructor, isolation, help...
    method test_readme (line 1819) | def test_readme(self, constructor, isolation, helpers):
    method test_all (line 1843) | def test_all(self, constructor, temp_dir, helpers):
  class TestCoreMetadataV24 (line 1910) | class TestCoreMetadataV24:
    method test_default (line 1911) | def test_default(self, constructor, isolation, helpers):
    method test_description (line 1922) | def test_description(self, constructor, isolation, helpers):
    method test_dynamic (line 1936) | def test_dynamic(self, constructor, isolation, helpers):
    method test_urls (line 1954) | def test_urls(self, constructor, isolation, helpers):
    method test_authors_name (line 1971) | def test_authors_name(self, constructor, isolation, helpers):
    method test_authors_email (line 1985) | def test_authors_email(self, constructor, isolation, helpers):
    method test_authors_name_and_email (line 2001) | def test_authors_name_and_email(self, constructor, isolation, helpers):
    method test_authors_multiple (line 2017) | def test_authors_multiple(self, constructor, isolation, helpers):
    method test_maintainers_name (line 2033) | def test_maintainers_name(self, constructor, isolation, helpers):
    method test_maintainers_email (line 2047) | def test_maintainers_email(self, constructor, isolation, helpers):
    method test_maintainers_name_and_email (line 2063) | def test_maintainers_name_and_email(self, constructor, isolation, help...
    method test_maintainers_multiple (line 2085) | def test_maintainers_multiple(self, constructor, isolation, helpers):
    method test_license (line 2101) | def test_license(self, constructor, isolation, helpers):
    method test_license_expression (line 2116) | def test_license_expression(self, constructor, isolation, helpers):
    method test_license_files (line 2132) | def test_license_files(self, constructor, temp_dir, helpers):
    method test_keywords_single (line 2154) | def test_keywords_single(self, constructor, isolation, helpers):
    method test_keywords_multiple (line 2168) | def test_keywords_multiple(self, constructor, isolation, helpers):
    method test_classifiers (line 2182) | def test_classifiers(self, constructor, isolation, helpers):
    method test_requires_python (line 2201) | def test_requires_python(self, constructor, isolation, helpers):
    method test_dependencies (line 2215) | def test_dependencies(self, constructor, isolation, helpers):
    method test_optional_dependencies (line 2232) | def test_optional_dependencies(self, constructor, isolation, helpers):
    method test_extra_runtime_dependencies (line 2262) | def test_extra_runtime_dependencies(self, constructor, isolation, help...
    method test_readme (line 2280) | def test_readme(self, constructor, isolation, helpers):
    method test_all (line 2304) | def test_all(self, constructor, temp_dir, helpers):

FILE: tests/backend/test_build.py
  function test_sdist (line 4) | def test_sdist(hatch, helpers, temp_dir, config_file):
  function test_wheel (line 45) | def test_wheel(hatch, helpers, temp_dir, config_file):
  function test_editable (line 86) | def test_editable(hatch, helpers, temp_dir, config_file):

FILE: tests/backend/utils/test_context.py
  function test_normal (line 9) | def test_normal(isolation):
  class TestStatic (line 14) | class TestStatic:
    method test_directory_separator (line 15) | def test_directory_separator(self, isolation):
    method test_path_separator (line 19) | def test_path_separator(self, isolation):
  class TestRoot (line 24) | class TestRoot:
    method test_default (line 25) | def test_default(self, isolation):
    method test_parent (line 29) | def test_parent(self, isolation):
    method test_parent_parent (line 34) | def test_parent_parent(self, isolation):
    method test_uri (line 39) | def test_uri(self, isolation, uri_slash_prefix):
    method test_uri_parent (line 44) | def test_uri_parent(self, isolation, uri_slash_prefix):
    method test_uri_parent_parent (line 49) | def test_uri_parent_parent(self, isolation, uri_slash_prefix):
    method test_real (line 54) | def test_real(self, isolation):
    method test_real_parent (line 59) | def test_real_parent(self, isolation):
    method test_real_parent_parent (line 64) | def test_real_parent_parent(self, isolation):
    method test_unknown_modifier (line 69) | def test_unknown_modifier(self, isolation):
    method test_too_many_modifiers_after_parent (line 75) | def test_too_many_modifiers_after_parent(self, isolation):
  class TestHome (line 82) | class TestHome:
    method test_default (line 83) | def test_default(self, isolation):
    method test_uri (line 87) | def test_uri(self, isolation, uri_slash_prefix):
    method test_real (line 92) | def test_real(self, isolation):
    method test_unknown_modifier (line 96) | def test_unknown_modifier(self, isolation):
  class TestEnvVars (line 103) | class TestEnvVars:
    method test_set (line 104) | def test_set(self, isolation):
    method test_default (line 110) | def test_default(self, isolation):
    method test_default_empty_string (line 115) | def test_default_empty_string(self, isolation):
    method test_default_nested_set (line 120) | def test_default_nested_set(self, isolation):
    method test_default_nested_default (line 126) | def test_default_nested_default(self, isolation):
    method test_no_selection (line 131) | def test_no_selection(self, isolation):
    method test_unset_without_default (line 137) | def test_unset_without_default(self, isolation):

FILE: tests/backend/utils/test_fs.py
  class TestPathToURI (line 6) | class TestPathToURI:
    method test_unix (line 7) | def test_unix(self, isolation, uri_slash_prefix):
    method test_character_escaping (line 12) | def test_character_escaping(self, temp_dir, uri_slash_prefix):

FILE: tests/backend/utils/test_macos.py
  function test_process_macos_plat_tag (line 25) | def test_process_macos_plat_tag(
  function check_normalization (line 55) | def check_normalization(*, version: str, arm: bool, compat: bool, expect...

FILE: tests/backend/version/scheme/test_standard.py
  function test_not_higher (line 9) | def test_not_higher(isolation):
  function test_specific (line 16) | def test_specific(isolation):
  function test_specific_not_higher_allowed_config (line 22) | def test_specific_not_higher_allowed_config(isolation):
  function test_specific_not_higher_allowed_env_var (line 28) | def test_specific_not_higher_allowed_env_var(isolation):
  function test_release (line 35) | def test_release(isolation):
  function test_major (line 41) | def test_major(isolation):
  function test_minor (line 47) | def test_minor(isolation):
  function test_micro (line 54) | def test_micro(isolation, keyword):
  class TestPre (line 60) | class TestPre:
    method test_begin (line 62) | def test_begin(self, isolation, phase):
    method test_continue (line 69) | def test_continue(self, isolation, phase):
    method test_restart (line 76) | def test_restart(self, isolation, phase):
  class TestPost (line 84) | class TestPost:
    method test_begin (line 86) | def test_begin(self, isolation, key):
    method test_continue (line 92) | def test_continue(self, isolation, key):
  class TestDev (line 98) | class TestDev:
    method test_begin (line 99) | def test_begin(self, isolation):
    method test_continue (line 104) | def test_continue(self, isolation):
  class TestMultiple (line 110) | class TestMultiple:
    method test_explicit_error (line 111) | def test_explicit_error(self, isolation):
    method test_correct (line 127) | def test_correct(self, isolation, operations, expected):
  class TestWithEpoch (line 133) | class TestWithEpoch:
    method test_correct (line 145) | def test_correct(self, isolation, operations, expected):

FILE: tests/backend/version/source/test_code.py
  function test_no_path (line 6) | def test_no_path(isolation):
  function test_path_not_string (line 13) | def test_path_not_string(isolation):
  function test_path_nonexistent (line 20) | def test_path_nonexistent(isolation):
  function test_expression_not_string (line 27) | def test_expression_not_string(temp_dir):
  function test_search_paths_not_array (line 38) | def test_search_paths_not_array(temp_dir):
  function test_search_paths_entry_not_string (line 49) | def test_search_paths_entry_not_string(temp_dir):
  function test_match_default_expression (line 60) | def test_match_default_expression(temp_dir):
  function test_match_custom_expression_basic (line 71) | def test_match_custom_expression_basic(temp_dir):
  function test_match_custom_expression_complex (line 82) | def test_match_custom_expression_complex(temp_dir, helpers):
  function test_search_paths (line 102) | def test_search_paths(temp_dir, helpers):

FILE: tests/backend/version/source/test_env.py
  function test_no_variable (line 7) | def test_no_variable(isolation):
  function test_variable_not_string (line 14) | def test_variable_not_string(isolation):
  function test_variable_not_available (line 21) | def test_variable_not_available(isolation):
  function test_variable_contains_version (line 31) | def test_variable_contains_version(isolation):

FILE: tests/backend/version/source/test_regex.py
  function test_no_path (line 10) | def test_no_path(isolation):
  function test_path_not_string (line 17) | def test_path_not_string(isolation):
  function test_path_nonexistent (line 24) | def test_path_nonexistent(isolation):
  function test_pattern_not_string (line 31) | def test_pattern_not_string(temp_dir):
  function test_no_version (line 42) | def test_no_version(temp_dir):
  function test_pattern_no_version_group (line 53) | def test_pattern_no_version_group(temp_dir):
  function test_match_custom_pattern (line 64) | def test_match_custom_pattern(temp_dir):
  function test_match_default_pattern (line 76) | def test_match_default_pattern(temp_dir, helpers, variable, quote, prefix):
  function test_set_default_pattern (line 99) | def test_set_default_pattern(temp_dir, helpers, variable, quote, prefix):

FILE: tests/cli/build/test_build.py
  class TestOtherBackend (line 14) | class TestOtherBackend:
    method test_standard (line 15) | def test_standard(self, hatch, temp_dir, helpers):
    method test_legacy (line 101) | def test_legacy(self, hatch, temp_dir, helpers):
  function test_incompatible_environment (line 161) | def test_incompatible_environment(hatch, temp_dir, helpers, build_env_co...
  function test_no_compatibility_check_if_exists (line 186) | def test_no_compatibility_check_if_exists(hatch, temp_dir, helpers, mock...
  function test_unknown_targets (line 238) | def test_unknown_targets(hatch, temp_dir, helpers):
  function test_mutually_exclusive_hook_options (line 263) | def test_mutually_exclusive_hook_options(hatch, temp_dir, helpers):
  function test_default (line 288) | def test_default(hatch, temp_dir, helpers):
  function test_explicit_targets (line 324) | def test_explicit_targets(hatch, temp_dir, helpers):
  function test_explicit_directory (line 357) | def test_explicit_directory(hatch, temp_dir, helpers):
  function test_explicit_directory_env_var (line 393) | def test_explicit_directory_env_var(hatch, temp_dir, helpers):
  function test_clean (line 429) | def test_clean(hatch, temp_dir, helpers, config_file):
  function test_clean_env_var (line 513) | def test_clean_env_var(hatch, temp_dir, helpers):
  function test_clean_only (line 569) | def test_clean_only(hatch, temp_dir, helpers, config_file):
  function test_clean_only_hooks_only (line 635) | def test_clean_only_hooks_only(hatch, temp_dir, helpers, config_file):
  function test_clean_hooks_after (line 701) | def test_clean_hooks_after(hatch, temp_
Condensed preview — 499 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,893K chars).
[
  {
    "path": ".gitattributes",
    "chars": 65,
    "preview": "# Auto detect text files and perform LF normalization\n* text=auto"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 50,
    "preview": "github:\n- ofek\ncustom:\n- https://ofek.dev/donate/\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/1-hatch_bug_report.yml",
    "chars": 535,
    "preview": "---\nname: Hatch Bug report\ndescription: Problems and issues with code in Hatch\nbody:\n- type: markdown\n  attributes:\n    "
  },
  {
    "path": ".github/ISSUE_TEMPLATE/2-feature_request.yml",
    "chars": 2413,
    "preview": "---\nname: Hatch feature request\ndescription: Suggest an idea for this project\nlabels: [\"kind:feature\"]\nbody:\n- type: mar"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 105,
    "preview": "version: 2\nupdates:\n- package-ecosystem: github-actions\n  directory: /\n  schedule:\n    interval: monthly\n"
  },
  {
    "path": ".github/workflows/auto-merge.yml",
    "chars": 659,
    "preview": "name: auto-merge\n\non:\n  pull_request_target:\n    types:\n    - opened\n    - reopened\n    - synchronize\n    branches:\n    "
  },
  {
    "path": ".github/workflows/build-distributions.yml",
    "chars": 6089,
    "preview": "name: build distributions\n\non:\n  workflow_call:\n    inputs:\n      version:\n        required: false\n        type: string\n"
  },
  {
    "path": ".github/workflows/build-hatch.yml",
    "chars": 16996,
    "preview": "name: build hatch\n\non:\n  push:\n    tags:\n    - hatch-v*\n    branches:\n    - master\n  pull_request:\n    branches:\n    - m"
  },
  {
    "path": ".github/workflows/build-hatchling.yml",
    "chars": 1245,
    "preview": "name: build hatchling\n\non:\n  push:\n    tags:\n    - hatchling-v*\n\nenv:\n  PYTHON_VERSION: \"3.12\"\n\njobs:\n  build:\n    name:"
  },
  {
    "path": ".github/workflows/cli.yml",
    "chars": 1187,
    "preview": "name: CLI experience\n\non:\n  push:\n    branches:\n    - master\n  pull_request:\n    branches:\n    - master\n\nconcurrency:\n  "
  },
  {
    "path": ".github/workflows/docs-dev.yml",
    "chars": 2281,
    "preview": "name: dev docs\n\non:\n  push:\n    branches:\n    - master\n  pull_request:\n    branches:\n    - master\n\nconcurrency:\n  group:"
  },
  {
    "path": ".github/workflows/docs-release.yml",
    "chars": 2365,
    "preview": "name: release docs\n\non:\n  push:\n    tags:\n    - hatch-v*\n  workflow_dispatch:\n\nconcurrency:\n  group: docs-deploy\n\nenv:\n "
  },
  {
    "path": ".github/workflows/test.yml",
    "chars": 3896,
    "preview": "name: test\n\non:\n  push:\n    branches:\n    - master\n  pull_request:\n    branches:\n    - master\n\nconcurrency:\n  group: ${{"
  },
  {
    "path": ".gitignore",
    "chars": 305,
    "preview": "# Global directories\n__pycache__/\n\n# Global files\n*.py[cod]\n*.dll\n*.so\n*.log\n*.swp\n\n# Root directories\n/.benchmarks/\n/.c"
  },
  {
    "path": ".linkcheckerrc",
    "chars": 196,
    "preview": "# https://linkchecker.github.io/linkchecker/man/linkcheckerrc.html\n[filtering]\nignore=\n  https://docs.astral.sh/ruff/rul"
  },
  {
    "path": "LICENSE.txt",
    "chars": 1088,
    "preview": "MIT License\n\nCopyright (c) 2017-present Ofek Lev <oss@ofek.dev>\n\nPermission is hereby granted, free of charge, to any pe"
  },
  {
    "path": "README.md",
    "chars": 3769,
    "preview": "# Hatch\n\n<div align=\"center\">\n\n<img src=\"https://raw.githubusercontent.com/pypa/hatch/master/docs/assets/images/logo.svg"
  },
  {
    "path": "backend/LICENSE.txt",
    "chars": 1088,
    "preview": "MIT License\n\nCopyright (c) 2021-present Ofek Lev <oss@ofek.dev>\n\nPermission is hereby granted, free of charge, to any pe"
  },
  {
    "path": "backend/README.md",
    "chars": 2335,
    "preview": "# Hatchling\n\n<div align=\"center\">\n\n<img src=\"https://raw.githubusercontent.com/pypa/hatch/master/docs/assets/images/logo"
  },
  {
    "path": "backend/pyproject.toml",
    "chars": 1582,
    "preview": "[build-system]\nrequires = []\nbuild-backend = 'hatchling.ouroboros'\nbackend-path = ['src']\n\n[project]\nname = \"hatchling\"\n"
  },
  {
    "path": "backend/src/hatchling/__about__.py",
    "chars": 23,
    "preview": "__version__ = \"1.29.0\"\n"
  },
  {
    "path": "backend/src/hatchling/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "backend/src/hatchling/__main__.py",
    "chars": 106,
    "preview": "import sys\n\nif __name__ == \"__main__\":\n    from hatchling.cli import hatchling\n\n    sys.exit(hatchling())\n"
  },
  {
    "path": "backend/src/hatchling/bridge/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "backend/src/hatchling/bridge/app.py",
    "chars": 3890,
    "preview": "from __future__ import annotations\n\nimport os\nimport sys\nfrom typing import Any\n\n\nclass Application:\n    \"\"\"\n    The way"
  },
  {
    "path": "backend/src/hatchling/build.py",
    "chars": 5577,
    "preview": "from __future__ import annotations\n\nimport os\nfrom typing import Any\n\n__all__ = [\n    \"build_editable\",\n    \"build_sdist"
  },
  {
    "path": "backend/src/hatchling/builders/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "backend/src/hatchling/builders/app.py",
    "chars": 530,
    "preview": "from __future__ import annotations\n\nfrom typing import Any\n\nfrom hatchling.builders.binary import BinaryBuilder\n\n\nclass "
  },
  {
    "path": "backend/src/hatchling/builders/binary.py",
    "chars": 7639,
    "preview": "from __future__ import annotations\n\nimport os\nimport sys\nfrom typing import TYPE_CHECKING, Any\n\nfrom hatchling.builders."
  },
  {
    "path": "backend/src/hatchling/builders/config.py",
    "chars": 35662,
    "preview": "from __future__ import annotations\n\nimport os\nfrom contextlib import contextmanager\nfrom functools import cached_propert"
  },
  {
    "path": "backend/src/hatchling/builders/constants.py",
    "chars": 860,
    "preview": "DEFAULT_BUILD_DIRECTORY = \"dist\"\n\nEXCLUDED_DIRECTORIES = frozenset((\n    # Python bytecode\n    \"__pycache__\",\n    # Sing"
  },
  {
    "path": "backend/src/hatchling/builders/custom.py",
    "chars": 2127,
    "preview": "from __future__ import annotations\n\nimport os\nfrom typing import TYPE_CHECKING, Any, Generic\n\nfrom hatchling.builders.pl"
  },
  {
    "path": "backend/src/hatchling/builders/hooks/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "backend/src/hatchling/builders/hooks/custom.py",
    "chars": 1378,
    "preview": "from __future__ import annotations\n\nimport os\nfrom typing import Any\n\nfrom hatchling.builders.hooks.plugin.interface imp"
  },
  {
    "path": "backend/src/hatchling/builders/hooks/plugin/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "backend/src/hatchling/builders/hooks/plugin/hooks.py",
    "chars": 440,
    "preview": "from __future__ import annotations\n\nimport typing\n\nfrom hatchling.builders.hooks.custom import CustomBuildHook\nfrom hatc"
  },
  {
    "path": "backend/src/hatchling/builders/hooks/plugin/interface.py",
    "chars": 4250,
    "preview": "from __future__ import annotations\n\nfrom typing import TYPE_CHECKING, Any, Generic, cast\n\nfrom hatchling.builders.config"
  },
  {
    "path": "backend/src/hatchling/builders/hooks/version.py",
    "chars": 2416,
    "preview": "from __future__ import annotations\n\nfrom typing import Any\n\nfrom hatchling.builders.hooks.plugin.interface import BuildH"
  },
  {
    "path": "backend/src/hatchling/builders/macos.py",
    "chars": 2085,
    "preview": "from __future__ import annotations\n\nimport os\nimport platform\nimport re\n\n__all__ = [\"process_macos_plat_tag\"]\n\n\ndef proc"
  },
  {
    "path": "backend/src/hatchling/builders/plugin/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "backend/src/hatchling/builders/plugin/hooks.py",
    "chars": 617,
    "preview": "from __future__ import annotations\n\nimport typing\n\nfrom hatchling.builders.app import AppBuilder\nfrom hatchling.builders"
  },
  {
    "path": "backend/src/hatchling/builders/plugin/interface.py",
    "chars": 16217,
    "preview": "from __future__ import annotations\n\nimport os\nimport re\nfrom abc import ABC, abstractmethod\nfrom typing import TYPE_CHEC"
  },
  {
    "path": "backend/src/hatchling/builders/sdist.py",
    "chars": 13558,
    "preview": "from __future__ import annotations\n\nimport gzip\nimport os\nimport tarfile\nimport tempfile\nfrom contextlib import closing\n"
  },
  {
    "path": "backend/src/hatchling/builders/utils.py",
    "chars": 3819,
    "preview": "from __future__ import annotations\n\nimport os\nimport shutil\nfrom base64 import urlsafe_b64encode\nfrom typing import TYPE"
  },
  {
    "path": "backend/src/hatchling/builders/wheel.py",
    "chars": 36554,
    "preview": "from __future__ import annotations\n\nimport csv\nimport hashlib\nimport os\nimport stat\nimport sys\nimport tempfile\nimport zi"
  },
  {
    "path": "backend/src/hatchling/cli/__init__.py",
    "chars": 730,
    "preview": "import argparse\n\nfrom hatchling.cli.build import build_command\nfrom hatchling.cli.dep import dep_command\nfrom hatchling."
  },
  {
    "path": "backend/src/hatchling/cli/build/__init__.py",
    "chars": 4270,
    "preview": "from __future__ import annotations\n\nimport argparse\nfrom typing import Any\n\n\ndef build_impl(\n    *,\n    called_by_app: b"
  },
  {
    "path": "backend/src/hatchling/cli/dep/__init__.py",
    "chars": 1169,
    "preview": "from __future__ import annotations\n\nimport sys\nfrom typing import TYPE_CHECKING, Any\n\nif TYPE_CHECKING:\n    import argpa"
  },
  {
    "path": "backend/src/hatchling/cli/dep/core.py",
    "chars": 5316,
    "preview": "from __future__ import annotations\n\nimport re\nimport sys\nfrom importlib.metadata import Distribution, DistributionFinder"
  },
  {
    "path": "backend/src/hatchling/cli/metadata/__init__.py",
    "chars": 1695,
    "preview": "from __future__ import annotations\n\nimport argparse\nfrom typing import Any\n\n\ndef metadata_impl(\n    *,\n    called_by_app"
  },
  {
    "path": "backend/src/hatchling/cli/version/__init__.py",
    "chars": 1597,
    "preview": "from __future__ import annotations\n\nimport argparse\nfrom typing import Any\n\n\ndef version_impl(\n    *,\n    called_by_app:"
  },
  {
    "path": "backend/src/hatchling/dep/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "backend/src/hatchling/dep/core.py",
    "chars": 70,
    "preview": "from hatchling.cli.dep.core import dependencies_in_sync  # noqa: F401\n"
  },
  {
    "path": "backend/src/hatchling/licenses/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "backend/src/hatchling/licenses/supported.py",
    "chars": 68,
    "preview": "from packaging.licenses._spdx import VERSION  # noqa: F401, PLC2701\n"
  },
  {
    "path": "backend/src/hatchling/metadata/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "backend/src/hatchling/metadata/core.py",
    "chars": 62187,
    "preview": "from __future__ import annotations\n\nimport os\nimport sys\nfrom contextlib import suppress\nfrom copy import deepcopy\nfrom "
  },
  {
    "path": "backend/src/hatchling/metadata/custom.py",
    "chars": 1424,
    "preview": "from __future__ import annotations\n\nimport os\nfrom typing import Any\n\nfrom hatchling.metadata.plugin.interface import Me"
  },
  {
    "path": "backend/src/hatchling/metadata/plugin/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "backend/src/hatchling/metadata/plugin/hooks.py",
    "chars": 397,
    "preview": "from __future__ import annotations\n\nfrom typing import TYPE_CHECKING\n\nfrom hatchling.metadata.custom import CustomMetada"
  },
  {
    "path": "backend/src/hatchling/metadata/plugin/interface.py",
    "chars": 1500,
    "preview": "from __future__ import annotations\n\nfrom abc import ABC, abstractmethod\n\n\nclass MetadataHookInterface(ABC):  # no cov\n  "
  },
  {
    "path": "backend/src/hatchling/metadata/spec.py",
    "chars": 23344,
    "preview": "from __future__ import annotations\n\nfrom typing import TYPE_CHECKING, Any\n\nif TYPE_CHECKING:\n    from collections.abc im"
  },
  {
    "path": "backend/src/hatchling/metadata/utils.py",
    "chars": 2560,
    "preview": "from __future__ import annotations\n\nimport re\nfrom typing import TYPE_CHECKING, Any\n\nif TYPE_CHECKING:\n    from packagin"
  },
  {
    "path": "backend/src/hatchling/ouroboros.py",
    "chars": 1507,
    "preview": "from __future__ import annotations\n\nimport os\nimport re\nfrom ast import literal_eval\nfrom typing import Any\n\nfrom hatchl"
  },
  {
    "path": "backend/src/hatchling/plugin/__init__.py",
    "chars": 57,
    "preview": "import pluggy\n\nhookimpl = pluggy.HookimplMarker(\"hatch\")\n"
  },
  {
    "path": "backend/src/hatchling/plugin/exceptions.py",
    "chars": 47,
    "preview": "class UnknownPluginError(ValueError):\n    pass\n"
  },
  {
    "path": "backend/src/hatchling/plugin/manager.py",
    "chars": 3731,
    "preview": "from __future__ import annotations\n\nfrom typing import TYPE_CHECKING, TypeVar\n\nimport pluggy\n\nif TYPE_CHECKING:\n    from"
  },
  {
    "path": "backend/src/hatchling/plugin/specs.py",
    "chars": 565,
    "preview": "import pluggy\n\nhookspec = pluggy.HookspecMarker(\"hatch\")\n\n\n@hookspec\ndef hatch_register_version_source() -> None:\n    \"\""
  },
  {
    "path": "backend/src/hatchling/plugin/utils.py",
    "chars": 1638,
    "preview": "from __future__ import annotations\n\nfrom typing import TYPE_CHECKING, TypeVar\n\nif TYPE_CHECKING:\n    from hatchling.buil"
  },
  {
    "path": "backend/src/hatchling/py.typed",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "backend/src/hatchling/utils/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "backend/src/hatchling/utils/constants.py",
    "chars": 149,
    "preview": "DEFAULT_BUILD_SCRIPT = \"hatch_build.py\"\nDEFAULT_CONFIG_FILE = \"hatch.toml\"\n\n\nclass VersionEnvVars:\n    VALIDATE_BUMP = \""
  },
  {
    "path": "backend/src/hatchling/utils/context.py",
    "chars": 6100,
    "preview": "from __future__ import annotations\n\nimport os\nimport string\nfrom abc import ABC, abstractmethod\nfrom collections import "
  },
  {
    "path": "backend/src/hatchling/utils/fs.py",
    "chars": 714,
    "preview": "from __future__ import annotations\n\nimport os\n\n\ndef locate_file(root: str, file_name: str, *, boundary: str | None = Non"
  },
  {
    "path": "backend/src/hatchling/version/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "backend/src/hatchling/version/core.py",
    "chars": 2153,
    "preview": "from __future__ import annotations\n\nimport os\nimport re\n\nDEFAULT_PATTERN = r'(?i)^(__version__|VERSION) *= *([\\'\"])v?(?P"
  },
  {
    "path": "backend/src/hatchling/version/scheme/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "backend/src/hatchling/version/scheme/plugin/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "backend/src/hatchling/version/scheme/plugin/hooks.py",
    "chars": 376,
    "preview": "from __future__ import annotations\n\nfrom typing import TYPE_CHECKING\n\nfrom hatchling.plugin import hookimpl\nfrom hatchli"
  },
  {
    "path": "backend/src/hatchling/version/scheme/plugin/interface.py",
    "chars": 2384,
    "preview": "from __future__ import annotations\n\nimport os\nfrom abc import ABC, abstractmethod\nfrom functools import cached_property\n"
  },
  {
    "path": "backend/src/hatchling/version/scheme/standard.py",
    "chars": 4420,
    "preview": "from __future__ import annotations\n\nfrom typing import TYPE_CHECKING, Any, Literal, cast\n\nfrom hatchling.version.scheme."
  },
  {
    "path": "backend/src/hatchling/version/source/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "backend/src/hatchling/version/source/code.py",
    "chars": 2348,
    "preview": "from __future__ import annotations\n\nimport os\n\nfrom hatchling.version.source.plugin.interface import VersionSourceInterf"
  },
  {
    "path": "backend/src/hatchling/version/source/env.py",
    "chars": 911,
    "preview": "from __future__ import annotations\n\nimport os\n\nfrom hatchling.version.source.plugin.interface import VersionSourceInterf"
  },
  {
    "path": "backend/src/hatchling/version/source/plugin/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "backend/src/hatchling/version/source/plugin/hooks.py",
    "chars": 502,
    "preview": "from __future__ import annotations\n\nfrom typing import TYPE_CHECKING\n\nfrom hatchling.plugin import hookimpl\nfrom hatchli"
  },
  {
    "path": "backend/src/hatchling/version/source/plugin/interface.py",
    "chars": 1852,
    "preview": "from __future__ import annotations\n\nfrom abc import ABC, abstractmethod\n\n\nclass VersionSourceInterface(ABC):  # no cov\n "
  },
  {
    "path": "backend/src/hatchling/version/source/regex.py",
    "chars": 1065,
    "preview": "from hatchling.version.core import VersionFile\nfrom hatchling.version.source.plugin.interface import VersionSourceInterf"
  },
  {
    "path": "backend/tests/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "backend/tests/downstream/datadogpy/data.json",
    "chars": 122,
    "preview": "{\n  \"repo_url\": \"https://github.com/DataDog/datadogpy\",\n  \"statements\": [\n    \"from datadog import initialize, api\"\n  ]\n"
  },
  {
    "path": "backend/tests/downstream/datadogpy/pyproject.toml",
    "chars": 1479,
    "preview": "[build-system]\nrequires = [\"hatchling\"]\nbuild-backend = \"hatchling.build\"\n\n[project]\nname = \"datadog\"\ndescription = \"The"
  },
  {
    "path": "backend/tests/downstream/hatch-showcase/data.json",
    "chars": 222,
    "preview": "{\n  \"repo_url\": \"https://github.com/ofek/hatch-showcase\",\n  \"statements\": [\n    \"from hatch_showcase.fib import fibonacc"
  },
  {
    "path": "backend/tests/downstream/integrate.py",
    "chars": 9462,
    "preview": "import errno\nimport json\nimport os\nimport platform\nimport shutil\nimport stat\nimport subprocess\nimport sys\nimport tempfil"
  },
  {
    "path": "backend/tests/downstream/requirements.txt",
    "chars": 46,
    "preview": "build\npackaging\nrequests\ntomli\nvirtualenv>=21\n"
  },
  {
    "path": "docs/.hooks/expand_blocks.py",
    "chars": 1351,
    "preview": "import re\nimport textwrap\n\nfrom markdown.preprocessors import Preprocessor\n\n_code_tab_regex = re.compile(\n    r'^( *)((`"
  },
  {
    "path": "docs/.hooks/inject_version.py",
    "chars": 968,
    "preview": "import os\nimport subprocess\nfrom functools import cache\n\nfrom markdown.preprocessors import Preprocessor\n\nMARKER = \"<HAT"
  },
  {
    "path": "docs/.hooks/plugin_register.py",
    "chars": 1059,
    "preview": "import os\nimport sys\n\nfrom markdown.extensions import Extension\n\nHERE = os.path.dirname(__file__)\n\n\ndef on_config(\n    c"
  },
  {
    "path": "docs/.hooks/render_default_test_env.py",
    "chars": 1788,
    "preview": "from __future__ import annotations\n\nimport os\nfrom ast import literal_eval\nfrom functools import cache\n\nimport tomlkit\nf"
  },
  {
    "path": "docs/.hooks/render_ruff_defaults.py",
    "chars": 7005,
    "preview": "from __future__ import annotations\n\nimport os\nimport re\nfrom collections import defaultdict\nfrom functools import cache\n"
  },
  {
    "path": "docs/.hooks/title_from_content.py",
    "chars": 387,
    "preview": "def on_page_markdown(\n    markdown,\n    page,\n    **kwargs,  # noqa: ARG001\n):\n    if \"title\" in page.meta:\n        retu"
  },
  {
    "path": "docs/.overrides/partials/copyright.html",
    "chars": 679,
    "preview": "<div class=\"md-copyright\">\n  {% if config.copyright %}\n    <div class=\"md-copyright__highlight\">\n      {{ config.copyrig"
  },
  {
    "path": "docs/.snippets/abbrs.txt",
    "chars": 30,
    "preview": "*[PyPI]: Python Package Index\n"
  },
  {
    "path": "docs/.snippets/links.txt",
    "chars": 452,
    "preview": "[PEP 440 version specifiers]: https://peps.python.org/pep-0440/#version-specifiers\n[PEP 508]: https://peps.python.org/pe"
  },
  {
    "path": "docs/assets/badge/v0.json",
    "chars": 5902,
    "preview": "{\"schemaVersion\":1,\"label\":\"\",\"message\":\"Hatch\",\"labelColor\":\"grey\",\"color\":\"#4051b5\",\"logoSvg\":\"<svg xmlns=\\\"http://www"
  },
  {
    "path": "docs/assets/css/custom.css",
    "chars": 712,
    "preview": ":root > * {\n  /* Use font but disable ligatures, see https://github.com/pypa/hatch/issues/104 */\n  font-variant-ligature"
  },
  {
    "path": "docs/blog/.authors.yml",
    "chars": 373,
    "preview": "authors:\n  ofek:\n    name: Ofek Lev\n    description: Creator\n    avatar: https://avatars.githubusercontent.com/u/9677399"
  },
  {
    "path": "docs/blog/index.md",
    "chars": 7,
    "preview": "# Blog\n"
  },
  {
    "path": "docs/blog/posts/release-hatch-1100.md",
    "chars": 6609,
    "preview": "---\ndate: 2024-05-02\nauthors: [ofek,flying-sheep]\ndescription: >-\n  Hatch v1.10.0 brings a test command, support for UV,"
  },
  {
    "path": "docs/blog/posts/release-hatch-1160.md",
    "chars": 3694,
    "preview": "---\ndate: 2025-11-24\nauthors: [cjames23]\ndescription: >-\n  Hatch v1.16.0 brings workspace support, dependency-groups, an"
  },
  {
    "path": "docs/blog/posts/release-hatch-160.md",
    "chars": 4744,
    "preview": "---\ndate: 2022-10-08\nauthors: [ofek]\ndescription: >-\n  Hatch v1.6.0 brings improvements to build environments, better ha"
  },
  {
    "path": "docs/blog/posts/release-hatch-180.md",
    "chars": 10285,
    "preview": "---\ndate: 2023-12-11\nauthors: [ofek]\ndescription: >-\n  Hatch v1.8.0 brings Python distribution management, static analys"
  },
  {
    "path": "docs/blog/posts/release-hatch-190.md",
    "chars": 1539,
    "preview": "---\ndate: 2023-12-18\nauthors: [ofek]\ndescription: >-\n  Hatch v1.9.0 brings improvements to static analysis and important"
  },
  {
    "path": "docs/build.md",
    "chars": 1675,
    "preview": "# Builds\n\n-----\n\n## Configuration\n\nBuilds are [configured](config/build.md) using the `tool.hatch.build` table. Every [t"
  },
  {
    "path": "docs/cli/about.md",
    "chars": 1413,
    "preview": "# CLI usage\n\n-----\n\n## Verbosity\n\nThe amount of displayed output is controlled solely by the `-v`/`--verbose` (environme"
  },
  {
    "path": "docs/cli/reference.md",
    "chars": 120,
    "preview": "::: mkdocs-click\n    :module: hatch.cli\n    :command: hatch\n    :depth: 0\n    :style: table\n    :remove_ascii_art: true\n"
  },
  {
    "path": "docs/community/contributing.md",
    "chars": 1040,
    "preview": "# Contributing\n\nThe usual process to make a contribution is to:\n\n1. Check for existing related issues\n2. Fork the reposi"
  },
  {
    "path": "docs/community/highlights.md",
    "chars": 420,
    "preview": "# Community highlights\n\n-----\n\n## Integration\n\n- Project Jupyter - https://blog.jupyter.org/packaging-for-jupyter-in-202"
  },
  {
    "path": "docs/community/users.md",
    "chars": 40501,
    "preview": "# Users\n\n-----\n\nThe following is not intended to be a complete enumeration. Be sure to view the [development version](/d"
  },
  {
    "path": "docs/config/build.md",
    "chars": 12618,
    "preview": "# Build configuration\n\n-----\n\n[Build targets](#build-targets) are defined as sections within `tool.hatch.build.targets`:"
  },
  {
    "path": "docs/config/context.md",
    "chars": 1918,
    "preview": "# Context formatting\n\n-----\n\nYou can populate configuration with the values of certain supported fields using the syntax"
  },
  {
    "path": "docs/config/dependency.md",
    "chars": 11435,
    "preview": "# Dependency configuration\n\n-----\n\n[Project dependencies](metadata.md#dependencies) are defined with [PEP 508][] strings"
  },
  {
    "path": "docs/config/environment/advanced.md",
    "chars": 11125,
    "preview": "# Advanced environment configuration\n\n-----\n\n## Context formatting\n\nAll environments support the following extra [contex"
  },
  {
    "path": "docs/config/environment/overview.md",
    "chars": 8526,
    "preview": "# Environment configuration\n\n-----\n\nAll environments are defined as sections within the `tool.hatch.envs` table.\n\n```tom"
  },
  {
    "path": "docs/config/hatch.md",
    "chars": 8647,
    "preview": "# Hatch configuration\n\n-----\n\nConfiguration for Hatch itself is stored in a `config.toml` file located by default in one"
  },
  {
    "path": "docs/config/internal/build.md",
    "chars": 1196,
    "preview": "#  Build environment configuration\n\n-----\n\nYou can fully alter the behavior of the environment used by the [`build`](../"
  },
  {
    "path": "docs/config/internal/static-analysis.md",
    "chars": 5108,
    "preview": "# Static analysis configuration\n\n-----\n\nStatic analysis performed by the [`fmt`](../../cli/reference.md#hatch-fmt) comma"
  },
  {
    "path": "docs/config/internal/testing.md",
    "chars": 3689,
    "preview": "# Testing configuration\n\n-----\n\nCheck out the [testing overview tutorial](../../tutorials/testing/overview.md) for a mor"
  },
  {
    "path": "docs/config/metadata.md",
    "chars": 5897,
    "preview": "# Configuring project metadata\n\n-----\n\nProject metadata is stored in a `pyproject.toml` file located at the root of a pr"
  },
  {
    "path": "docs/config/project-templates.md",
    "chars": 1369,
    "preview": "# Project templates\n\n-----\n\nYou can control how new projects are created by the [new](../cli/reference.md#hatch-new) com"
  },
  {
    "path": "docs/environment.md",
    "chars": 5432,
    "preview": "# Environments\n\n-----\n\n[Environments](config/environment/overview.md) are designed to allow for isolated workspaces for "
  },
  {
    "path": "docs/history/hatch.md",
    "chars": 24837,
    "preview": "# Hatch history\n\n-----\n\nAll notable changes to Hatch will be documented in this file.\n\nThe format is based on [Keep a Ch"
  },
  {
    "path": "docs/history/hatchling.md",
    "chars": 20981,
    "preview": "# Hatchling history\n\n-----\n\nAll notable changes to Hatchling will be documented in this file.\n\nThe format is based on [K"
  },
  {
    "path": "docs/how-to/config/dynamic-metadata.md",
    "chars": 3627,
    "preview": "# How to configure custom dynamic metadata\n\n----\n\nIf you have [project metadata](../../config/metadata.md) that is not a"
  },
  {
    "path": "docs/how-to/environment/dependency-resolution.md",
    "chars": 1760,
    "preview": "# How to configure dependency resolution\n\n-----\n\nMost Hatch environment types, like the default [virtual](../../plugins/"
  },
  {
    "path": "docs/how-to/environment/select-installer.md",
    "chars": 2761,
    "preview": "# How to select the installer\n\n-----\n\n## Enabling UV\n\nThe [virtual](../../plugins/environment/virtual.md) environment ty"
  },
  {
    "path": "docs/how-to/environment/workspace.md",
    "chars": 4255,
    "preview": "# How to configure workspace environments\n\n-----\n\nWorkspace environments allow you to manage multiple related packages w"
  },
  {
    "path": "docs/how-to/integrate/vscode.md",
    "chars": 2114,
    "preview": "# How to use Hatch environments from Visual Studio Code\n\n-----\n\nVisual Studio Code announced support for [Hatch environm"
  },
  {
    "path": "docs/how-to/meta/report-issues.md",
    "chars": 1299,
    "preview": "# How to report issues\n\n-----\n\nAll reports regarding unexpected behavior should be generated with the [`self report`](.."
  },
  {
    "path": "docs/how-to/plugins/testing-builds.md",
    "chars": 2049,
    "preview": "# Testing build plugins\n\n-----\n\nFor testing [Hatchling plugins](../../plugins/about.md#hatchling), you'll usually want t"
  },
  {
    "path": "docs/how-to/publish/auth.md",
    "chars": 1442,
    "preview": "# How to authenticate for index publishing\n\n----\n\nThe username is derived from the following sources, in order of preced"
  },
  {
    "path": "docs/how-to/publish/repo.md",
    "chars": 703,
    "preview": "# How to configure repositories for index publishing\n\n----\n\nYou can select the repository with which to upload using the"
  },
  {
    "path": "docs/how-to/python/custom.md",
    "chars": 2070,
    "preview": "# How to use custom Python distributions\n\n----\n\nThe built-in [Python management](../../tutorials/python/manage.md) capab"
  },
  {
    "path": "docs/how-to/run/python-scripts.md",
    "chars": 2801,
    "preview": "# How to run Python scripts\n\n-----\n\nThe [`run`](../../cli/reference.md#hatch-run) command supports executing Python scri"
  },
  {
    "path": "docs/how-to/static-analysis/behavior.md",
    "chars": 2066,
    "preview": "# Customize static analysis behavior\n\n-----\n\nYou can [fully alter](../../config/internal/static-analysis.md#customize-be"
  },
  {
    "path": "docs/index.md",
    "chars": 5372,
    "preview": "# Hatch\n\n<div class=\"grid\" markdown>\n\n![Hatch logo](assets/images/logo.svg){ role=\"img\" }\n\n| | |\n| --- | --- |\n| CI/CD |"
  },
  {
    "path": "docs/install.md",
    "chars": 6499,
    "preview": "# Installation\n\n-----\n\n## GitHub Actions\n\n```yaml\n- name: Install Hatch\n  uses: pypa/hatch@install\n```\n\nRefer to the [of"
  },
  {
    "path": "docs/intro.md",
    "chars": 2164,
    "preview": "# Introduction\n\n-----\n\n## Setup\n\nProjects can be set up for use by Hatch using the [`new`](cli/reference.md#hatch-new) c"
  },
  {
    "path": "docs/meta/authors.md",
    "chars": 1126,
    "preview": "# Authors\n\n-----\n\n## Maintainers\n\n- Ofek Lev [:material-web:](https://ofek.dev) [:material-github:](https://github.com/o"
  },
  {
    "path": "docs/meta/faq.md",
    "chars": 5675,
    "preview": "# FAQ\n\n-----\n\n## Interoperability\n\n***Q***: What is the risk of lock-in?\n\n***A***: Not much! Other than the [plugin syst"
  },
  {
    "path": "docs/next-steps.md",
    "chars": 1332,
    "preview": "# Next steps\n\n-----\n\n## Learn more\n\nAt this point you should have a basic understanding of how to use Hatch.\n\nNow you ma"
  },
  {
    "path": "docs/plugins/about.md",
    "chars": 2468,
    "preview": "# Plugins\n\n-----\n\nHatch utilizes [pluggy](https://github.com/pytest-dev/pluggy) for its plugin functionality.\n\n## Overvi"
  },
  {
    "path": "docs/plugins/build-hook/custom.md",
    "chars": 958,
    "preview": "# Custom build hook\n\n-----\n\nThis is a custom class in a given Python file that inherits from the [BuildHookInterface](re"
  },
  {
    "path": "docs/plugins/build-hook/reference.md",
    "chars": 3862,
    "preview": "# Build hook plugins\n\n-----\n\nA build hook provides code that will be executed at various stages of the build process. Se"
  },
  {
    "path": "docs/plugins/build-hook/version.md",
    "chars": 835,
    "preview": "# Version build hook\n\n-----\n\nThis writes the project's version to a file.\n\n## Configuration\n\nThe build hook plugin name "
  },
  {
    "path": "docs/plugins/builder/binary.md",
    "chars": 1764,
    "preview": "# Binary builder\n\n-----\n\nThis uses [PyApp](https://github.com/ofek/pyapp) to build an application that is able to bootst"
  },
  {
    "path": "docs/plugins/builder/custom.md",
    "chars": 864,
    "preview": "# Custom builder\n\n-----\n\nThis is a custom class in a given Python file that inherits from the [BuilderInterface](referen"
  },
  {
    "path": "docs/plugins/builder/reference.md",
    "chars": 748,
    "preview": "# Builder plugins\n\n-----\n\nSee the documentation for [build configuration](../../config/build.md).\n\n## Known third-party\n"
  },
  {
    "path": "docs/plugins/builder/sdist.md",
    "chars": 1802,
    "preview": "# Source distribution builder\n\n-----\n\nA source distribution, or `sdist`, is an archive of Python \"source code\". Although"
  },
  {
    "path": "docs/plugins/builder/wheel.md",
    "chars": 4852,
    "preview": "# Wheel builder\n\n-----\n\nA [wheel](https://packaging.python.org/specifications/binary-distribution-format/) is a binary d"
  },
  {
    "path": "docs/plugins/environment/reference.md",
    "chars": 3047,
    "preview": "# Environment plugins\n\n-----\n\nSee the documentation for [environment configuration](../../config/environment/overview.md"
  },
  {
    "path": "docs/plugins/environment/virtual.md",
    "chars": 7034,
    "preview": "# Virtual environment\n\n-----\n\nThis uses virtual environments backed by [virtualenv](https://github.com/pypa/virtualenv) "
  },
  {
    "path": "docs/plugins/environment-collector/custom.md",
    "chars": 1021,
    "preview": "# Custom environment collector\n\n-----\n\nThis is a custom class in a given Python file that inherits from the [Environment"
  },
  {
    "path": "docs/plugins/environment-collector/default.md",
    "chars": 393,
    "preview": "# Default environment collector\n\n-----\n\nThis adds the `default` environment with [type](../../config/environment/overvie"
  },
  {
    "path": "docs/plugins/environment-collector/reference.md",
    "chars": 890,
    "preview": "# Environment collector plugins\n\n-----\n\nEnvironment collectors allow for dynamically modifying environments or adding en"
  },
  {
    "path": "docs/plugins/metadata-hook/custom.md",
    "chars": 916,
    "preview": "# Custom metadata hook\n\n-----\n\nThis is a custom class in a given Python file that inherits from the [MetadataHookInterfa"
  },
  {
    "path": "docs/plugins/metadata-hook/reference.md",
    "chars": 1136,
    "preview": "# Metadata hook plugins\n\n-----\n\nMetadata hooks allow for the modification of [project metadata](../../config/metadata.md"
  },
  {
    "path": "docs/plugins/publisher/package-index.md",
    "chars": 1613,
    "preview": "# Index publisher\n\n-----\n\nSee the documentation for [publishing](../../publish.md).\n\n## Options\n\n| Flag | Config name | "
  },
  {
    "path": "docs/plugins/publisher/reference.md",
    "chars": 389,
    "preview": "# Publisher plugins\n\n-----\n\n## Known third-party\n\n- [hatch-aws-publisher](https://github.com/aka-raccoon/hatch-aws-publi"
  },
  {
    "path": "docs/plugins/utilities.md",
    "chars": 1397,
    "preview": "# Plugin utilities\n\n-----\n\n::: hatchling.builders.utils.get_reproducible_timestamp\n    options:\n      show_root_full_pat"
  },
  {
    "path": "docs/plugins/version-scheme/reference.md",
    "chars": 345,
    "preview": "# Version scheme plugins\n\n-----\n\n## Known third-party\n\n- [hatch-semver](https://github.com/Nagidal/hatch-semver) - uses "
  },
  {
    "path": "docs/plugins/version-scheme/standard.md",
    "chars": 448,
    "preview": "# Standard version scheme\n\n-----\n\nSee the documentation for [versioning](../../version.md#updating).\n\n## Configuration\n\n"
  },
  {
    "path": "docs/plugins/version-source/code.md",
    "chars": 1255,
    "preview": "# Code version source\n\n-----\n\n## Updates\n\nSetting the version is not supported.\n\n## Configuration\n\nThe version source pl"
  },
  {
    "path": "docs/plugins/version-source/env.md",
    "chars": 468,
    "preview": "# Environment version source\n\n-----\n\nRetrieves the version from an environment variable. This can be useful in build pip"
  },
  {
    "path": "docs/plugins/version-source/reference.md",
    "chars": 768,
    "preview": "# Version source plugins\n\n-----\n\n## Known third-party\n\n- [hatch-vcs](https://github.com/ofek/hatch-vcs) - uses your pref"
  },
  {
    "path": "docs/plugins/version-source/regex.md",
    "chars": 678,
    "preview": "# Regex version source\n\n-----\n\nSee the documentation for [versioning](../../version.md).\n\n## Updates\n\nSetting the versio"
  },
  {
    "path": "docs/publish.md",
    "chars": 1172,
    "preview": "# Publishing\n\n-----\n\nAfter your project is [built](build.md), you can distribute it using the [`publish`](cli/reference."
  },
  {
    "path": "docs/tutorials/environment/basic-usage.md",
    "chars": 5838,
    "preview": "# Managing environments\n\n-----\n\nHatch [environments](../../environment.md) are isolated workspaces that can be used for "
  },
  {
    "path": "docs/tutorials/python/manage.md",
    "chars": 4354,
    "preview": "# Managing Python distributions\n\n-----\n\nThe [`python`](../../cli/reference.md#hatch-python) command group provides a set"
  },
  {
    "path": "docs/tutorials/testing/overview.md",
    "chars": 6938,
    "preview": "# Testing projects\n\n-----\n\nThe [`test`](../../cli/reference.md#hatch-test) command ([by default](../../config/internal/t"
  },
  {
    "path": "docs/version.md",
    "chars": 2698,
    "preview": "# Versioning\n\n-----\n\n## Configuration\n\nWhen the version is not [statically set](config/metadata.md#version), configurati"
  },
  {
    "path": "docs/why.md",
    "chars": 10207,
    "preview": "# Why Hatch?\n\n-----\n\nThe high level value proposition of Hatch is that if one adopts all functionality then many other t"
  },
  {
    "path": "hatch.toml",
    "chars": 3212,
    "preview": "\n[envs.hatch-static-analysis]\nconfig-path = \"ruff_defaults.toml\"\n\n[envs.default]\ninstaller = \"uv\"\n\n\n[envs.hatch-test]\nwo"
  },
  {
    "path": "mkdocs.insiders.yml",
    "chars": 596,
    "preview": "INHERIT: mkdocs.yml\n\nplugins:\n  git-committers:\n    repository: pypa/hatch\n    enabled: !ENV [GITHUB_ACTIONS, false]\n   "
  },
  {
    "path": "mkdocs.yml",
    "chars": 8795,
    "preview": "site_name: Hatch\nsite_description: Modern, extensible Python project management\nsite_author: Ofek Lev\nsite_url: https://"
  },
  {
    "path": "pyoxidizer.bzl",
    "chars": 2304,
    "preview": "VERSION = VARS[\"version\"]\nAPP_NAME = \"hatch\"\nDISPLAY_NAME = \"Hatch\"\nAUTHOR = \"Python Packaging Authority\"\n\n\ndef make_msi"
  },
  {
    "path": "pyproject.toml",
    "chars": 3410,
    "preview": "[build-system]\nrequires = [\"hatchling>=1.27\", \"hatch-vcs>=0.3.0\"]\nbuild-backend = \"hatchling.build\"\n\n[project]\nname = \"h"
  },
  {
    "path": "release/README.md",
    "chars": 116,
    "preview": "# Release assets\n\n-----\n\nThis directory stores files related to building binaries and installers for each platform.\n"
  },
  {
    "path": "release/macos/build_pkg.py",
    "chars": 3959,
    "preview": "\"\"\"\nThis script must be run from the root of the repository.\n\nAt a high level, the goal is to have a directory that emul"
  },
  {
    "path": "release/macos/pkg/distribution.xml",
    "chars": 994,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<installer-gui-script minSpecVersion=\"1\">\n  <!--\n  https://developer.apple.com/li"
  },
  {
    "path": "release/unix/make_scripts_portable.py",
    "chars": 1393,
    "preview": "from __future__ import annotations\n\nimport sys\nimport sysconfig\nfrom io import BytesIO\nfrom pathlib import Path\n\n\ndef ma"
  },
  {
    "path": "release/windows/make_scripts_portable.py",
    "chars": 3242,
    "preview": "from __future__ import annotations\n\nimport sys\nimport sysconfig\nfrom contextlib import closing\nfrom importlib.metadata i"
  },
  {
    "path": "ruff.toml",
    "chars": 525,
    "preview": "extend = \"ruff_defaults.toml\"\n\n# https://github.com/astral-sh/ruff/issues/8627\nexclude = [\".git\", \".mypy_cache\", \".ruff_"
  },
  {
    "path": "ruff_defaults.toml",
    "chars": 7697,
    "preview": "line-length = 120\n\n[format]\ndocstring-code-format = true\ndocstring-code-line-length = 80\n\n[lint]\nselect = [\n  \"A001\",\n  "
  },
  {
    "path": "scripts/bump.py",
    "chars": 2152,
    "preview": "import argparse\nimport re\nimport subprocess\nfrom datetime import datetime, timezone\n\nfrom utils import ROOT, get_latest_"
  },
  {
    "path": "scripts/generate_coverage_summary.py",
    "chars": 1807,
    "preview": "import json\nfrom collections import defaultdict\n\nfrom lxml import etree  # nosec B410\nfrom utils import ROOT\n\nPACKAGES ="
  },
  {
    "path": "scripts/install_mkdocs_material_insiders.py",
    "chars": 934,
    "preview": "import os\nimport subprocess\nimport sys\n\nTOKEN = os.environ.get(\"GH_TOKEN_MKDOCS_MATERIAL_INSIDERS\", \"\")\nDEP_REF = f\"git+"
  },
  {
    "path": "scripts/release_github.py",
    "chars": 1076,
    "preview": "import argparse\nimport subprocess\nimport sys\nimport webbrowser\nfrom urllib.parse import urlencode\n\nfrom utils import get"
  },
  {
    "path": "scripts/set_release_version.py",
    "chars": 311,
    "preview": "import os\n\nfrom utils import get_latest_release\n\n\ndef main():\n    version, _ = get_latest_release(\"hatch\")\n    parts = v"
  },
  {
    "path": "scripts/update_distributions.py",
    "chars": 2744,
    "preview": "from __future__ import annotations\n\nimport re\nfrom ast import literal_eval\nfrom collections import defaultdict\n\nimport h"
  },
  {
    "path": "scripts/update_ruff.py",
    "chars": 5921,
    "preview": "from __future__ import annotations\n\nimport json\nimport re\nimport subprocess\nimport sys\nimport typing\nfrom importlib.meta"
  }
]

// ... and 299 more files (download for full content)

About this extraction

This page contains the full source code of the pypa/hatch GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 499 files (2.6 MB), approximately 703.1k tokens, and a symbol index with 3469 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!