pdm-project / pdm

A modern Python package and dependency manager supporting the latest PEP standards
https://pdm-project.org
MIT License
7.02k stars 352 forks source link

Inconsistent behaviour of `pdm add` in mode direct_minimal_versions #2853

Closed jxrossel closed 1 month ago

jxrossel commented 1 month ago

Steps to reproduce

  1. Create an empty project, with no dependencies
  2. run pdm lock --strategy direct_minimal_versions to activate the locking strategy
  3. run pdm add django. This will modify the pyproject file to install the latest compatible django package (-> django>=4.2.11 for python 3.9)
  4. run again pdm add django. The pyproject file will now be modified to install the earliest compatible django package (-> django>=1.1.3)

Expected behavior

Environment Information

# Paste the output of `pdm info && pdm info --env` below:
PDM version:
  2.15.1
Python Interpreter:
  D:\tmp\test_pdm\.venv\Scripts\python.exe (3.9)
Project Root:
  D:/tmp/test_pdm
Local Packages:

{
  "implementation_name": "cpython",
  "implementation_version": "3.9.13",
  "os_name": "nt",
  "platform_machine": "AMD64",
  "platform_release": "10",
  "platform_system": "Windows",
  "platform_version": "10.0.19045",
  "python_full_version": "3.9.13",
  "platform_python_implementation": "CPython",
  "python_version": "3.9",
  "sys_platform": "win32"
}

Discussion

Thanks for the awesome work done on PDM!

frostming commented 1 month ago

IMHO, the latest version should be sought, even in direct_minimal_versions strategy, since that strategy specifies how the lock file consistency with the pyproject file is enforced, not how the pyproject file is specified

I think, on the contrary, the lowest version should be locked.

  • Another issue is what pdm add should do with respect to what is already specified in the pyproject file.

It means to "overwrite" what is stored in the pyproject.toml

  • When reading the documentation, it is not obvious how to reliably increase the lower bounds of the dependencies specified in the pyproject file with PDM.

pdm update --unconstrained for this. It is to "ignore" the version ranges in the pyproject.toml temporarily and update the pinned version, then recalculate the version ranges based on the save strategy and write it back to pyproject.toml

jxrossel commented 1 month ago

Hi @frostming ,

Thanks for having speedily fixed this and taken the time to answer my comments!

Regarding your "lowest version" policy for pdm add <new> under the direct_minimal_versions strategy, I might be using PDM wrong but it looks like it will make it harder to use. We use direct_minimal_versions to ensure that the lower version bounds in pyproject.toml are tested, and therefore meaningful. When adding a new dependency in development, we do want to take the last stable version, since we will use the last features and documentation for new developments with that dependency. With this "lowest version" policy, I guess we will have to set the version we want explicitly with pdm add new_dep>=last_ver. Am I correct?

pawamoy commented 1 month ago

You should probably use two lock files, one with latest versions (the default one), one with lowest versions (only used in CI, or maybe also when running tests locally).

frostming commented 1 month ago

Yes, basically you add dependencies to the default lock file which prefers latest and run pdm lock -L pdm.min.lock -S direct_minimal_versions(The -S ... can be omitted for subsequent runs) to produce another lock with minimal versions.

jxrossel commented 1 month ago

Hi @pawamoy @frostming , thank you both for your feedback. I didn't think of using two lock files. I have to give it some thoughts.

Have a nice day!