Skip to content

Commit

Permalink
Ensure Config.inifile is available during pytest_cmdline_main
Browse files Browse the repository at this point in the history
  • Loading branch information
nicoddemus committed Dec 8, 2021
1 parent 7ae23ff commit 9510bd7
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 20 deletions.
1 change: 1 addition & 0 deletions changelog/9396.bugfix.rst
@@ -0,0 +1 @@
Ensure :attr:`pytest.Config.inifile` is available during the :func:`pytest_cmdline_main <_pytest.hookspec.pytest_cmdline_main>` hook (regression during ``7.0.0rc1``).
47 changes: 27 additions & 20 deletions src/_pytest/legacypath.py
Expand Up @@ -400,27 +400,11 @@ def Node_fspath_set(self: Node, value: LEGACY_PATH) -> None:
self.path = Path(value)


@pytest.hookimpl
def pytest_configure(config: pytest.Config) -> None:
@pytest.hookimpl(tryfirst=True)
def pytest_load_initial_conftests(early_config: pytest.Config) -> None:
"""Monkeypatch legacy path attributes in several classes, as early as possible."""
mp = pytest.MonkeyPatch()
config.add_cleanup(mp.undo)

if config.pluginmanager.has_plugin("tmpdir"):
# Create TmpdirFactory and attach it to the config object.
#
# This is to comply with existing plugins which expect the handler to be
# available at pytest_configure time, but ideally should be moved entirely
# to the tmpdir_factory session fixture.
try:
tmp_path_factory = config._tmp_path_factory # type: ignore[attr-defined]
except AttributeError:
# tmpdir plugin is blocked.
pass
else:
_tmpdirhandler = TempdirFactory(tmp_path_factory, _ispytest=True)
mp.setattr(config, "_tmpdirhandler", _tmpdirhandler, raising=False)

config.pluginmanager.register(LegacyTmpdirPlugin, "legacypath-tmpdir")
early_config.add_cleanup(mp.undo)

# Add Cache.makedir().
mp.setattr(pytest.Cache, "makedir", Cache_makedir, raising=False)
Expand Down Expand Up @@ -452,6 +436,29 @@ def pytest_configure(config: pytest.Config) -> None:
mp.setattr(Node, "fspath", property(Node_fspath, Node_fspath_set), raising=False)


@pytest.hookimpl
def pytest_configure(config: pytest.Config) -> None:
"""Installs the LegacyTmpdirPlugin if the ``tmpdir`` plugin is also installed."""
if config.pluginmanager.has_plugin("tmpdir"):
mp = pytest.MonkeyPatch()
config.add_cleanup(mp.undo)
# Create TmpdirFactory and attach it to the config object.
#
# This is to comply with existing plugins which expect the handler to be
# available at pytest_configure time, but ideally should be moved entirely
# to the tmpdir_factory session fixture.
try:
tmp_path_factory = config._tmp_path_factory # type: ignore[attr-defined]
except AttributeError:
# tmpdir plugin is blocked.
pass
else:
_tmpdirhandler = TempdirFactory(tmp_path_factory, _ispytest=True)
mp.setattr(config, "_tmpdirhandler", _tmpdirhandler, raising=False)

config.pluginmanager.register(LegacyTmpdirPlugin, "legacypath-tmpdir")


@pytest.hookimpl
def pytest_plugin_registered(
plugin: object, manager: pytest.PytestPluginManager
Expand Down
1 change: 1 addition & 0 deletions testing/test_config.py
Expand Up @@ -1268,6 +1268,7 @@ def pytest_load_initial_conftests(self):
expected = [
"_pytest.config",
m.__module__,
"_pytest.legacypath",
"_pytest.pythonpath",
"_pytest.capture",
"_pytest.warnings",
Expand Down
17 changes: 17 additions & 0 deletions testing/test_legacypath.py
Expand Up @@ -161,3 +161,20 @@ def test_overriden(pytestconfig):
)
result = pytester.runpytest("--override-ini", "paths=foo/bar1.py foo/bar2.py", "-s")
result.stdout.fnmatch_lines(["user_path:bar1.py", "user_path:bar2.py"])


def test_inifile_from_cmdline_main_hook(pytester: pytest.Pytester) -> None:
"""Ensure Config.inifile is available during pytest_cmdline_main (#9396)."""
p = pytester.makeini(
"""
[pytest]
"""
)
pytester.makeconftest(
"""
def pytest_cmdline_main(config):
print("pytest_cmdline_main inifile =", config.inifile)
"""
)
result = pytester.runpytest_subprocess("-s")
result.stdout.fnmatch_lines(f"*pytest_cmdline_main inifile = {p}")

0 comments on commit 9510bd7

Please sign in to comment.