diff --git a/src/_pytest/assertion/__init__.py b/src/_pytest/assertion/__init__.py index 29c25d035..480a26ad8 100644 --- a/src/_pytest/assertion/__init__.py +++ b/src/_pytest/assertion/__init__.py @@ -88,13 +88,13 @@ class AssertionState: def install_importhook(config: Config) -> rewrite.AssertionRewritingHook: """Try to install the rewrite hook, raise SystemError if it fails.""" - config._store[assertstate_key] = AssertionState(config, "rewrite") - config._store[assertstate_key].hook = hook = rewrite.AssertionRewritingHook(config) + config.stash[assertstate_key] = AssertionState(config, "rewrite") + config.stash[assertstate_key].hook = hook = rewrite.AssertionRewritingHook(config) sys.meta_path.insert(0, hook) - config._store[assertstate_key].trace("installed rewrite import hook") + config.stash[assertstate_key].trace("installed rewrite import hook") def undo() -> None: - hook = config._store[assertstate_key].hook + hook = config.stash[assertstate_key].hook if hook is not None and hook in sys.meta_path: sys.meta_path.remove(hook) @@ -106,7 +106,7 @@ def pytest_collection(session: "Session") -> None: # This hook is only called when test modules are collected # so for example not in the managing process of pytest-xdist # (which does not collect test modules). - assertstate = session.config._store.get(assertstate_key, None) + assertstate = session.config.stash.get(assertstate_key, None) if assertstate: if assertstate.hook is not None: assertstate.hook.set_session(session) @@ -169,7 +169,7 @@ def pytest_runtest_protocol(item: Item) -> Generator[None, None, None]: def pytest_sessionfinish(session: "Session") -> None: - assertstate = session.config._store.get(assertstate_key, None) + assertstate = session.config.stash.get(assertstate_key, None) if assertstate: if assertstate.hook is not None: assertstate.hook.set_session(None) diff --git a/src/_pytest/assertion/rewrite.py b/src/_pytest/assertion/rewrite.py index 3c8ffde4e..8c85240ef 100644 --- a/src/_pytest/assertion/rewrite.py +++ b/src/_pytest/assertion/rewrite.py @@ -87,7 +87,7 @@ class AssertionRewritingHook(importlib.abc.MetaPathFinder, importlib.abc.Loader) ) -> Optional[importlib.machinery.ModuleSpec]: if self._writing_pyc: return None - state = self.config._store[assertstate_key] + state = self.config.stash[assertstate_key] if self._early_rewrite_bailout(name, state): return None state.trace("find_module called for: %s" % name) @@ -131,7 +131,7 @@ class AssertionRewritingHook(importlib.abc.MetaPathFinder, importlib.abc.Loader) assert module.__spec__ is not None assert module.__spec__.origin is not None fn = Path(module.__spec__.origin) - state = self.config._store[assertstate_key] + state = self.config.stash[assertstate_key] self._rewritten_names.add(module.__name__) diff --git a/src/_pytest/faulthandler.py b/src/_pytest/faulthandler.py index fc2471f39..aaee307ff 100644 --- a/src/_pytest/faulthandler.py +++ b/src/_pytest/faulthandler.py @@ -27,9 +27,9 @@ def pytest_configure(config: Config) -> None: import faulthandler stderr_fd_copy = os.dup(get_stderr_fileno()) - config._store[fault_handler_stderr_key] = open(stderr_fd_copy, "w") - config._store[fault_handler_originally_enabled_key] = faulthandler.is_enabled() - faulthandler.enable(file=config._store[fault_handler_stderr_key]) + config.stash[fault_handler_stderr_key] = open(stderr_fd_copy, "w") + config.stash[fault_handler_originally_enabled_key] = faulthandler.is_enabled() + faulthandler.enable(file=config.stash[fault_handler_stderr_key]) def pytest_unconfigure(config: Config) -> None: @@ -37,10 +37,10 @@ def pytest_unconfigure(config: Config) -> None: faulthandler.disable() # Close the dup file installed during pytest_configure. - if fault_handler_stderr_key in config._store: - config._store[fault_handler_stderr_key].close() - del config._store[fault_handler_stderr_key] - if config._store.get(fault_handler_originally_enabled_key, False): + if fault_handler_stderr_key in config.stash: + config.stash[fault_handler_stderr_key].close() + del config.stash[fault_handler_stderr_key] + if config.stash.get(fault_handler_originally_enabled_key, False): # Re-enable the faulthandler if it was originally enabled. faulthandler.enable(file=get_stderr_fileno()) @@ -67,7 +67,7 @@ def get_timeout_config_value(config: Config) -> float: @pytest.hookimpl(hookwrapper=True, trylast=True) def pytest_runtest_protocol(item: Item) -> Generator[None, None, None]: timeout = get_timeout_config_value(item.config) - stderr = item.config._store[fault_handler_stderr_key] + stderr = item.config.stash[fault_handler_stderr_key] if timeout > 0 and stderr is not None: import faulthandler diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index 305ec0348..347d49003 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -199,7 +199,7 @@ def add_funcarg_pseudo_fixture_def( name2pseudofixturedef = None else: default: Dict[str, FixtureDef[Any]] = {} - name2pseudofixturedef = node._store.setdefault( + name2pseudofixturedef = node.stash.setdefault( name2pseudofixturedef_key, default ) if name2pseudofixturedef is not None and argname in name2pseudofixturedef: diff --git a/src/_pytest/junitxml.py b/src/_pytest/junitxml.py index d7b00cca1..6d13e89a4 100644 --- a/src/_pytest/junitxml.py +++ b/src/_pytest/junitxml.py @@ -267,7 +267,7 @@ def _warn_incompatibility_with_xunit2( """Emit a PytestWarning about the given fixture being incompatible with newer xunit revisions.""" from _pytest.warning_types import PytestWarning - xml = request.config._store.get(xml_key, None) + xml = request.config.stash.get(xml_key, None) if xml is not None and xml.family not in ("xunit1", "legacy"): request.node.warn( PytestWarning( @@ -322,7 +322,7 @@ def record_xml_attribute(request: FixtureRequest) -> Callable[[str, object], Non attr_func = add_attr_noop - xml = request.config._store.get(xml_key, None) + xml = request.config.stash.get(xml_key, None) if xml is not None: node_reporter = xml.node_reporter(request.node.nodeid) attr_func = node_reporter.add_attribute @@ -370,7 +370,7 @@ def record_testsuite_property(request: FixtureRequest) -> Callable[[str, object] __tracebackhide__ = True _check_record_param_type("name", name) - xml = request.config._store.get(xml_key, None) + xml = request.config.stash.get(xml_key, None) if xml is not None: record_func = xml.add_global_property # noqa return record_func @@ -428,7 +428,7 @@ def pytest_configure(config: Config) -> None: # Prevent opening xmllog on worker nodes (xdist). if xmlpath and not hasattr(config, "workerinput"): junit_family = config.getini("junit_family") - config._store[xml_key] = LogXML( + config.stash[xml_key] = LogXML( xmlpath, config.option.junitprefix, config.getini("junit_suite_name"), @@ -437,13 +437,13 @@ def pytest_configure(config: Config) -> None: junit_family, config.getini("junit_log_passing_tests"), ) - config.pluginmanager.register(config._store[xml_key]) + config.pluginmanager.register(config.stash[xml_key]) def pytest_unconfigure(config: Config) -> None: - xml = config._store.get(xml_key, None) + xml = config.stash.get(xml_key, None) if xml: - del config._store[xml_key] + del config.stash[xml_key] config.pluginmanager.unregister(xml) diff --git a/src/_pytest/logging.py b/src/_pytest/logging.py index 376a6b31f..7ed1820bb 100644 --- a/src/_pytest/logging.py +++ b/src/_pytest/logging.py @@ -372,7 +372,7 @@ class LogCaptureFixture: :rtype: LogCaptureHandler """ - return self._item._store[caplog_handler_key] + return self._item.stash[caplog_handler_key] def get_records(self, when: str) -> List[logging.LogRecord]: """Get the logging records for one of the possible test phases. @@ -385,7 +385,7 @@ class LogCaptureFixture: .. versionadded:: 3.4 """ - return self._item._store[caplog_records_key].get(when, []) + return self._item.stash[caplog_records_key].get(when, []) @property def text(self) -> str: @@ -694,8 +694,8 @@ class LoggingPlugin: ) as report_handler: caplog_handler.reset() report_handler.reset() - item._store[caplog_records_key][when] = caplog_handler.records - item._store[caplog_handler_key] = caplog_handler + item.stash[caplog_records_key][when] = caplog_handler.records + item.stash[caplog_handler_key] = caplog_handler yield @@ -707,7 +707,7 @@ class LoggingPlugin: self.log_cli_handler.set_when("setup") empty: Dict[str, List[logging.LogRecord]] = {} - item._store[caplog_records_key] = empty + item.stash[caplog_records_key] = empty yield from self._runtest_for(item, "setup") @hookimpl(hookwrapper=True) @@ -721,8 +721,8 @@ class LoggingPlugin: self.log_cli_handler.set_when("teardown") yield from self._runtest_for(item, "teardown") - del item._store[caplog_records_key] - del item._store[caplog_handler_key] + del item.stash[caplog_records_key] + del item.stash[caplog_handler_key] @hookimpl def pytest_runtest_logfinish(self) -> None: diff --git a/src/_pytest/mark/__init__.py b/src/_pytest/mark/__init__.py index 877b5ef1c..05dd1cdc1 100644 --- a/src/_pytest/mark/__init__.py +++ b/src/_pytest/mark/__init__.py @@ -269,7 +269,7 @@ def pytest_collection_modifyitems(items: "List[Item]", config: Config) -> None: def pytest_configure(config: Config) -> None: - config._store[old_mark_config_key] = MARK_GEN._config + config.stash[old_mark_config_key] = MARK_GEN._config MARK_GEN._config = config empty_parameterset = config.getini(EMPTY_PARAMETERSET_OPTION) @@ -282,4 +282,4 @@ def pytest_configure(config: Config) -> None: def pytest_unconfigure(config: Config) -> None: - MARK_GEN._config = config._store.get(old_mark_config_key, None) + MARK_GEN._config = config.stash.get(old_mark_config_key, None) diff --git a/src/_pytest/pastebin.py b/src/_pytest/pastebin.py index 1ca7cc494..b33383504 100644 --- a/src/_pytest/pastebin.py +++ b/src/_pytest/pastebin.py @@ -37,26 +37,26 @@ def pytest_configure(config: Config) -> None: # when using pytest-xdist, for example. if tr is not None: # pastebin file will be UTF-8 encoded binary file. - config._store[pastebinfile_key] = tempfile.TemporaryFile("w+b") + config.stash[pastebinfile_key] = tempfile.TemporaryFile("w+b") oldwrite = tr._tw.write def tee_write(s, **kwargs): oldwrite(s, **kwargs) if isinstance(s, str): s = s.encode("utf-8") - config._store[pastebinfile_key].write(s) + config.stash[pastebinfile_key].write(s) tr._tw.write = tee_write def pytest_unconfigure(config: Config) -> None: - if pastebinfile_key in config._store: - pastebinfile = config._store[pastebinfile_key] + if pastebinfile_key in config.stash: + pastebinfile = config.stash[pastebinfile_key] # Get terminal contents and delete file. pastebinfile.seek(0) sessionlog = pastebinfile.read() pastebinfile.close() - del config._store[pastebinfile_key] + del config.stash[pastebinfile_key] # Undo our patching in the terminal reporter. tr = config.pluginmanager.getplugin("terminalreporter") del tr._tw.__dict__["write"] diff --git a/src/_pytest/skipping.py b/src/_pytest/skipping.py index 18f9a49bc..f18716b14 100644 --- a/src/_pytest/skipping.py +++ b/src/_pytest/skipping.py @@ -237,16 +237,16 @@ def pytest_runtest_setup(item: Item) -> None: if skipped: raise skip.Exception(skipped.reason, _use_item_location=True) - item._store[xfailed_key] = xfailed = evaluate_xfail_marks(item) + item.stash[xfailed_key] = xfailed = evaluate_xfail_marks(item) if xfailed and not item.config.option.runxfail and not xfailed.run: xfail("[NOTRUN] " + xfailed.reason) @hookimpl(hookwrapper=True) def pytest_runtest_call(item: Item) -> Generator[None, None, None]: - xfailed = item._store.get(xfailed_key, None) + xfailed = item.stash.get(xfailed_key, None) if xfailed is None: - item._store[xfailed_key] = xfailed = evaluate_xfail_marks(item) + item.stash[xfailed_key] = xfailed = evaluate_xfail_marks(item) if xfailed and not item.config.option.runxfail and not xfailed.run: xfail("[NOTRUN] " + xfailed.reason) @@ -254,16 +254,16 @@ def pytest_runtest_call(item: Item) -> Generator[None, None, None]: yield # The test run may have added an xfail mark dynamically. - xfailed = item._store.get(xfailed_key, None) + xfailed = item.stash.get(xfailed_key, None) if xfailed is None: - item._store[xfailed_key] = xfailed = evaluate_xfail_marks(item) + item.stash[xfailed_key] = xfailed = evaluate_xfail_marks(item) @hookimpl(hookwrapper=True) def pytest_runtest_makereport(item: Item, call: CallInfo[None]): outcome = yield rep = outcome.get_result() - xfailed = item._store.get(xfailed_key, None) + xfailed = item.stash.get(xfailed_key, None) if item.config.option.runxfail: pass # don't interfere elif call.excinfo and isinstance(call.excinfo.value, xfail.Exception): diff --git a/testing/logging/test_fixture.py b/testing/logging/test_fixture.py index f82df1971..bcb20de58 100644 --- a/testing/logging/test_fixture.py +++ b/testing/logging/test_fixture.py @@ -169,7 +169,7 @@ def test_caplog_captures_for_all_stages(caplog, logging_during_setup_and_teardow assert [x.message for x in caplog.get_records("setup")] == ["a_setup_log"] # This reaches into private API, don't use this type of thing in real tests! - assert set(caplog._item._store[caplog_records_key]) == {"setup", "call"} + assert set(caplog._item.stash[caplog_records_key]) == {"setup", "call"} def test_ini_controls_global_log_level(pytester: Pytester) -> None: diff --git a/testing/test_junitxml.py b/testing/test_junitxml.py index 0ded0685a..edd1dfde6 100644 --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -951,7 +951,7 @@ def test_dont_configure_on_workers(tmp_path: Path) -> None: def __init__(self): self.pluginmanager = self self.option = self - self._store = Stash() + self.stash = Stash() def getini(self, name): return "pytest"