From b43ebb7d657944fd9a04dbfa189c68bc5ab6c06f Mon Sep 17 00:00:00 2001 From: Alexey Zankevich Date: Thu, 1 Aug 2019 20:46:27 -0400 Subject: [PATCH] Cache split nodes results to reduce long tests collection time on large test suites --- changelog/5516.trivial.rst | 1 + src/_pytest/nodes.py | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 changelog/5516.trivial.rst diff --git a/changelog/5516.trivial.rst b/changelog/5516.trivial.rst new file mode 100644 index 000000000..2f6b4e35e --- /dev/null +++ b/changelog/5516.trivial.rst @@ -0,0 +1 @@ +Cache node splitting function which can improve collection performance in very large test suites. diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index 7e1c40bcb..9b78dca38 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -1,5 +1,6 @@ import os import warnings +from functools import lru_cache import py @@ -13,6 +14,7 @@ SEP = "/" tracebackcutdir = py.path.local(_pytest.__file__).dirpath() +@lru_cache(maxsize=None) def _splitnode(nodeid): """Split a nodeid into constituent 'parts'. @@ -30,11 +32,12 @@ def _splitnode(nodeid): """ if nodeid == "": # If there is no root node at all, return an empty list so the caller's logic can remain sane - return [] + return () parts = nodeid.split(SEP) # Replace single last element 'test_foo.py::Bar' with multiple elements 'test_foo.py', 'Bar' parts[-1:] = parts[-1].split("::") - return parts + # Convert parts into a tuple to avoid possible errors with caching of a mutable type + return tuple(parts) def ischildnode(baseid, nodeid):