Repository: pdm-project/pdm
Pull request #3216 (2024-10-17 10:25:15)

fix: self update using locked extra
Signed-off-by: Frost Ming <me@frostming.com>

## 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.


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/pdm-project/pdm/pull/3216?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pdm-project) Report
Attention: Patch coverage is `41.66667%` with `7 lines` in your changes missing coverage. Please review.
> Project coverage is 85.09%. Comparing base [(`e6e041e`)](https://app.codecov.io/gh/pdm-project/pdm/commit/e6e041ee0a4caf527bcec313244d83b665e49812?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pdm-project) to head [(`a2ed0d8`)](https://app.codecov.io/gh/pdm-project/pdm/commit/a2ed0d82d076e77f49e86587801df04a75d04757?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pdm-project).

| [Files with missing lines](https://app.codecov.io/gh/pdm-project/pdm/pull/3216?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pdm-project) | Patch % | Lines |
|---|---|---|
| [src/pdm/cli/commands/self\_cmd.py](https://app.codecov.io/gh/pdm-project/pdm/pull/3216?src=pr&el=tree&filepath=src%2Fpdm%2Fcli%2Fcommands%2Fself_cmd.py&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pdm-project#diff-c3JjL3BkbS9jbGkvY29tbWFuZHMvc2VsZl9jbWQucHk=) | 41.66% | [7 Missing :warning: ](https://app.codecov.io/gh/pdm-project/pdm/pull/3216?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pdm-project) |

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #3216      +/-   ##
==========================================
- Coverage   85.61%   85.09%   -0.53%     
==========================================
  Files         112      112              
  Lines       11251    11257       +6     
  Branches     2440     2442       +2     
==========================================
- Hits         9633     9579      -54     
- Misses       1101     1152      +51     
- Partials      517      526       +9     
```

| [Flag](https://app.codecov.io/gh/pdm-project/pdm/pull/3216/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pdm-project) | Coverage Δ | |
|---|---|---|
| [unittests](https://app.codecov.io/gh/pdm-project/pdm/pull/3216/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pdm-project) | `84.97% <41.66%> (-0.45%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pdm-project#carryforward-flags-in-the-pull-request-comment) to find out more.

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/pdm-project/pdm/pull/3216?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pdm-project).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pdm-project).


Patch:
diff --git a/news/3216.bugfix.md b/news/3216.bugfix.md
new file mode 100644
index 00000000..eb825d34
--- /dev/null
+++ b/news/3216.bugfix.md
@@ -0,0 +1,1 @@
+`pdm self update` now prefers the locked dependencies unless `--no-frozen-deps` is specified.
diff --git a/src/pdm/cli/commands/self_cmd.py b/src/pdm/cli/commands/self_cmd.py
index 1d167820..e9fbe659 100644
--- a/src/pdm/cli/commands/self_cmd.py
+++ b/src/pdm/cli/commands/self_cmd.py
@@ -31,9 +31,15 @@ def list_distributions(plugin_only: bool = False) -> list[Distribution]:
 
 
 def run_pip(project: Project, args: list[str]) -> subprocess.CompletedProcess[str]:
-    env = BareEnvironment(project)
-    project.environment = env
-    run_args = env.pip_command + args
+    if project.config["use_uv"]:
+        if "--upgrade-strategy" in args:
+            # uv doesn't support this option
+            args[(i := args.index("--upgrade-strategy")) : i + 2] = []
+        run_args = [*project.core.uv_cmd, "pip", *args, "--python", sys.executable]
+    else:
+        env = BareEnvironment(project)
+        project.environment = env
+        run_args = [*env.pip_command, *args]
     project.core.ui.echo(f"Running pip command: {run_args}", verbosity=termui.Verbosity.DETAIL)
 
     result = subprocess.run(
@@ -216,6 +222,13 @@ class UpdateCommand(BaseCommand):
             help="Update to the latest prerelease version",
             action="store_true",
         )
+        parser.add_argument(
+            "--no-frozen-deps",
+            action="store_false",
+            dest="frozen_deps",
+            default=True,
+            help="Do not install frozen dependency versions",
+        )
         parser.add_argument(
             "--pip-args",
             help="Additional arguments that will be passed to pip install",
@@ -225,8 +238,10 @@ class UpdateCommand(BaseCommand):
     def handle(self, project: Project, options: argparse.Namespace) -> None:
         from pdm.__version__ import __version__, read_version
 
+        locked = "[locked]" if options.frozen_deps else ""
+
         if options.head:
-            package = f"pdm @ git+{PDM_REPO}@main"
+            package = f"pdm{locked} @ git+{PDM_REPO}@main"
             version: str | None = "HEAD"
         else:
             version = get_latest_pdm_version_from_pypi(project, options.pre)
@@ -234,8 +249,8 @@ class UpdateCommand(BaseCommand):
             if parse_version(__version__) >= parse_version(version):
                 project.core.ui.echo(f"Already up-to-date: [primary]{__version__}[/]")
                 return
-            package = f"pdm=={version}"
-        pip_args = ["install", "--upgrade", *shlex.split(options.pip_args), package]
+            package = f"pdm{locked}=={version}"
+        pip_args = ["install", "--upgrade", "--upgrade-strategy", "eager", *shlex.split(options.pip_args), package]
         try:
             with project.core.ui.open_spinner(f"Updating pdm to version [primary]{version}[/]"):
                 run_pip(project, pip_args)


Test patch:
diff --git a/tests/cli/test_self_command.py b/tests/cli/test_self_command.py
index abe04eb8..272d4bc0 100644
--- a/tests/cli/test_self_command.py
+++ b/tests/cli/test_self_command.py
@@ -98,11 +98,11 @@ def test_self_remove(pdm, mock_pip, mocker, monkeypatch):
 @pytest.mark.parametrize(
     "args,expected",
     [
-        (["self", "update"], ["install", "--upgrade", "pdm==99.0.0"]),
-        (["self", "update", "--pre"], ["install", "--upgrade", "pdm==99.0.1b1"]),
+        (["self", "update"], ["install", "--upgrade", "--upgrade-strategy", "eager", "pdm[locked]==99.0.0"]),
+        (["self", "update", "--pre"], ["install", "--upgrade", "--upgrade-strategy", "eager", "pdm[locked]==99.0.1b1"]),
         (
             ["self", "update", "--head"],
-            ["install", "--upgrade", f"pdm @ git+{self_cmd.PDM_REPO}@main"],
+            ["install", "--upgrade", "--upgrade-strategy", "eager", f"pdm[locked] @ git+{self_cmd.PDM_REPO}@main"],
         ),
     ],
 )