Skip to content

Commit 0f5aa5a

Browse files
authored
Merge pull request #11825 from woutdenolf/fix_missing_fixture_issue
avoid using __file__ in pytest_plugin_registered as can be wrong on Windows
2 parents a6708b9 + 9ea2e0a commit 0f5aa5a

File tree

5 files changed

+35
-24
lines changed

5 files changed

+35
-24
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ repos:
6464
additional_dependencies:
6565
- iniconfig>=1.1.0
6666
- attrs>=19.2.0
67+
- pluggy
6768
- packaging
6869
- tomli
6970
- types-pkg_resources

changelog/11825.improvement.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
The :hook:`pytest_plugin_registered` hook has a new ``plugin_name`` parameter containing the name by which ``plugin`` is registered.

src/_pytest/config/__init__.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -490,15 +490,19 @@ def register(
490490
)
491491
)
492492
return None
493-
ret: Optional[str] = super().register(plugin, name)
494-
if ret:
493+
plugin_name = super().register(plugin, name)
494+
if plugin_name is not None:
495495
self.hook.pytest_plugin_registered.call_historic(
496-
kwargs=dict(plugin=plugin, manager=self)
496+
kwargs=dict(
497+
plugin=plugin,
498+
plugin_name=plugin_name,
499+
manager=self,
500+
)
497501
)
498502

499503
if isinstance(plugin, types.ModuleType):
500504
self.consider_module(plugin)
501-
return ret
505+
return plugin_name
502506

503507
def getplugin(self, name: str):
504508
# Support deprecated naming because plugins (xdist e.g.) use it.

src/_pytest/fixtures.py

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,25 +1483,27 @@ def getfixtureinfo(
14831483

14841484
return FuncFixtureInfo(argnames, initialnames, names_closure, arg2fixturedefs)
14851485

1486-
def pytest_plugin_registered(self, plugin: _PluggyPlugin) -> None:
1487-
nodeid = None
1488-
try:
1489-
p = absolutepath(plugin.__file__) # type: ignore[attr-defined]
1490-
except AttributeError:
1491-
pass
1486+
def pytest_plugin_registered(self, plugin: _PluggyPlugin, plugin_name: str) -> None:
1487+
# Fixtures defined in conftest plugins are only visible to within the
1488+
# conftest's directory. This is unlike fixtures in non-conftest plugins
1489+
# which have global visibility. So for conftests, construct the base
1490+
# nodeid from the plugin name (which is the conftest path).
1491+
if plugin_name and plugin_name.endswith("conftest.py"):
1492+
# Note: we explicitly do *not* use `plugin.__file__` here -- The
1493+
# difference is that plugin_name has the correct capitalization on
1494+
# case-insensitive systems (Windows) and other normalization issues
1495+
# (issue #11816).
1496+
conftestpath = absolutepath(plugin_name)
1497+
try:
1498+
nodeid = str(conftestpath.parent.relative_to(self.config.rootpath))
1499+
except ValueError:
1500+
nodeid = ""
1501+
if nodeid == ".":
1502+
nodeid = ""
1503+
if os.sep != nodes.SEP:
1504+
nodeid = nodeid.replace(os.sep, nodes.SEP)
14921505
else:
1493-
# Construct the base nodeid which is later used to check
1494-
# what fixtures are visible for particular tests (as denoted
1495-
# by their test id).
1496-
if p.name == "conftest.py":
1497-
try:
1498-
nodeid = str(p.parent.relative_to(self.config.rootpath))
1499-
except ValueError:
1500-
nodeid = ""
1501-
if nodeid == ".":
1502-
nodeid = ""
1503-
if os.sep != nodes.SEP:
1504-
nodeid = nodeid.replace(os.sep, nodes.SEP)
1506+
nodeid = None
15051507

15061508
self.parsefactories(plugin, nodeid)
15071509

src/_pytest/hookspec.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,15 @@ def pytest_addhooks(pluginmanager: "PytestPluginManager") -> None:
6363

6464
@hookspec(historic=True)
6565
def pytest_plugin_registered(
66-
plugin: "_PluggyPlugin", manager: "PytestPluginManager"
66+
plugin: "_PluggyPlugin",
67+
plugin_name: str,
68+
manager: "PytestPluginManager",
6769
) -> None:
6870
"""A new pytest plugin got registered.
6971
7072
:param plugin: The plugin module or instance.
71-
:param manager: pytest plugin manager.
73+
:param plugin_name: The name by which the plugin is registered.
74+
:param manager: The pytest plugin manager.
7275
7376
.. note::
7477
This hook is incompatible with hook wrappers.

0 commit comments

Comments
 (0)