From 381f0bffad9120302c35b49b7289134b153fdabd Mon Sep 17 00:00:00 2001 From: Ethan Koenig Date: Sun, 13 Oct 2024 22:07:40 -0700 Subject: [PATCH 1/2] Cache `Path.is_dir` calls Profiles of a `poetry lock --no-update` command are showing that this `Path.is_dir` call is both a hotspot (~0.8s out of a ~4.8s), and is regularly called with the same path multiple times (~1260 calls with ~440 unique paths): https://github.com/python-poetry/poetry-core/blob/1bdbd900c4fc1e2d4ed1ef15dfbcafdcb66dd892/src/poetry/core/packages/dependency.py#L364 Caching `Path.is_dir` trims roughly ~0.5s off of the time spent in `Path.is_dir` calls. --- src/poetry/core/packages/dependency.py | 3 ++- src/poetry/core/packages/utils/utils.py | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/poetry/core/packages/dependency.py b/src/poetry/core/packages/dependency.py index bbf8d5290..1ba279bab 100644 --- a/src/poetry/core/packages/dependency.py +++ b/src/poetry/core/packages/dependency.py @@ -330,6 +330,7 @@ def create_from_pep_508( """ from poetry.core.packages.url_dependency import URLDependency from poetry.core.packages.utils.link import Link + from poetry.core.packages.utils.utils import cached_is_dir from poetry.core.packages.utils.utils import is_archive_file from poetry.core.packages.utils.utils import is_python_project from poetry.core.packages.utils.utils import is_url @@ -361,7 +362,7 @@ def create_from_pep_508( else: path_str = os.path.normpath(os.path.abspath(name)) # noqa: PTH100 p, extras = strip_extras(path_str) - if p.is_dir() and (os.path.sep in name or name.startswith(".")): + if cached_is_dir(p) and (os.path.sep in name or name.startswith(".")): if not is_python_project(Path(name)): raise ValueError( f"Directory {name!r} is not installable. Not a Python project." diff --git a/src/poetry/core/packages/utils/utils.py b/src/poetry/core/packages/utils/utils.py index 271e1e2d8..c3bfa979f 100644 --- a/src/poetry/core/packages/utils/utils.py +++ b/src/poetry/core/packages/utils/utils.py @@ -116,11 +116,16 @@ def strip_extras(path: str) -> tuple[Path, str | None]: return Path(path_no_extras), extras +@functools.lru_cache(maxsize=None) +def cached_is_dir(path: Path) -> bool: + """A cached version of `Path.is_dir`.""" + return path.is_dir() + @functools.lru_cache(maxsize=None) def is_python_project(path: Path) -> bool: """Return true if the directory is a Python project""" - if not path.is_dir(): + if not cached_is_dir(path): return False setup_py = path / "setup.py" From 16643fc455869651bf1322b22f5277adbc5ec785 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 05:25:10 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/poetry/core/packages/utils/utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/poetry/core/packages/utils/utils.py b/src/poetry/core/packages/utils/utils.py index c3bfa979f..ca0456094 100644 --- a/src/poetry/core/packages/utils/utils.py +++ b/src/poetry/core/packages/utils/utils.py @@ -116,6 +116,7 @@ def strip_extras(path: str) -> tuple[Path, str | None]: return Path(path_no_extras), extras + @functools.lru_cache(maxsize=None) def cached_is_dir(path: Path) -> bool: """A cached version of `Path.is_dir`."""