Repository: pdm-project/pdm Branch: main Commit: d14eebc6ae12 Files: 373 Total size: 1.8 MB Directory structure: gitextract_02e0wlec/ ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.yml │ │ └── feature_request.yml │ ├── PULL_REQUEST_TEMPLATE.md │ ├── dependabot.yml │ └── workflows/ │ ├── ci.yml │ ├── claude.yml │ └── release.yml ├── .gitignore ├── .pre-commit-config.yaml ├── .pre-commit-hooks.yaml ├── .readthedocs.yaml ├── AGENTS.md ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── README_zh.md ├── SECURITY.md ├── codecov.yml ├── docs/ │ ├── assets/ │ │ ├── extra.css │ │ └── extra.js │ ├── dev/ │ │ ├── benchmark.md │ │ ├── changelog.md │ │ ├── contributing.md │ │ ├── fixtures.md │ │ └── write.md │ ├── index.md │ ├── overrides/ │ │ └── main.html │ ├── reference/ │ │ ├── api.md │ │ ├── build.md │ │ ├── cli.md │ │ ├── configuration.md │ │ └── pep621.md │ └── usage/ │ ├── advanced.md │ ├── config.md │ ├── dependency.md │ ├── hooks.md │ ├── lock-targets.md │ ├── lockfile.md │ ├── pep582.md │ ├── project.md │ ├── publish.md │ ├── scripts.md │ ├── template.md │ ├── uv.md │ └── venv.md ├── install-pdm.ps1 ├── install-pdm.py ├── install-pdm.py.sha256 ├── install-pdm.sh ├── mkdocs.yml ├── news/ │ ├── .gitkeep │ └── 3541.misc.md ├── pyproject.toml ├── src/ │ └── pdm/ │ ├── __init__.py │ ├── __main__.py │ ├── __version__.py │ ├── _types.py │ ├── builders/ │ │ ├── __init__.py │ │ ├── base.py │ │ ├── editable.py │ │ ├── sdist.py │ │ └── wheel.py │ ├── cli/ │ │ ├── __init__.py │ │ ├── actions.py │ │ ├── commands/ │ │ │ ├── __init__.py │ │ │ ├── add.py │ │ │ ├── base.py │ │ │ ├── build.py │ │ │ ├── cache.py │ │ │ ├── completion.py │ │ │ ├── config.py │ │ │ ├── export.py │ │ │ ├── fix/ │ │ │ │ ├── __init__.py │ │ │ │ └── fixers.py │ │ │ ├── import_cmd.py │ │ │ ├── info.py │ │ │ ├── init.py │ │ │ ├── install.py │ │ │ ├── list.py │ │ │ ├── lock.py │ │ │ ├── new.py │ │ │ ├── outdated.py │ │ │ ├── publish/ │ │ │ │ ├── __init__.py │ │ │ │ ├── package.py │ │ │ │ └── repository.py │ │ │ ├── python.py │ │ │ ├── remove.py │ │ │ ├── run.py │ │ │ ├── search.py │ │ │ ├── self_cmd.py │ │ │ ├── show.py │ │ │ ├── sync.py │ │ │ ├── update.py │ │ │ ├── use.py │ │ │ └── venv/ │ │ │ ├── __init__.py │ │ │ ├── activate.py │ │ │ ├── backends.py │ │ │ ├── create.py │ │ │ ├── list.py │ │ │ ├── purge.py │ │ │ ├── remove.py │ │ │ └── utils.py │ │ ├── completions/ │ │ │ ├── __init__.py │ │ │ ├── pdm.bash │ │ │ ├── pdm.fish │ │ │ ├── pdm.ps1 │ │ │ └── pdm.zsh │ │ ├── filters.py │ │ ├── hooks.py │ │ ├── options.py │ │ ├── templates/ │ │ │ ├── __init__.py │ │ │ ├── default/ │ │ │ │ ├── .gitignore │ │ │ │ ├── README.md │ │ │ │ ├── __init__.py │ │ │ │ ├── pyproject.toml │ │ │ │ ├── src/ │ │ │ │ │ └── example_package/ │ │ │ │ │ └── __init__.py │ │ │ │ └── tests/ │ │ │ │ └── __init__.py │ │ │ └── minimal/ │ │ │ ├── .gitignore │ │ │ ├── __init__.py │ │ │ └── pyproject.toml │ │ └── utils.py │ ├── compat.py │ ├── core.py │ ├── environments/ │ │ ├── __init__.py │ │ ├── base.py │ │ ├── local.py │ │ └── python.py │ ├── exceptions.py │ ├── formats/ │ │ ├── __init__.py │ │ ├── base.py │ │ ├── flit.py │ │ ├── pipfile.py │ │ ├── poetry.py │ │ ├── pylock.py │ │ ├── requirements.py │ │ ├── setup_py.py │ │ └── uv.py │ ├── installers/ │ │ ├── __init__.py │ │ ├── base.py │ │ ├── core.py │ │ ├── installers.py │ │ ├── manager.py │ │ ├── synchronizers.py │ │ ├── uninstallers.py │ │ └── uv.py │ ├── misc/ │ │ ├── __init__.py │ │ └── sysconfig_patcher.py │ ├── models/ │ │ ├── __init__.py │ │ ├── auth.py │ │ ├── backends.py │ │ ├── cached_package.py │ │ ├── caches.py │ │ ├── candidates.py │ │ ├── finder.py │ │ ├── in_process/ │ │ │ ├── __init__.py │ │ │ ├── env_spec.py │ │ │ ├── parse_setup.py │ │ │ └── sysconfig_get_paths.py │ │ ├── markers.py │ │ ├── project_info.py │ │ ├── python.py │ │ ├── python_max_versions.json │ │ ├── reporter.py │ │ ├── repositories/ │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ ├── lock.py │ │ │ └── pypi.py │ │ ├── requirements.py │ │ ├── search.py │ │ ├── session.py │ │ ├── setup.py │ │ ├── specifiers.py │ │ ├── venv.py │ │ ├── versions.py │ │ └── working_set.py │ ├── pep582/ │ │ ├── __init__.py │ │ └── sitecustomize.py │ ├── project/ │ │ ├── __init__.py │ │ ├── config.py │ │ ├── core.py │ │ ├── lockfile/ │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ ├── pdmlock.py │ │ │ └── pylock.py │ │ ├── project_file.py │ │ └── toml_file.py │ ├── py.typed │ ├── pytest.py │ ├── resolver/ │ │ ├── __init__.py │ │ ├── base.py │ │ ├── graph.py │ │ ├── providers.py │ │ ├── python.py │ │ ├── reporters.py │ │ ├── resolvelib.py │ │ └── uv.py │ ├── signals.py │ ├── termui.py │ └── utils.py ├── tasks/ │ ├── complete.py │ ├── max_versions.py │ └── release.py ├── tests/ │ ├── __init__.py │ ├── cli/ │ │ ├── __init__.py │ │ ├── conftest.py │ │ ├── test_add.py │ │ ├── test_build.py │ │ ├── test_cache.py │ │ ├── test_completion.py │ │ ├── test_config.py │ │ ├── test_fix.py │ │ ├── test_hooks.py │ │ ├── test_info.py │ │ ├── test_init.py │ │ ├── test_install.py │ │ ├── test_list.py │ │ ├── test_lock.py │ │ ├── test_others.py │ │ ├── test_outdated.py │ │ ├── test_publish.py │ │ ├── test_python.py │ │ ├── test_remove.py │ │ ├── test_run.py │ │ ├── test_search.py │ │ ├── test_self_command.py │ │ ├── test_show.py │ │ ├── test_template.py │ │ ├── test_update.py │ │ ├── test_use.py │ │ ├── test_utils.py │ │ └── test_venv.py │ ├── conftest.py │ ├── environments/ │ │ ├── test_environment.py │ │ └── test_shebangs.py │ ├── fixtures/ │ │ ├── Pipfile │ │ ├── __init__.py │ │ ├── artifacts/ │ │ │ ├── PyFunctional-1.4.3-py3-none-any.whl │ │ │ ├── celery-4.4.2-py2.py3-none-any.whl │ │ │ ├── demo-0.0.1-cp36-cp36m-win_amd64.whl │ │ │ ├── demo-0.0.1-py2.py3-none-any.whl │ │ │ ├── editables-0.2-py3-none-any.whl │ │ │ ├── first-2.0.2-py2.py3-none-any.whl │ │ │ ├── flit_core-3.6.0-py3-none-any.whl │ │ │ ├── future_fstrings-1.2.0-py2.py3-none-any.whl │ │ │ ├── importlib_metadata-4.8.3-py3-none-any.whl │ │ │ ├── jmespath-0.10.0-py2.py3-none-any.whl │ │ │ ├── pdm_backend-2.1.4-py3-none-any.whl │ │ │ ├── pdm_hello-0.1.0-py3-none-any.whl │ │ │ ├── pdm_hello-0.1.0-py3-none-win_amd64.whl │ │ │ ├── pdm_pep517-1.0.0-py3-none-any.whl │ │ │ ├── poetry_core-1.3.2-py3-none-any.whl │ │ │ ├── setuptools-68.0.0-py3-none-any.whl │ │ │ ├── typing_extensions-4.4.0-py3-none-any.whl │ │ │ ├── wheel-0.37.1-py2.py3-none-any.whl │ │ │ ├── zipp-3.6.0-py3-none-any.whl │ │ │ └── zipp-3.7.0-py3-none-any.whl │ │ ├── constraints.txt │ │ ├── index/ │ │ │ ├── demo.html │ │ │ ├── future-fstrings.html │ │ │ ├── pep345-legacy.html │ │ │ └── wheel.html │ │ ├── json/ │ │ │ └── zipp.json │ │ ├── poetry-error.toml │ │ ├── poetry-new.toml │ │ ├── projects/ │ │ │ ├── __init__.py │ │ │ ├── demo/ │ │ │ │ ├── demo.py │ │ │ │ ├── pylock.toml │ │ │ │ └── pyproject.toml │ │ │ ├── demo-#-with-hash/ │ │ │ │ ├── demo.py │ │ │ │ └── setup.py │ │ │ ├── demo-combined-extras/ │ │ │ │ ├── demo.py │ │ │ │ └── pyproject.toml │ │ │ ├── demo-failure/ │ │ │ │ ├── demo.py │ │ │ │ └── setup.py │ │ │ ├── demo-failure-no-dep/ │ │ │ │ ├── demo.py │ │ │ │ └── setup.py │ │ │ ├── demo-module/ │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── bar_module.py │ │ │ │ ├── foo_module.py │ │ │ │ └── pyproject.toml │ │ │ ├── demo-package/ │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── data_out.json │ │ │ │ ├── my_package/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── data.json │ │ │ │ ├── pyproject.toml │ │ │ │ ├── requirements.ini │ │ │ │ ├── requirements.txt │ │ │ │ ├── requirements_simple.txt │ │ │ │ ├── setup.txt │ │ │ │ └── single_module.py │ │ │ ├── demo-package-has-dep-with-extras/ │ │ │ │ ├── pyproject.toml │ │ │ │ └── requirements.txt │ │ │ ├── demo-parent-package/ │ │ │ │ ├── README.md │ │ │ │ ├── package-a/ │ │ │ │ │ ├── foo.py │ │ │ │ │ └── setup.py │ │ │ │ └── package-b/ │ │ │ │ ├── bar.py │ │ │ │ └── pyproject.toml │ │ │ ├── demo-prerelease/ │ │ │ │ ├── demo.py │ │ │ │ └── setup.py │ │ │ ├── demo-src-package/ │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── data_out.json │ │ │ │ ├── pyproject.toml │ │ │ │ ├── single_module.py │ │ │ │ └── src/ │ │ │ │ └── my_package/ │ │ │ │ ├── __init__.py │ │ │ │ └── data.json │ │ │ ├── demo_extras/ │ │ │ │ ├── demo.py │ │ │ │ └── setup.py │ │ │ ├── flit-demo/ │ │ │ │ ├── README.rst │ │ │ │ ├── doc/ │ │ │ │ │ └── index.html │ │ │ │ ├── flit.py │ │ │ │ └── pyproject.toml │ │ │ ├── poetry-demo/ │ │ │ │ ├── mylib.py │ │ │ │ └── pyproject.toml │ │ │ ├── poetry-with-circular-dep/ │ │ │ │ ├── packages/ │ │ │ │ │ └── child/ │ │ │ │ │ ├── child/ │ │ │ │ │ │ └── __init__.py │ │ │ │ │ └── pyproject.toml │ │ │ │ ├── parent/ │ │ │ │ │ └── __init__.py │ │ │ │ └── pyproject.toml │ │ │ ├── test-hatch-static/ │ │ │ │ ├── README.md │ │ │ │ └── pyproject.toml │ │ │ ├── test-monorepo/ │ │ │ │ ├── README.md │ │ │ │ ├── core/ │ │ │ │ │ ├── core.py │ │ │ │ │ └── pyproject.toml │ │ │ │ ├── package_a/ │ │ │ │ │ ├── alice.py │ │ │ │ │ └── pyproject.toml │ │ │ │ ├── package_b/ │ │ │ │ │ ├── bob.py │ │ │ │ │ └── pyproject.toml │ │ │ │ └── pyproject.toml │ │ │ ├── test-package-type-fixer/ │ │ │ │ ├── pyproject.toml │ │ │ │ └── src/ │ │ │ │ └── test_package_type_fixer/ │ │ │ │ └── __init__.py │ │ │ ├── test-plugin/ │ │ │ │ ├── hello.py │ │ │ │ └── setup.py │ │ │ ├── test-plugin-pdm/ │ │ │ │ ├── hello.py │ │ │ │ └── pyproject.toml │ │ │ ├── test-removal/ │ │ │ │ ├── __init__.py │ │ │ │ ├── bar.py │ │ │ │ ├── foo.py │ │ │ │ └── subdir/ │ │ │ │ └── __init__.py │ │ │ └── test-setuptools/ │ │ │ ├── AUTHORS │ │ │ ├── README.md │ │ │ ├── mymodule.py │ │ │ ├── setup.cfg │ │ │ └── setup.py │ │ ├── pypi.json │ │ ├── pyproject.toml │ │ ├── requirements-include.txt │ │ └── requirements.txt │ ├── models/ │ │ ├── __init__.py │ │ ├── test_backends.py │ │ ├── test_candidates.py │ │ ├── test_marker.py │ │ ├── test_requirements.py │ │ ├── test_session.py │ │ ├── test_setup_parsing.py │ │ ├── test_setup_parsing_extra.py │ │ ├── test_specifiers.py │ │ └── test_versions.py │ ├── resolver/ │ │ ├── __init__.py │ │ ├── test_graph.py │ │ ├── test_resolve.py │ │ └── test_uv_resolver.py │ ├── test_formats.py │ ├── test_installer.py │ ├── test_integration.py │ ├── test_plugin.py │ ├── test_project.py │ ├── test_signals.py │ └── test_utils.py ├── tox.ini └── typings/ └── shellingham.pyi ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.yml ================================================ name: "Bug report" description: Create a report to help us improve labels: ['🐛 bug'] body: - type: markdown attributes: value: "Thank you for taking the time to report a bug. Please provide as much information as possible to help us understand and resolve the issue." - type: textarea id: describe-bug attributes: label: Describe the bug description: "A clear and concise description of what the bug is." placeholder: "Describe the bug..." validations: required: true - type: textarea id: reproduce-bug attributes: label: To reproduce description: "Steps to reproduce the behavior." placeholder: "Steps to reproduce the behavior..." validations: required: true - type: textarea id: expected-behavior attributes: label: Expected Behavior description: "A clear and concise description of what you expected to happen." placeholder: "Explain what you expected to happen..." validations: required: true - type: textarea id: "environment-info" attributes: label: Environment Information description: "Paste the output of `pdm info && pdm info --env`" placeholder: "Paste the output of `pdm info && pdm info --env`" validations: required: true - type: textarea id: "pdm-debug-output" attributes: label: "Verbose Command Output" description: "Please provide the command output with `-v`." placeholder: "Add the command output with `-v`..." validations: required: false - type: textarea id: additional-context attributes: label: Additional Context description: "Add any other context about the problem here." placeholder: "Additional details..." validations: required: false - type: checkboxes id: willing-to-submit-pr attributes: label: "Are you willing to submit a PR to fix this bug?" description: "Let us know if you are willing to contribute a fix by submitting a Pull Request." options: - label: "Yes, I would like to submit a PR." ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.yml ================================================ name: "Feature / Enhancement Proposal" description: Suggest an idea for this project labels: ['⭐ enhancement'] body: - type: markdown attributes: value: "Thank you for suggesting a new feature. Please fill out the details below to help us understand your idea better." - type: textarea id: feature-description attributes: label: Feature Description description: "A detailed description of the feature you would like to see." placeholder: "Describe the feature you'd like..." validations: required: true - type: textarea id: problem-solution attributes: label: Problem and Solution description: "Describe the problem that this feature would solve. Explain how you envision it working." placeholder: "What problem does this feature solve? How do you envision it working?" validations: required: true - type: textarea id: additional-context attributes: label: Additional Context description: "Add any other context or screenshots about the feature request here." placeholder: "Add any other context or screenshots about the feature request here." validations: required: false - type: checkboxes id: willing-to-contribute attributes: label: "Are you willing to contribute to the development of this feature?" description: "Let us know if you are willing to help by contributing code or other resources." options: - label: "Yes, I am willing to contribute to the development of this feature." ================================================ FILE: .github/PULL_REQUEST_TEMPLATE.md ================================================ ## Pull Request Checklist - [ ] A news fragment is added in `news/` describing what is new. - [ ] Test cases added for changed code. ## Describe what you have changed in this PR. ================================================ FILE: .github/dependabot.yml ================================================ version: 2 updates: # Maintain dependencies for workflow actions - package-ecosystem: "github-actions" directory: "/" schedule: interval: "monthly" labels: - "github_actions" groups: actions: patterns: - "*" ================================================ FILE: .github/workflows/ci.yml ================================================ name: Tests on: pull_request: branches: - main - dev - "maintain/*" paths-ignore: - "docs/**" - "news/**" - "*.md" push: branches: - main - dev - "maintain/*" paths-ignore: - "docs/**" - "news/**" - "*.md" concurrency: group: ${{ github.event.number || github.run_id }} cancel-in-progress: true jobs: Testing: env: PYTHONDEVMODE: 1 runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: python-version: [3.9, "3.10", 3.11, 3.12, 3.13, 3.14] os: [ubuntu-latest, windows-latest, macos-latest] install-via: [pip] include: - python-version: 3.12 os: ubuntu-latest install-via: script - python-version: pypy-3.11 os: ubuntu-latest install-via: pip steps: - uses: actions/checkout@v6.0.2 - name: Setup Python Versions uses: actions/setup-python@v6 with: python-version: | 3.9 3.10 3.11 3.12 3.13 3.14 allow-prereleases: true if: matrix.os != 'macos-latest' - name: Setup Python Versions uses: actions/setup-python@v6 with: python-version: | 3.10 3.11 3.12 3.13 3.14 allow-prereleases: true if: matrix.os == 'macos-latest' - name: Setup Python ${{ matrix.python-version }} uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} cache: pip allow-prereleases: true - name: Cache venv uses: actions/cache@v5.0.3 with: path: .venv key: venv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('pdm.lock') }} - name: Install uv uses: astral-sh/setup-uv@v7.3.1 with: version: "latest" - name: Install current PDM via pip if: matrix.install-via == 'pip' run: python -m pip install -U . - name: Install current PDM via script if: matrix.install-via == 'script' run: | shasum -a256 --check install-pdm.py.sha256 python install-pdm.py --version head echo "$HOME/.local/bin" >> $GITHUB_PATH - name: Install Dev Dependencies run: | pdm install -v -Gtest pdm run pip install -U setuptools pdm info # - name: Setup tmate session # uses: mxschmitt/action-tmate@v3.22 - name: Run Tests run: pdm run pytest -n auto --cov=pdm --cov-config=pyproject.toml --cov-report=xml tests - name: Upload coverage to Codecov uses: codecov/codecov-action@v5.5.2 with: token: ${{ secrets.CODECOV_TOKEN }} file: ./coverage.xml flags: unittests Pack: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6.0.2 with: fetch-depth: 0 - uses: actions/setup-python@v6 with: python-version: 3.x - name: Install PDM run: | python -m pip install . pdm self add pdm-packer - name: Pack pdm run: pdm pack - name: Test zipapp run: python pdm.pyz --version ================================================ FILE: .github/workflows/claude.yml ================================================ name: Claude Code on: issue_comment: types: [created] pull_request_review_comment: types: [created] issues: types: [opened, assigned] pull_request_review: types: [submitted] jobs: claude: if: | (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) runs-on: ubuntu-latest permissions: contents: read pull-requests: read issues: read id-token: write actions: read # Required for Claude to read CI results on PRs steps: - name: Checkout repository uses: actions/checkout@v6.0.2 with: fetch-depth: 1 - name: Run Claude Code id: claude uses: anthropics/claude-code-action@v1.0.64 with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} # This is an optional setting that allows Claude to read CI results on PRs additional_permissions: | actions: read # Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4) # model: "claude-opus-4-20250514" # Optional: Customize the trigger phrase (default: @claude) # trigger_phrase: "/claude" # Optional: Trigger when specific user is assigned to an issue # assignee_trigger: "claude-bot" # Optional: Allow Claude to run specific commands # allowed_tools: "Bash(npm install),Bash(npm run build),Bash(npm run test:*),Bash(npm run lint:*)" # Optional: Add custom instructions for Claude to customize its behavior for your project # custom_instructions: | # Follow our coding standards # Ensure all new code has tests # Use TypeScript for new files # Optional: Custom environment variables for Claude # claude_env: | # NODE_ENV: test ================================================ FILE: .github/workflows/release.yml ================================================ name: Release on: push: tags: - "*" defaults: run: # make sure to work on Windows shell: bash jobs: release-pypi: name: release-pypi runs-on: ubuntu-latest permissions: id-token: write contents: write steps: - uses: actions/checkout@v6.0.2 - uses: actions/setup-python@v6 with: python-version: "3.11" cache: pip - name: Check prerelease id: check_version run: | if [[ "${{ github.ref }}" =~ ^refs/tags/[0-9.]+$ ]]; then echo "PRERELEASE=false" >> $GITHUB_OUTPUT else echo "PRERELEASE=true" >> $GITHUB_OUTPUT fi - name: Build artifacts run: | pipx run build - name: Upload artifacts uses: actions/upload-artifact@v7.0.0 with: name: pdm-wheel path: dist/*.whl if-no-files-found: error retention-days: 15 - name: Test Build run: | python -m pip install "pdm[locked] @ file://$(ls ${GITHUB_WORKSPACE}/dist/*.whl)" pdm --help - name: Publish package distributions to PyPI run: pdm publish --no-build - name: Get Changelog id: get-changelog run: | awk '/## Release/{if (flag==1)exit;else;flag=1;next} flag' CHANGELOG.md > .changelog.md - name: Create Release uses: actions/create-release@main env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: ${{ github.ref }} release_name: v${{ github.ref }} body_path: .changelog.md draft: false prerelease: ${{ steps.check_version.outputs.PRERELEASE }} - name: Trigger Bucket Update uses: benc-uk/workflow-dispatch@v1.3.1 with: workflow: Excavator repo: frostming/scoop-frostming token: ${{ secrets.G_T }} ref: master binary: needs: release-pypi runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ "ubuntu-24.04", "ubuntu-24.04-arm", "windows-2025", "macos-15-intel", "macos-15", ] env: PYAPP_REPO: pyapp PYAPP_VERSION: "0.27.0" PYAPP_PROJECT_NAME: pdm PYAPP_PROJECT_VERSION: ${{ github.ref_name }} PYAPP_SELF_COMMAND: app # since `self` has been taken in `pdm` PYAPP_DISTRIBUTION_EMBED: true PYAPP_PROJECT_FEATURES: locked SOURCE_FILE: ${{ matrix.os != 'windows-2025' && 'pyapp' || 'pyapp.exe' }} TARGET_FILE: ${{ matrix.os != 'windows-2025' && 'pdm' || 'pdm.exe' }} steps: - name: Checkout uses: actions/checkout@v6.0.2 - 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: Setup Rust uses: dtolnay/rust-toolchain@stable - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.9 if: matrix.os != 'macos-15-intel' - name: Set sccache env if: matrix.os != 'macos-15-intel' run: | echo "SCCACHE_GHA_ENABLED=true" >> $GITHUB_ENV echo "RUSTC_WRAPPER=sccache" >> $GITHUB_ENV - name: Download artifacts uses: actions/download-artifact@v8.0.0 with: name: pdm-wheel path: dist - name: Configure embedded wheel run: | cd dist wheel="$(echo *.whl)" mv $wheel ../$PYAPP_REPO echo "PYAPP_PROJECT_PATH=$wheel" >> $GITHUB_ENV echo "TARGET_TRIPLE=$(rustc --version --verbose | grep "host" | awk '{print $2}')" >> $GITHUB_ENV - name: Build run: | cd $PYAPP_REPO cargo build --release mv target/release/$SOURCE_FILE ../$TARGET_FILE - name: Upload Assets uses: actions/upload-artifact@v7.0.0 with: name: pdm-${{ github.ref_name }}-${{ env.TARGET_TRIPLE }} path: ${{ env.TARGET_FILE }} if-no-files-found: error retention-days: 15 - name: Create and Upload Archive with Checksum env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} UPLOAD_FILE: pdm-${{ github.ref_name }}-${{ env.TARGET_TRIPLE }}.tar.gz CHECKSUM_FILE: pdm-${{ github.ref_name }}-${{ env.TARGET_TRIPLE }}.tar.gz.sha256 run: | tar -czf $UPLOAD_FILE $TARGET_FILE if command -v sha256sum &> /dev/null; then sha256sum $UPLOAD_FILE > $CHECKSUM_FILE else shasum -a 256 $UPLOAD_FILE > $CHECKSUM_FILE fi gh release upload ${{ github.ref_name }} $UPLOAD_FILE $CHECKSUM_FILE --clobber ================================================ FILE: .gitignore ================================================ # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ pip-wheel-metadata/ share/python-wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover *.py,cover .hypothesis/ .pytest_cache/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py db.sqlite3 db.sqlite3-journal # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ docs/site # PyBuilder target/ # Jupyter Notebook .ipynb_checkpoints # IPython profile_default/ ipython_config.py # pyenv .python-version # pipenv # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. # However, in case of collaboration, if having platform-specific dependencies or dependencies # having no cross-platform support, pipenv may install dependencies that don't work, or not # install all needed dependencies. #Pipfile.lock # PEP 582; used by e.g. github.com/David-OConnor/pyflow __pypackages__/ # Celery stuff celerybeat-schedule celerybeat.pid # SageMath parsed files *.sage.py # Environments .env .venv env/ /venv/ ENV/ env.bak/ venv.bak/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ .dmypy.json dmypy.json # Pyre type checker .pyre/ .vscode/ caches/ .idea/ __pypackages__ .pdm.toml .pdm-python temp.py # Pyannotate generated stubs type_info.json .pdm-build/ src/pdm/VERSION .zed/ ================================================ FILE: .pre-commit-config.yaml ================================================ ci: autoupdate_schedule: monthly repos: - repo: https://github.com/astral-sh/ruff-pre-commit rev: 'v0.15.4' hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix, --show-fixes] - id: ruff-format - repo: https://github.com/codespell-project/codespell rev: v2.4.1 hooks: - id: codespell # See pyproject.toml for args additional_dependencies: - tomli - repo: https://github.com/pre-commit/mirrors-mypy rev: v1.19.1 hooks: - id: mypy args: [src] pass_filenames: false additional_dependencies: - types-requests - types-certifi - pytest ================================================ FILE: .pre-commit-hooks.yaml ================================================ - id: pdm-lock-check name: pdm-lock-check description: run pdm lock --check to validate config entry: pdm lock --check language: python language_version: python3 pass_filenames: false files: ^pyproject.toml$ - id: pdm-export name: pdm-export-lock description: export locked packages to requirements.txt or setup.py entry: pdm export language: python language_version: python3 pass_filenames: false files: ^pdm.lock$ - id: pdm-sync name: pdm-sync description: sync current working set with pdm.lock entry: pdm sync language: python language_version: python3 pass_filenames: false stages: - post-checkout - post-merge - post-rewrite always_run: true ================================================ FILE: .readthedocs.yaml ================================================ # Read the Docs configuration file for MkDocs projects # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details # Required version: 2 # Set the version of Python and other tools you might need build: os: ubuntu-22.04 tools: python: "3.12" jobs: post_create_environment: - python install-pdm.py --path ~/.local/pdm - ~/.local/pdm/bin/pdm --version post_install: - VIRTUAL_ENV=$READTHEDOCS_VIRTUALENV_PATH ~/.local/pdm/bin/pdm install -dG doc mkdocs: configuration: mkdocs.yml ================================================ FILE: AGENTS.md ================================================ # AGENTS.md This file provides guidance to AI coding assistants when working with code in this repository. ## Project Overview PDM (Python Dependency Manager) is a modern Python package and dependency manager that supports the latest PEP standards (PEP 517, PEP 621). It provides fast dependency resolution, flexible plugin system, and centralized cache management similar to pnpm. ## Core Architecture ### Key Components 1. **Project Management** (`src/pdm/project/`): Handles pyproject.toml parsing, project configuration, and metadata management 2. **Dependency Resolution** (`src/pdm/resolver/`): Fast dependency resolver using resolvelib with custom optimizations for binary distributions 3. **Environment Management** (`src/pdm/environments/`): Manages Python environments (virtualenv, PEP 582, system) 4. **Installer System** (`src/pdm/installers/`): Installs and uninstalls packages into the site-packages directory with centralized cache support 5. **CLI System** (`src/pdm/cli/commands/`): Command-line interface using argparse with plugin support 6. **Repository Models** (`src/pdm/models/repositories/`): PyPI repository interaction and package finder 7. **Build System** (`src/pdm/builders/`): PEP 517 build front-end for creating wheels and sdists ### Command Entry Points All CLI commands are in `src/pdm/cli/commands/` with command registration in `src/pdm/core.py`. Commands inherit from `BaseCommand` and use decorator patterns for common options. ## Development Commands ### Setup Development Environment ```bash # Install development dependencies pdm install ``` ### Run Tests ```bash # Run all tests pdm run test # Run tests in parallel pdm run test -n auto ``` Most of the time, you can exclude tests with "integration" mark to save runtime: ```bash pdm run test -n auto -m "not integration" ``` ### Code Quality ```bash # Run linting (ruff-format + codespell + mypy) pdm run lint ``` ### Documentation ```bash # Serve documentation locally pdm run doc ``` ### Contribution Guidelines Refer to [CONTRIBUTING.md](CONTRIBUTING.md) ## Important Files - `pyproject.toml`: Project configuration and dependencies - `src/pdm/core.py`: Main application entry point and command registration - `src/pdm/project/__init__.py`: Project class managing project state - `src/pdm/cli/commands/base.py`: Base command class for all CLI commands - `.pre-commit-config.yaml`: Code quality hooks (ruff, mypy, codespell) ## Common Development Tasks ### Adding a New Command 1. Create new file in `src/pdm/cli/commands/` 2. Inherit from `BaseCommand` 3. Register in `src/pdm/core.py` ### Debugging Resolution Issues - Set `PDM_DEBUG=1` environment variable for verbose output - Check `pdm.lock` for resolved versions - Use `pdm lock --check` to verify lock file ### Working with Lock Files PDM uses its own lock file format (`pdm.lock`) that includes: - Exact versions with hashes - Environment markers - Cross-platform support - Group dependencies ### Update dependencies ```bash # Add a new dependency to default group pdm add # Update all dependencies pdm update # Remove a dependency pdm remove # Add a new dependency to given group pdm add --group ``` ## Architecture Patterns - **Dependency Injection**: Core class passed to commands - **Signal System**: Event-driven architecture for plugins - **Repository Pattern**: Abstract repository interface for package sources - **Strategy Pattern**: Different environment backends (venv, conda, etc.) - **Chain of Responsibility**: Middleware system for HTTP client ================================================ FILE: CHANGELOG.md ================================================ ## Release v2.26.6 (2026-01-22) ### Bug Fixes - Support `packaging==26.0` changes for version comparison ([#3729](https://github.com/pdm-project/pdm/issues/3729)) ## Release v2.26.5 (2026-01-21) ### Bug Fixes - Respect the project path when using cookiecutter template in `pdm init` command. ([#3721](https://github.com/pdm-project/pdm/issues/3721)) - Fix a bug that `resolution.excludes` is not applied when evaluating candidates from the lock file. ([#3726](https://github.com/pdm-project/pdm/issues/3726)) ### Documentation - Remove chatbot from the docs page footer. ([#3722](https://github.com/pdm-project/pdm/issues/3722)) - Generate llms.txt for docs powered by `mkdocs-llmstxt`. ([#3723](https://github.com/pdm-project/pdm/issues/3723)) ## Release v2.26.4 (2026-01-09) ### Bug Fixes - Make sure cursor closing for fixing PyPy different gc mode also add PyPy in CI. ([#3708](https://github.com/pdm-project/pdm/issues/3708)) - Fix a bug that old HTTP cache directories cause PDM to crash when trying to clear them. ([#3715](https://github.com/pdm-project/pdm/issues/3715)) ## Release v2.26.3 (2025-12-24) ### Features & Improvements - Port to `hishel` 1.0.0. ([#3700](https://github.com/pdm-project/pdm/issues/3700)) ### Bug Fixes - Update `.gitignore` file in the default template. ([#3686](https://github.com/pdm-project/pdm/issues/3686)) - Correct the sysconfig variables for Python standalone build installations. ([#3693](https://github.com/pdm-project/pdm/issues/3693)) - Ignore `packages.vcs.requested-revision` if it's None when formatting pylock.toml. ([#3694](https://github.com/pdm-project/pdm/issues/3694)) - Fix test failures with uv test cases using non-venv Python interpreters. ([#3698](https://github.com/pdm-project/pdm/issues/3698)) ## Release v2.26.2 (2025-11-24) ### Features & Improvements - Only parse TOML document with `tomlkit` when writing is required. ([#3672](https://github.com/pdm-project/pdm/issues/3672)) - Add SHA256 checksums for binary releases during the release workflow and create an installer script that downloads binaries from GitHub releases with automatic platform detection and checksum verification. ([#3679](https://github.com/pdm-project/pdm/issues/3679)) ### Bug Fixes - Fix test_use_python_write_file_multiple_versions to match PDM's actual behavior. ([#3660](https://github.com/pdm-project/pdm/issues/3660)) - Correctly calculate the venv path for `UV_PROJECT_ENVIRONMENT` env var when using uv mode. ([#3675](https://github.com/pdm-project/pdm/issues/3675)) - Ensure `implementation.gil_disabled` is a boolean in `get_current_env_spec`. This fix an issue that free-threaded wheels get rejected incorrectly. ([#3677](https://github.com/pdm-project/pdm/issues/3677)) - Fix CLI help formatting on Python 3.14+. ([#3683](https://github.com/pdm-project/pdm/issues/3683)) - Make `PdmBasicAuth` a `cached_property` to accelerate execution. ([#3684](https://github.com/pdm-project/pdm/issues/3684)) ### Removals and Deprecations - Add deprecation warning for `pdm search` command as PyPI no longer supports search API. ([#3674](https://github.com/pdm-project/pdm/issues/3674)) ### Miscellany - Add tests to utils.fs_supports_link_method and utils.convert_to_datetime. ([#3541](https://github.com/pdm-project/pdm/issues/3541)) ## Release v2.26.1 (2025-10-29) ### Bug Fixes - Substitute missing env vars with empty string in `expand_env_vars`. ([#3653](https://github.com/pdm-project/pdm/issues/3653)) - Constrained hishel to be less than 1.0.0 due to its refactor ([#3657](https://github.com/pdm-project/pdm/issues/3657)) ## Release v2.26.0 (2025-10-11) ### Features & Improvements - Limit the log file size to 100MB and truncate the log output if exceeded. ([#3633](https://github.com/pdm-project/pdm/issues/3633)) - Speed up dependency resolution in the bad path by skipping candidates of the same version when resolving. ([#3647](https://github.com/pdm-project/pdm/issues/3647)) ### Bug Fixes - Reload project files after running hook scripts. ([#3615](https://github.com/pdm-project/pdm/issues/3615)) - Fix a bug when using UV as the resolver does not respect the venv.location configuration. ([#3616](https://github.com/pdm-project/pdm/issues/3616)) - Fix `publish --skip-existing` for Nexus Repository OSS >= 3.70 ([#3617](https://github.com/pdm-project/pdm/issues/3617)) - Fix a resolution failure when both prerelease and non-prerelease requirements exist. ([#3634](https://github.com/pdm-project/pdm/issues/3634)) - Ignore invalid `python` requirement during locking. ([#3635](https://github.com/pdm-project/pdm/issues/3635)) - Isolate PDM loggers with the root logger to avoid log leakage. ([#3637](https://github.com/pdm-project/pdm/issues/3637)) - Fix a crash when resolving URL dependencies under `use_uv=true`. ([#3640](https://github.com/pdm-project/pdm/issues/3640)) ## Release v2.25.9 (2025-08-22) No significant changes. ## Release v2.25.8 (2025-08-22) ### Bug Fixes - Fix a careless error by fast apply in AI coding. ([#3612](https://github.com/pdm-project/pdm/issues/3612)) ## Release v2.25.7 (2025-08-22) ### Features & Improvements - Show the path to site-packages in the output of `pdm info`. ([#3600](https://github.com/pdm-project/pdm/issues/3600)) ### Bug Fixes - Fix `uv python dir` path resolution on Windows ([#3603](https://github.com/pdm-project/pdm/issues/3603)) - Strip local version in version specifiers when writing package locks. ([#3605](https://github.com/pdm-project/pdm/issues/3605)) - Show an error message when 'default' is used in optional dependencies or dependency groups. ([#3609](https://github.com/pdm-project/pdm/issues/3609)) - Prevent hash clearing when appending to lockfile with env_spec. ([#3610](https://github.com/pdm-project/pdm/issues/3610)) ## Release v2.25.6 (2025-08-14) ### Features & Improvements - The `pdm python install -v` command now shows the download URL for the Python interpreter. ([#3552](https://github.com/pdm-project/pdm/issues/3552)) ### Bug Fixes - Ensure `make_array` always returns a tomlkit array type. ([#3586](https://github.com/pdm-project/pdm/issues/3586)) - Preserve multi-line help text in the CLI help output. ([#3587](https://github.com/pdm-project/pdm/issues/3587)) - Re-caculate artifact files and hashes when the lock target changes. ([#3595](https://github.com/pdm-project/pdm/issues/3595)) ### Dependencies - Require packaging>22.0 and remove conditional PACKAGING_22 version checks. ([#3601](https://github.com/pdm-project/pdm/issues/3601)) - Bump truststore to version 0.10.4. ([#3602](https://github.com/pdm-project/pdm/issues/3602)) ## Release v2.25.5 (2025-07-30) ### Features & Improvements - Tell the difference between free-threaded Python and normal ones. Users need to request for free-threaded versions explicitly by adding `t` to the version string, otherwise the normal build will be preferred. ([#3562](https://github.com/pdm-project/pdm/issues/3562)) ### Bug Fixes - Fix a bug that editable local package URLs are empty when using `pylock.toml`. ([#3565](https://github.com/pdm-project/pdm/issues/3565)) - Fix a bug where `pdm export` with `--lockfile pylock.toml` produced empty requirements.txt files due to missing group information extraction from pylock format markers. ([#3573](https://github.com/pdm-project/pdm/issues/3573)) - Read metadata from installed distribution when using reuse-installed strategy. ([#3579](https://github.com/pdm-project/pdm/issues/3579)) - Fix a lockfile writing error when locking git dependencies in the pylock.toml format. ([#3582](https://github.com/pdm-project/pdm/issues/3582)) ## Release v2.25.4 (2025-06-30) ### Bug Fixes - Add credentials when passing source urls to uv resolver. ([#3553](https://github.com/pdm-project/pdm/issues/3553)) - Redact credentials in source urls in the log output, and inject credentials into the source url for uv sync command as well. ([#3555](https://github.com/pdm-project/pdm/issues/3555)) - Fix a bug that extra dependencies of transitive dependencies are not properly installed when USE_UV=true ([#3558](https://github.com/pdm-project/pdm/issues/3558)) - Improve the terminal output when setting up a script environment. ([#3560](https://github.com/pdm-project/pdm/issues/3560)) - Skip non-existent library paths in post-install steps when trying to fix the pth files. ([#3561](https://github.com/pdm-project/pdm/issues/3561)) ### Dependencies - Update `resolvelib` to 1.2.0. ([#3557](https://github.com/pdm-project/pdm/issues/3557)) ## Release v2.25.3 (2025-06-22) ### Bug Fixes - Fix a bug that local file package metadata was missing when reading the lockfile. ([#3545](https://github.com/pdm-project/pdm/issues/3545)) - Extract `dependency-groups` and `extras` markers from `marker` value when parsing pylock.toml. ([#3550](https://github.com/pdm-project/pdm/issues/3550)) ## Release v2.25.2 (2025-06-16) No significant changes. ## Release v2.25.1 (2025-06-14) ### Bug Fixes - Fix duplicated dependencies added to the lock file when the same dependency with extras is requested. ([#3542](https://github.com/pdm-project/pdm/issues/3542)) - Stabilize order of the `extras` and `dependency-groups` fields in pylock output. ([#3543](https://github.com/pdm-project/pdm/issues/3543)) ## Release v2.25.0 (2025-06-13) ### Features & Improvements - Support pylock as alternative lock format and make it opt-in by config. ([#3481](https://github.com/pdm-project/pdm/issues/3481)) - Search for package metadata in lock file first when reuse strategy is used. ([#3522](https://github.com/pdm-project/pdm/issues/3522)) ### Bug Fixes - Fix Windows 11 install pdm error, which is because of msgpack install failure. ([#3485](https://github.com/pdm-project/pdm/issues/3485)) - Change the return type of `array_of_inline_tables` to list[dict] from list[str] ([#3523](https://github.com/pdm-project/pdm/issues/3523)) - Ensure uv resolver to include hash for package files. ([#3531](https://github.com/pdm-project/pdm/issues/3531)) - Avoid infinite recursion when reading pyproject.toml with circular file dependencies. ([#3539](https://github.com/pdm-project/pdm/issues/3539)) ## Release v2.24.2 (2025-05-23) ### Bug Fixes - Reinstalling local wheel if its checksum changes. ([#3503](https://github.com/pdm-project/pdm/issues/3503)) - Ignore HTTP cache entries if deserialization fails. ([#3515](https://github.com/pdm-project/pdm/issues/3515)) - Fetch missing URLs when `static_urls` is not enabled when running `pdm export -f pylock`. ([#3517](https://github.com/pdm-project/pdm/issues/3517)) - Missing self package when `--self` or `--editable-self` is passed to `pdm export -f pylock`. ([#3518](https://github.com/pdm-project/pdm/issues/3518)) ### Miscellany - Add Python 3.14 to the test matrix. ([#3506](https://github.com/pdm-project/pdm/issues/3506)) ## Release v2.24.1 (2025-04-23) ### Bug Fixes - Install the project when using the `BaseSynchronizer` with `install_self` set to `True`. This fixes the bug that when calling `pdm sync --quiet`, it skips installing the project itself. ([#3484](https://github.com/pdm-project/pdm/issues/3484)) - Mark one additional test as requiring network, and fix another one not to require it anymore. ([#3487](https://github.com/pdm-project/pdm/issues/3487)) ## Release v2.24.0 (2025-04-18) ### Features & Improvements - New command `pdm new` that behaves like `pdm init` but creates a new project. ([#3462](https://github.com/pdm-project/pdm/issues/3462)) - Support use `--name` as project name for command `pdm new` e.g. `pdm new hello --name world` ([#3476](https://github.com/pdm-project/pdm/issues/3476)) - Support exporting to pylock.toml format as described by PEP 751. ([#3480](https://github.com/pdm-project/pdm/issues/3480)) ### Bug Fixes - Pass the `--quiet` option to `pdm sync` command. ([#3401](https://github.com/pdm-project/pdm/issues/3401)) - If a `.python-version` file is found and it contains multiple lines, the file will be ignored. The usage of the `.python-version` file can be disabled, if configuration value `python.use_python_version` (or environment variable `PDM_USE_PYTHON_VERSION`) is `False`. ([#3417](https://github.com/pdm-project/pdm/issues/3417)) - fix `pdm config -e` command to open read-only file under linux ([#3423](https://github.com/pdm-project/pdm/issues/3423)) - Replace project names and import names in both `README.md` and `pyproject.toml` when running `pdm init