chore: optimise unit tests (#2293)

* optimise unit tests - Cache loading the config TOML

Unit test time: 13.1s -> 10.5s

* optimise unit tests - use the same pyproject validator across the tests

Unit test time: 10.5s -> 5.7s

* optimise unit tests - selector optimisation

Unit test time: 5.7s -> 5.1s

* optimise unit tests - build options computation cache

Unit test time: 5.1s -> 3.2s

* Use functools.cache rather than functools.lru_cache

* Don't overwrite build_options when applying functools.cache
This commit is contained in:
Joe Rickerby
2025-03-10 21:29:07 +01:00
committed by GitHub
parent bddd438a88
commit c136aefe20
4 changed files with 38 additions and 31 deletions
+8 -2
View File
@@ -591,6 +591,10 @@ class Options:
except FileNotFoundError:
self.pyproject_toml = None
# cache the build options method so repeated calls don't need to
# resolve the options again
self.build_options = functools.cache(self._compute_build_options)
@functools.cached_property
def config_file_path(self) -> Path | None:
args = self.command_line_arguments
@@ -667,9 +671,11 @@ class Options:
allow_empty=allow_empty,
)
def build_options(self, identifier: str | None) -> BuildOptions:
def _compute_build_options(self, identifier: str | None) -> BuildOptions:
"""
Compute BuildOptions for a single run configuration.
Compute BuildOptions for a single run configuration. Normally accessed
through the `build_options` method, which is the same but the result
is cached.
"""
with self.reader.identifier(identifier):
+6 -9
View File
@@ -1,7 +1,7 @@
import fnmatch
import itertools
from dataclasses import dataclass
from enum import Enum
from fnmatch import fnmatch
from typing import Any
import bracex
@@ -18,9 +18,10 @@ def selector_matches(patterns: str, string: str) -> bool:
expansion. For example, 'cp{36,37}-*' would match either of 'cp36-*' or
'cp37-*'.
"""
patterns_list = patterns.split()
expanded_patterns = itertools.chain.from_iterable(bracex.expand(p) for p in patterns_list)
return any(fnmatch.fnmatch(string, pat) for pat in expanded_patterns)
return any(fnmatch(string, pat) for pat in expanded_patterns)
class EnableGroup(Enum):
@@ -59,15 +60,11 @@ class BuildSelector:
return False
# filter out groups that are not enabled
if EnableGroup.CPythonFreeThreading not in self.enable and selector_matches(
"cp3??t-*", build_id
):
if EnableGroup.CPythonFreeThreading not in self.enable and fnmatch(build_id, "cp3??t-*"):
return False
if EnableGroup.CPythonPrerelease not in self.enable and selector_matches(
"cp314*", build_id
):
if EnableGroup.CPythonPrerelease not in self.enable and fnmatch(build_id, "cp314*"):
return False
if EnableGroup.PyPy not in self.enable and selector_matches("pp*", build_id):
if EnableGroup.PyPy not in self.enable and fnmatch(build_id, "pp*"):
return False
should_build = selector_matches(self.build_config, build_id)
+3
View File
@@ -1,3 +1,4 @@
import functools
import tomllib
from pathlib import Path
from typing import Final
@@ -16,6 +17,8 @@ VIRTUALENV: Final[Path] = PATH / "virtualenv.toml"
CIBUILDWHEEL_SCHEMA: Final[Path] = PATH / "cibuildwheel.schema.json"
# this value is cached because it's used a lot in unit tests
@functools.cache
def read_python_configs(config: PlatformName) -> list[dict[str, str]]:
with BUILD_PLATFORMS.open("rb") as f:
loaded_file = tomllib.load(f)