Skip to content

Commit

Permalink
fix: call funciton from dep-logic instead of implementing own (#3176)
Browse files Browse the repository at this point in the history
* fix: call funciton from dep-logic instead of implementing own

Signed-off-by: Frost Ming <me@frostming.com>

* fix: add news

Signed-off-by: Frost Ming <me@frostming.com>

* add news

Signed-off-by: Frost Ming <me@frostming.com>
  • Loading branch information
frostming authored Sep 23, 2024
1 parent cdb025c commit 1dc5f69
Show file tree
Hide file tree
Showing 9 changed files with 30 additions and 61 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,13 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: |
3.7
3.8
3.9
3.10
3.11
3.12
3.13
allow-prereleases: true
if: matrix.os != 'macos-latest'
- name: Setup Python Versions
uses: actions/setup-python@v5
Expand All @@ -77,6 +78,8 @@ jobs:
3.10
3.11
3.12
3.13
allow-prereleases: true
if: matrix.os == 'macos-latest'
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
Expand Down
12 changes: 8 additions & 4 deletions docs/usage/project.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ will be stored in `.pdm-python` and used by subsequent commands. You can also ch
Alternatively, you can specify the Python interpreter path via `PDM_PYTHON` environment variable. When it is set, the path saved in `.pdm-python` will be ignored.

!!! warning "Using an existing environment"
If you choose to use an existing environment, such as reusing an environment created by `conda`, please note that PDM will *remove* dependencies not listed in `pyproject.toml` or `pdm.lock` when running `pdm sync --clean` or `pdm remove`. This may lead to destructive consequences. Therefore, try not to share environment among multiple projects.
If you choose to use an existing environment, such as reusing an environment created by `conda`, please note that PDM will _remove_ dependencies not listed in `pyproject.toml` or `pdm.lock` when running `pdm sync --clean` or `pdm remove`. This may lead to destructive consequences. Therefore, try not to share environment among multiple projects.

### Install Python interpreters with PDM

Expand Down Expand Up @@ -99,7 +99,7 @@ In `pyproject.toml`, there is a field `distribution` under the `[tool.pdm]` tabl

## Specify `requires-python`

You need to set an appropriate `requires-python` value for your project. This is an important property that affects how dependencies are resolved. Basically, each package's `requires-python` must *cover* the project's `requires-python` range. For example, consider the following setup:
You need to set an appropriate `requires-python` value for your project. This is an important property that affects how dependencies are resolved. Basically, each package's `requires-python` must _cover_ the project's `requires-python` range. For example, consider the following setup:

- Project: `requires-python = ">=3.9"`
- Package `foo`: `requires-python = ">=3.7,<3.11"`
Expand All @@ -111,7 +111,7 @@ Unable to find a resolution because the following dependencies don't work
on all Python versions defined by the project's `requires-python`
```

Because the dependency's `requires-python` is `>=3.7,<3.11`, it *doesn't* cover the project's `requires-python` range of `>=3.9`. In other words, the project promises to work on Python 3.9, 3.10, 3.11 (and so on), but the dependency doesn't support Python 3.11 (or any higher). Since PDM creates a cross-platform lockfile that should work on all Python versions within the `requires-python` range, it can't find a valid resolution.
Because the dependency's `requires-python` is `>=3.7,<3.11`, it _doesn't_ cover the project's `requires-python` range of `>=3.9`. In other words, the project promises to work on Python 3.9, 3.10, 3.11 (and so on), but the dependency doesn't support Python 3.11 (or any higher). Since PDM creates a cross-platform lockfile that should work on all Python versions within the `requires-python` range, it can't find a valid resolution.
To fix this, you need add a maximum version to `requires-python`, like `>=3.9,<3.11`.

The value of `requires-python` is a [version specifier as defined in PEP 440](https://peps.python.org/pep-0440/#version-specifiers). Here are some examples:
Expand All @@ -124,6 +124,10 @@ The value of `requires-python` is a [version specifier as defined in PEP 440](ht

## Working with older Python versions

--- 2.19.0

PDM now supports 3.8 and above as the python version of projects.

Although PDM run on Python 3.8 and above, you can still have lower Python versions for your **working project**. But remember, if your project is a library, which needs to be built, published or installed, you make sure the PEP 517 build backend being used supports the lowest Python version you need. For instance, the default backend `pdm-backend` only works on Python 3.7+, so if you run [`pdm build`](../reference/cli.md#build) on a project with Python 3.6, you will get an error. Most modern build backends have dropped the support for Python 3.6 and lower, so it is highly recommended to upgrade the Python version to 3.7+. Here are the supported Python range for some commonly used build backends, we only list those that support PEP 621 since otherwise PDM can't work with them.

| Backend | Supported Python | Support PEP 621 |
Expand Down Expand Up @@ -151,7 +155,7 @@ PDM provides `import` command so that you don't have to initialize the project m
Also, when you are executing [`pdm init`](../reference/cli.md#init) or [`pdm install`](../reference/cli.md#install), PDM can auto-detect possible files to import if your PDM project has not been initialized yet.

!!! info
Converting a `setup.py` will execute the file with the project interpreter. Make sure `setuptools` is installed with the interpreter and the `setup.py` is trusted.
Converting a `setup.py` will execute the file with the project interpreter. Make sure `setuptools` is installed with the interpreter and the `setup.py` is trusted.

## Working with version control

Expand Down
1 change: 1 addition & 0 deletions news/3176.breaking.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The minimum supported Python version of projects using PDM has been bumped to 3.8.
1 change: 1 addition & 0 deletions news/3176.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Call functions from shared library in the in-process `env_spec.py` script.
6 changes: 3 additions & 3 deletions pdm.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion src/pdm/models/in_process/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import json
import os
import subprocess
import sysconfig
import tempfile
from typing import Any, Generator

Expand Down Expand Up @@ -47,5 +48,6 @@ def parse_setup_py(executable: str, path: str) -> dict[str, Any]:
@functools.lru_cache
def get_env_spec(executable: str) -> EnvSpec:
"""Get the environment spec of the python interpreter"""
shared_lib = sysconfig.get_path("purelib")
with _in_process_script("env_spec.py") as script:
return EnvSpec.from_spec(**json.loads(subprocess.check_output([executable, "-Es", script])))
return EnvSpec.from_spec(**json.loads(subprocess.check_output([executable, "-EsS", script, shared_lib])))
58 changes: 8 additions & 50 deletions src/pdm/models/in_process/env_spec.py
Original file line number Diff line number Diff line change
@@ -1,66 +1,24 @@
from __future__ import annotations

import json
import platform
import site
import sys
import sysconfig


class EnvError(Exception):
pass


def get_arch() -> str:
arch = platform.machine().lower()
if arch in ("i386", "i686"):
return "x86"
if arch == "amd64":
if platform.architecture()[0] == "32bit":
return "x86"
return "x86_64"
if arch == "arm64":
return "aarch64"
return arch


def get_platform() -> str:
"""Return the current platform."""

system = platform.system()
arch = get_arch()
if system == "Linux":
libc_ver = platform.libc_ver()[1]
if libc_ver:
parts = libc_ver.split(".")
return f"manylinux_{parts[0]}_{parts[1]}_{arch}"
else: # musl
# There is no easy way to retrieve the musl version, so we just assume it's 1.2
return f"musllinux_1_2_{arch}"
elif system == "Windows":
if arch == "aarch64":
return "windows_arm64"
if arch == "x86_64":
return "windows_amd64"
return f"windows_{arch}"
elif system == "Darwin":
mac_ver = platform.mac_ver()[0].split(".")
if arch == "aarch64":
arch = "arm64"
major, minor = int(mac_ver[0]), int(mac_ver[1])
if major >= 11:
minor = 0
return f"macos_{major}_{minor}_{arch}"
else:
raise EnvError("Unsupported platform")

def get_current_env_spec(shared_lib: str) -> dict[str, str | bool]:
site.addsitedir(shared_lib)
from dep_logic.tags import Platform

def get_current_env_spec():
python_version = f"{sys.version_info[0]}.{sys.version_info[1]}.{sys.version_info[2]}"
return {
"requires_python": f"=={python_version}",
"platform": get_platform(),
"platform": str(Platform.current()),
"implementation": platform.python_implementation().lower(),
"gil_disabled": sysconfig.get_config_var("Py_GIL_DISABLED") or False,
}


if __name__ == "__main__":
print(json.dumps(get_current_env_spec(), indent=2))
print(json.dumps(get_current_env_spec(sys.argv[1]), indent=2))
2 changes: 1 addition & 1 deletion tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from pdm.utils import cd

PYTHON_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
PYTHON_VERSIONS = ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
PYPROJECT = {
"project": {"name": "test-project", "version": "0.1.0", "requires-python": ">=3.7"},
"build-system": {"requires": ["pdm-backend"], "build-backend": "pdm.backend"},
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# https://pypi.org/project/tox-pdm/ is needed to run this tox configuration
[tox]
envlist = py3{8,9,10,11,12}
envlist = py3{8,9,10,11,12,13}
passenv = LD_PRELOAD
isolated_build = True

Expand Down

0 comments on commit 1dc5f69

Please sign in to comment.