Skip to content

Commit 1df593f

Browse files
authored
Merge pull request #6865 from bluetech/more-config-store
Convert a couple of places to use config store
2 parents fcd3fad + f011bc6 commit 1df593f

File tree

5 files changed

+47
-13
lines changed

5 files changed

+47
-13
lines changed

src/_pytest/assertion/__init__.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from _pytest.assertion import rewrite
88
from _pytest.assertion import truncate
99
from _pytest.assertion import util
10+
from _pytest.assertion.rewrite import assertstate_key
1011
from _pytest.compat import TYPE_CHECKING
1112
from _pytest.config import hookimpl
1213

@@ -82,13 +83,13 @@ def __init__(self, config, mode):
8283

8384
def install_importhook(config):
8485
"""Try to install the rewrite hook, raise SystemError if it fails."""
85-
config._assertstate = AssertionState(config, "rewrite")
86-
config._assertstate.hook = hook = rewrite.AssertionRewritingHook(config)
86+
config._store[assertstate_key] = AssertionState(config, "rewrite")
87+
config._store[assertstate_key].hook = hook = rewrite.AssertionRewritingHook(config)
8788
sys.meta_path.insert(0, hook)
88-
config._assertstate.trace("installed rewrite import hook")
89+
config._store[assertstate_key].trace("installed rewrite import hook")
8990

9091
def undo():
91-
hook = config._assertstate.hook
92+
hook = config._store[assertstate_key].hook
9293
if hook is not None and hook in sys.meta_path:
9394
sys.meta_path.remove(hook)
9495

@@ -100,7 +101,7 @@ def pytest_collection(session: "Session") -> None:
100101
# this hook is only called when test modules are collected
101102
# so for example not in the master process of pytest-xdist
102103
# (which does not collect test modules)
103-
assertstate = getattr(session.config, "_assertstate", None)
104+
assertstate = session.config._store.get(assertstate_key, None)
104105
if assertstate:
105106
if assertstate.hook is not None:
106107
assertstate.hook.set_session(session)
@@ -163,7 +164,7 @@ def call_assertion_pass_hook(lineno, orig, expl):
163164

164165

165166
def pytest_sessionfinish(session):
166-
assertstate = getattr(session.config, "_assertstate", None)
167+
assertstate = session.config._store.get(assertstate_key, None)
167168
if assertstate:
168169
if assertstate.hook is not None:
169170
assertstate.hook.set_session(None)

src/_pytest/assertion/rewrite.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,18 @@
2626
format_explanation as _format_explanation,
2727
)
2828
from _pytest.compat import fspath
29+
from _pytest.compat import TYPE_CHECKING
2930
from _pytest.pathlib import fnmatch_ex
3031
from _pytest.pathlib import Path
3132
from _pytest.pathlib import PurePath
33+
from _pytest.store import StoreKey
34+
35+
if TYPE_CHECKING:
36+
from _pytest.assertion import AssertionState # noqa: F401
37+
38+
39+
assertstate_key = StoreKey["AssertionState"]()
40+
3241

3342
# pytest caches rewritten pycs in pycache dirs
3443
PYTEST_TAG = "{}-pytest-{}".format(sys.implementation.cache_tag, version)
@@ -65,7 +74,7 @@ def set_session(self, session):
6574
def find_spec(self, name, path=None, target=None):
6675
if self._writing_pyc:
6776
return None
68-
state = self.config._assertstate
77+
state = self.config._store[assertstate_key]
6978
if self._early_rewrite_bailout(name, state):
7079
return None
7180
state.trace("find_module called for: %s" % name)
@@ -104,7 +113,7 @@ def create_module(self, spec):
104113

105114
def exec_module(self, module):
106115
fn = Path(module.__spec__.origin)
107-
state = self.config._assertstate
116+
state = self.config._store[assertstate_key]
108117

109118
self._rewritten_names.add(module.__name__)
110119

src/_pytest/mark/evaluate.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,28 @@
22
import platform
33
import sys
44
import traceback
5+
from typing import Any
6+
from typing import Dict
57

68
from ..outcomes import fail
79
from ..outcomes import TEST_OUTCOME
10+
from _pytest.config import Config
11+
from _pytest.store import StoreKey
812

913

10-
def cached_eval(config, expr, d):
11-
if not hasattr(config, "_evalcache"):
12-
config._evalcache = {}
14+
evalcache_key = StoreKey[Dict[str, Any]]()
15+
16+
17+
def cached_eval(config: Config, expr: str, d: Dict[str, object]) -> Any:
18+
default = {} # type: Dict[str, object]
19+
evalcache = config._store.setdefault(evalcache_key, default)
1320
try:
14-
return config._evalcache[expr]
21+
return evalcache[expr]
1522
except KeyError:
1623
import _pytest._code
1724

1825
exprcode = _pytest._code.compile(expr, mode="eval")
19-
config._evalcache[expr] = x = eval(exprcode, d)
26+
evalcache[expr] = x = eval(exprcode, d)
2027
return x
2128

2229

src/_pytest/store.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,15 @@ def get(self, key: StoreKey[T], default: D) -> Union[T, D]:
104104
except KeyError:
105105
return default
106106

107+
def setdefault(self, key: StoreKey[T], default: T) -> T:
108+
"""Return the value of key if already set, otherwise set the value
109+
of key to default and return default."""
110+
try:
111+
return self[key]
112+
except KeyError:
113+
self[key] = default
114+
return default
115+
107116
def __delitem__(self, key: StoreKey[T]) -> None:
108117
"""Delete the value for key.
109118

testing/test_store.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@ def test_store() -> None:
3737
with pytest.raises(KeyError):
3838
store[key1]
3939

40+
# setdefault
41+
store[key1] = "existing"
42+
assert store.setdefault(key1, "default") == "existing"
43+
assert store[key1] == "existing"
44+
key_setdefault = StoreKey[bytes]()
45+
assert store.setdefault(key_setdefault, b"default") == b"default"
46+
assert store[key_setdefault] == b"default"
47+
4048
# Can't accidentally add attributes to store object itself.
4149
with pytest.raises(AttributeError):
4250
store.foo = "nope" # type: ignore[attr-defined] # noqa: F821

0 commit comments

Comments
 (0)