Skip to content

Commit 5c69ece

Browse files
authored
Merge pull request pytest-dev#9532 from bluetech/getdir-cache
config: avoid stat storm in _getconftestmodules
2 parents a17e708 + aee04cd commit 5c69ece

File tree

1 file changed

+14
-4
lines changed

1 file changed

+14
-4
lines changed

src/_pytest/config/__init__.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,14 @@ def _prepareconfig(
330330
raise
331331

332332

333+
def _get_directory(path: Path) -> Path:
334+
"""Get the directory of a path - itself if already a directory."""
335+
if path.is_file():
336+
return path.parent
337+
else:
338+
return path
339+
340+
333341
@final
334342
class PytestPluginManager(PluginManager):
335343
"""A :py:class:`pluggy.PluginManager <pluggy.PluginManager>` with
@@ -357,6 +365,11 @@ def __init__(self) -> None:
357365
# If set, conftest loading is skipped.
358366
self._noconftest = False
359367

368+
# _getconftestmodules()'s call to _get_directory() causes a stat
369+
# storm when it's called potentially thousands of times in a test
370+
# session (#9478), often with the same path, so cache it.
371+
self._get_directory = lru_cache(256)(_get_directory)
372+
360373
self._duplicatepaths: Set[Path] = set()
361374

362375
# plugins that were explicitly skipped with pytest.skip
@@ -547,10 +560,7 @@ def _getconftestmodules(
547560
if self._noconftest:
548561
return []
549562

550-
if path.is_file():
551-
directory = path.parent
552-
else:
553-
directory = path
563+
directory = self._get_directory(path)
554564

555565
# Optimization: avoid repeated searches in the same directory.
556566
# Assumes always called with same importmode and rootpath.

0 commit comments

Comments
 (0)