Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,15 @@ base branch. A maintainer might ask you to ensure the branch is up-to-date prior
All pull requests, unless otherwise instructed, need to be first accepted into the `main` branch. Maintainers will
generally decide if any backports to other branches are required, and carry them out as needed.

#### Performance contributions

Performance contributions should result in a significant improvement when running a Poetry command.
Micro-optimizations that do not meet this criterion are only acceptable if they do not decrease code readability.

When making performance measurements, you can set the `POETRY_FORCE_HTTP_CACHE` environment variable
to force using the HTTP cache. This helps make performance measurements more consistent by reducing
variability from network requests.

### Issue triage

{{% note %}}
Expand Down
23 changes: 23 additions & 0 deletions src/poetry/utils/authenticator.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,25 @@
from pathlib import Path
from typing import TYPE_CHECKING
from typing import Any
from typing import Literal

import requests
import requests.adapters
import requests.auth
import requests.exceptions

from cachecontrol import CacheControlAdapter
from cachecontrol import CacheController
from cachecontrol.caches import SeparateBodyFileCache
from requests import PreparedRequest
from requests_toolbelt import user_agent

from poetry.__version__ import __version__
from poetry.config.config import Config
from poetry.console.exceptions import ConsoleMessage
from poetry.console.exceptions import PoetryRuntimeError
from poetry.exceptions import PoetryError
from poetry.utils.constants import FORCE_HTTP_CACHE
from poetry.utils.constants import REQUESTS_TIMEOUT
from poetry.utils.constants import RETRY_AFTER_HEADER
from poetry.utils.constants import STATUS_FORCELIST
Expand All @@ -34,11 +38,29 @@

if TYPE_CHECKING:
from cleo.io.io import IO
from urllib3 import HTTPResponse


logger = logging.getLogger(__name__)


class ForceCacheController(CacheController):
"""
A custom CacheController that forces the use of cached responses
if they are available, even if they are stale, and does not attempt
to revalidate them with the server.

This is useful for performance analyses
to rule out a source of uncertainty.
"""

def cached_request(self, request: PreparedRequest) -> HTTPResponse | Literal[False]:
resp = self._load_from_cache(request)
if not resp:
return False # genuinely not cached -> nothing we can do
return resp


@dataclasses.dataclass(frozen=True)
class RepositoryCertificateConfig:
cert: Path | None = dataclasses.field(default=None)
Expand Down Expand Up @@ -145,6 +167,7 @@ def create_session(self) -> requests.Session:
adapter = CacheControlAdapter(
cache=self._cache_control,
pool_maxsize=self._pool_size,
controller_class=ForceCacheController if FORCE_HTTP_CACHE else None,
)
session.mount("http://", adapter)
session.mount("https://", adapter)
Expand Down
4 changes: 4 additions & 0 deletions src/poetry/utils/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,7 @@

# Server response codes to retry requests on.
STATUS_FORCELIST = [429, 500, 501, 502, 503, 504]

# Force the use of cached http responses even if they are stale.
# This is useful for performance analyses to rule out a source of uncertainty.
FORCE_HTTP_CACHE = os.getenv("POETRY_FORCE_HTTP_CACHE", "").lower() in ("true", "1")
Loading