Skip to content

move Bestrelpath cache move to session #4314

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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
16 changes: 16 additions & 0 deletions src/_pytest/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import pkgutil
import sys

import attr
import py
import six

Expand Down Expand Up @@ -369,6 +370,16 @@ class Failed(Exception):
""" signals a stop as failed test run. """


@attr.s
class _bestrelpath_cache(dict):
path = attr.ib()

def __missing__(self, path):
r = self.path.bestrelpath(path)
self[path] = r
return r


class Session(nodes.FSCollector):
Interrupted = Interrupted
Failed = Failed
Expand All @@ -387,9 +398,14 @@ def __init__(self, config):
self._initialpaths = frozenset()
# Keep track of any collected nodes in here, so we don't duplicate fixtures
self._node_cache = {}
self._bestrelpathcache = _bestrelpath_cache(config.rootdir)

self.config.pluginmanager.register(self, name="session")

def _node_location_to_relpath(self, node_path):
# bestrelpath is a quite slow function
return self._bestrelpathcache[node_path]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about using lru_cache here?
Or mark is as TODO, since py27 does not use it.
(we could also backport it for py27, of course, if we're starting to use it more/here)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lru cache has a significantly higher complexity - for a full cache (like this one) its overcill ^^
that being said - in a few iterations the cache will be gone for more effective ways


@hookimpl(tryfirst=True)
def pytest_collectstart(self):
if self.shouldfail:
Expand Down
8 changes: 1 addition & 7 deletions src/_pytest/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -523,13 +523,7 @@ def location(self):
return self._location
except AttributeError:
location = self.reportinfo()
# bestrelpath is a quite slow function
cache = self.config.__dict__.setdefault("_bestrelpathcache", {})
try:
fspath = cache[location[0]]
except KeyError:
fspath = self.session.fspath.bestrelpath(location[0])
cache[location[0]] = fspath
fspath = self.session._node_location_to_relpath(location[0])
location = (fspath, location[1], str(location[2]))
self._location = location
return location