Merge pull request #6865 from bluetech/more-config-store
Convert a couple of places to use config store
This commit is contained in:
		
						commit
						1df593f978
					
				| 
						 | 
				
			
			@ -7,6 +7,7 @@ from typing import Optional
 | 
			
		|||
from _pytest.assertion import rewrite
 | 
			
		||||
from _pytest.assertion import truncate
 | 
			
		||||
from _pytest.assertion import util
 | 
			
		||||
from _pytest.assertion.rewrite import assertstate_key
 | 
			
		||||
from _pytest.compat import TYPE_CHECKING
 | 
			
		||||
from _pytest.config import hookimpl
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -82,13 +83,13 @@ class AssertionState:
 | 
			
		|||
 | 
			
		||||
def install_importhook(config):
 | 
			
		||||
    """Try to install the rewrite hook, raise SystemError if it fails."""
 | 
			
		||||
    config._assertstate = AssertionState(config, "rewrite")
 | 
			
		||||
    config._assertstate.hook = hook = rewrite.AssertionRewritingHook(config)
 | 
			
		||||
    config._store[assertstate_key] = AssertionState(config, "rewrite")
 | 
			
		||||
    config._store[assertstate_key].hook = hook = rewrite.AssertionRewritingHook(config)
 | 
			
		||||
    sys.meta_path.insert(0, hook)
 | 
			
		||||
    config._assertstate.trace("installed rewrite import hook")
 | 
			
		||||
    config._store[assertstate_key].trace("installed rewrite import hook")
 | 
			
		||||
 | 
			
		||||
    def undo():
 | 
			
		||||
        hook = config._assertstate.hook
 | 
			
		||||
        hook = config._store[assertstate_key].hook
 | 
			
		||||
        if hook is not None and hook in sys.meta_path:
 | 
			
		||||
            sys.meta_path.remove(hook)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -100,7 +101,7 @@ def pytest_collection(session: "Session") -> None:
 | 
			
		|||
    # this hook is only called when test modules are collected
 | 
			
		||||
    # so for example not in the master process of pytest-xdist
 | 
			
		||||
    # (which does not collect test modules)
 | 
			
		||||
    assertstate = getattr(session.config, "_assertstate", None)
 | 
			
		||||
    assertstate = session.config._store.get(assertstate_key, None)
 | 
			
		||||
    if assertstate:
 | 
			
		||||
        if assertstate.hook is not None:
 | 
			
		||||
            assertstate.hook.set_session(session)
 | 
			
		||||
| 
						 | 
				
			
			@ -163,7 +164,7 @@ def pytest_runtest_protocol(item):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
def pytest_sessionfinish(session):
 | 
			
		||||
    assertstate = getattr(session.config, "_assertstate", None)
 | 
			
		||||
    assertstate = session.config._store.get(assertstate_key, None)
 | 
			
		||||
    if assertstate:
 | 
			
		||||
        if assertstate.hook is not None:
 | 
			
		||||
            assertstate.hook.set_session(None)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,9 +26,18 @@ from _pytest.assertion.util import (  # noqa: F401
 | 
			
		|||
    format_explanation as _format_explanation,
 | 
			
		||||
)
 | 
			
		||||
from _pytest.compat import fspath
 | 
			
		||||
from _pytest.compat import TYPE_CHECKING
 | 
			
		||||
from _pytest.pathlib import fnmatch_ex
 | 
			
		||||
from _pytest.pathlib import Path
 | 
			
		||||
from _pytest.pathlib import PurePath
 | 
			
		||||
from _pytest.store import StoreKey
 | 
			
		||||
 | 
			
		||||
if TYPE_CHECKING:
 | 
			
		||||
    from _pytest.assertion import AssertionState  # noqa: F401
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
assertstate_key = StoreKey["AssertionState"]()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# pytest caches rewritten pycs in pycache dirs
 | 
			
		||||
PYTEST_TAG = "{}-pytest-{}".format(sys.implementation.cache_tag, version)
 | 
			
		||||
