Skip to content

Commit

Permalink
feat: reuse request sesison within the environment (pdm-project#2697)
Browse files Browse the repository at this point in the history
* feat: reuse request sesison within the environment

Signed-off-by: Frost Ming <[email protected]>

* add news

Signed-off-by: Frost Ming <[email protected]>
  • Loading branch information
frostming authored Mar 16, 2024
1 parent b4da6e0 commit 6823199
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 28 deletions.
1 change: 1 addition & 0 deletions news/2697.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Reuse the request sesison within the environment.
4 changes: 1 addition & 3 deletions src/pdm/cli/commands/publish/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import os
import pathlib
import weakref
from typing import TYPE_CHECKING, Any, Iterable
from urllib.parse import urlparse, urlunparse

Expand All @@ -29,7 +28,7 @@ def __init__(
verify_ssl: bool | None = True,
) -> None:
self.url = url
self.session = project.environment._build_session([])
self.session = project.environment.session
if verify_ssl is False:
self.session.verify = verify_ssl
elif ca_certs is not None:
Expand All @@ -38,7 +37,6 @@ def __init__(
self.ui = project.core.ui
username, password = self._ensure_credentials(username, password)
self.session.auth = (username, password)
weakref.finalize(self, self.session.close)

def _ensure_credentials(self, username: str | None, password: str | None) -> tuple[str, str]:
from pdm.models.auth import keyring
Expand Down
28 changes: 18 additions & 10 deletions src/pdm/environments/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
from contextlib import contextmanager
from functools import cached_property, partial
from pathlib import Path
from typing import TYPE_CHECKING, Generator, no_type_check
from threading import local
from typing import TYPE_CHECKING, Generator, cast, no_type_check

from pdm.exceptions import BuildError, PdmUsageError
from pdm.models.in_process import get_pep508_environment, get_python_abis, get_uname, sysconfig_get_platform
Expand Down Expand Up @@ -71,6 +72,8 @@ def __init__(self, project: Project, *, python: str | None = None) -> None:
else:
self._interpreter = PythonInfo.from_path(python)

self._local_cache = local()

@property
def is_global(self) -> bool:
"""For backward compatibility, it is opposite to ``is_local``."""
Expand Down Expand Up @@ -109,10 +112,11 @@ def target_python(self) -> unearth.TargetPython:
tp.supported_tags()
return tp

def _build_session(self, trusted_hosts: list[str]) -> PDMSession:
def _build_session(self) -> PDMSession:
from pdm.models.session import PDMSession

ca_certs = self.project.config.get("pypi.ca_certs")
trusted_hosts = get_trusted_hosts(self.project.sources)
session = PDMSession(
cache_dir=self.project.cache("http"),
trusted_hosts=trusted_hosts,
Expand All @@ -125,8 +129,18 @@ def _build_session(self, trusted_hosts: list[str]) -> PDMSession:
session.cert = (Path(certfn), Path(keyfn) if keyfn else None)

session.auth = self.auth
self.project.core.exit_stack.callback(session.close)
return session

@property
def session(self) -> PDMSession:
"""Build the session and cache it in the thread local storage."""
sess = getattr(self._local_cache, "session", None)
if sess is None:
sess = self._build_session()
self._local_cache.session = sess
return cast("PDMSession", sess)

@contextmanager
def _patch_target_python(self) -> Generator[None, None, None]:
"""Patch the packaging modules to respect the arch of target python."""
Expand Down Expand Up @@ -178,11 +192,8 @@ def get_finder(
f"{self.project.config['pypi.ignore_stored_index']}"
)

trusted_hosts = get_trusted_hosts(sources)

session = self._build_session(trusted_hosts)
finder = PDMPackageFinder(
session=session,
session=self.session,
target_python=self.target_python,
ignore_compatibility=ignore_compatibility,
no_binary=os.getenv("PDM_NO_BINARY", "").split(","),
Expand All @@ -201,10 +212,7 @@ def get_finder(
finder.add_find_links(source.url)
else:
finder.add_index_url(source.url)
try:
yield finder
finally:
session.close()
yield finder

def get_working_set(self) -> WorkingSet:
"""Get the working set based on local packages directory."""
Expand Down
14 changes: 4 additions & 10 deletions tests/models/test_candidates.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import pytest
from unearth import Link

from pdm._types import RepositoryConfig
from pdm.models.candidates import Candidate
from pdm.models.requirements import parse_requirement
from pdm.utils import is_path_relative_to, path_to_url
Expand Down Expand Up @@ -277,16 +276,11 @@ def test_ignore_invalid_py_version(project):


def test_find_candidates_from_find_links(project):
repo = project.get_repository()
repo.sources = [
RepositoryConfig(
name="test",
config_prefix="pypi",
url="http://fixtures.test/index/demo.html",
verify_ssl=False,
type="find_links",
)
project.pyproject.settings["source"] = [
{"name": "test", "url": "http://fixtures.test/index/demo.html", "verify_ssl": False, "type": "find_links"}
]
project.pyproject.write(False)
repo = project.get_repository()
candidates = list(repo.find_candidates(parse_requirement("demo")))
assert len(candidates) == 2

Expand Down
10 changes: 5 additions & 5 deletions tests/test_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,8 +397,8 @@ def test_preserve_log_file(project, pdm, tmp_path, mocker):
all_logs = list(tmp_path.joinpath("logs").iterdir())
assert len(all_logs) == 0

with mocker.patch.object(project.core.synchronizer_class, "synchronize", side_effect=Exception):
result = pdm(["add", "pytz"], obj=project)
assert result.exit_code != 0
install_log = next(tmp_path.joinpath("logs").glob("pdm-install-*.log"))
assert install_log.exists()
mocker.patch.object(project.core.synchronizer_class, "synchronize", side_effect=Exception)
result = pdm(["add", "pytz"], obj=project)
assert result.exit_code != 0
install_log = next(tmp_path.joinpath("logs").glob("pdm-install-*.log"))
assert install_log.exists()

0 comments on commit 6823199

Please sign in to comment.