| 
						 | 
				
			
			@ -65,7 +74,7 @@ class AssertionRewritingHook(importlib.abc.MetaPathFinder, importlib.abc.Loader)
 | 
			
		|||
    def find_spec(self, name, path=None, target=None):
 | 
			
		||||
        if self._writing_pyc:
 | 
			
		||||
            return None
 | 
			
		||||
        state = self.config._assertstate
 | 
			
		||||
        state = self.config._store[assertstate_key]
 | 
			
		||||
        if self._early_rewrite_bailout(name, state):
 | 
			
		||||
            return None
 | 
			
		||||
        state.trace("find_module called for: %s" % name)
 | 
			
		||||
| 
						 | 
				
			
			@ -104,7 +113,7 @@ class AssertionRewritingHook(importlib.abc.MetaPathFinder, importlib.abc.Loader)
 | 
			
		|||
 | 
			
		||||
    def exec_module(self, module):
 | 
			
		||||
        fn = Path(module.__spec__.origin)
 | 
			
		||||
        state = self.config._assertstate
 | 
			
		||||
        state = self.config._store[assertstate_key]
 | 
			
		||||
 | 
			
		||||
        self._rewritten_names.add(module.__name__)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,21 +2,28 @@ import os
 | 
			
		|||
import platform
 | 
			
		||||
import sys
 | 
			
		||||
import traceback
 | 
			
		||||
from typing import Any
 | 
			
		||||
from typing import Dict
 | 
			
		||||
 | 
			
		||||
from ..outcomes import fail
 | 
			
		||||
from ..outcomes import TEST_OUTCOME
 | 
			
		||||
from _pytest.config import Config
 | 
			
		||||
from _pytest.store import StoreKey
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def cached_eval(config, expr, d):
 | 
			
		||||
    if not hasattr(config, "_evalcache"):
 | 
			
		||||
        config._evalcache = {}
 | 
			
		||||
evalcache_key = StoreKey[Dict[str, Any]]()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def cached_eval(config: Config, expr: str, d: Dict[str, object]) -> Any:
 | 
			
		||||
    default = {}  # type: Dict[str, object]
 | 
			
		||||
    evalcache = config._store.setdefault(evalcache_key, default)
 | 
			
		||||
    try:
 | 
			
		||||
        return config._evalcache[expr]
 | 
			
		||||
        return evalcache[expr]
 | 
			
		||||
    except KeyError:
 | 
			
		||||
        import _pytest._code
 | 
			
		||||
 | 
			
		||||
        exprcode = _pytest._code.compile(expr, mode="eval")
 | 
			
		||||
        config._evalcache[expr] = x = eval(exprcode, d)
 | 
			
		||||
        evalcache[expr] = x = eval(exprcode, d)
 | 
			
		||||
        return x
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -104,6 +104,15 @@ class Store:
 | 
			
		|||
        except KeyError:
 | 
			
		||||
            return default
 | 
			
		||||
 | 
			
		||||
    def setdefault(self, key: StoreKey[T], default: T) -> T:
 | 
			
		||||
        """Return the value of key if already set, otherwise set the value
 | 
			
		||||
        of key to default and return default."""
 | 
			
		||||
        try:
 | 
			
		||||
            return self[key]
 | 
			
		||||
        except KeyError:
 | 
			
		||||
            self[key] = default
 | 
			
		||||
            return default
 | 
			
		||||
 | 
			
		||||
    def __delitem__(self, key: StoreKey[T]) -> None:
 | 
			
		||||
        """Delete the value for key.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,6 +37,14 @@ def test_store() -> None:
 | 
			
		|||
    with pytest.raises(KeyError):
 | 
			
		||||
        store[key1]
 | 
			
		||||
 | 
			
		||||
    # setdefault
 | 
			
		||||
    store[key1] = "existing"
 | 
			
		||||
    assert store.setdefault(key1, "default") == "existing"
 | 
			
		||||
    assert store[key1] == "existing"
 | 
			
		||||
    key_setdefault = StoreKey[bytes]()
 | 
			
		||||
    assert store.setdefault(key_setdefault, b"default") == b"default"
 | 
			
		||||
    assert store[key_setdefault] == b"default"
 | 
			
		||||
 | 
			
		||||
    # Can't accidentally add attributes to store object itself.
 | 
			
		||||
    with pytest.raises(AttributeError):
 | 
			
		||||
        store.foo = "nope"  # type: ignore[attr-defined] # noqa: F821
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue