diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index 46b201184..51c573575 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -1483,27 +1483,27 @@ class FixtureManager: return FuncFixtureInfo(argnames, initialnames, names_closure, arg2fixturedefs) - def pytest_plugin_registered(self, plugin: _PluggyPlugin) -> None: - nodeid = None - plugin_name = self.config.pluginmanager.get_name(plugin) - - # Construct the base nodeid which is later used to check - # what fixtures are visible for particular tests (as denoted - # by their test id). + def pytest_plugin_registered(self, plugin: _PluggyPlugin, plugin_name: str) -> None: + # Fixtures defined in conftest plugins are only visible to within the + # conftest's directory. This is unlike fixtures in non-conftest plugins + # which have global visibility. So for conftests, construct the base + # nodeid from the plugin name (which is the conftest path). if plugin_name and plugin_name.endswith("conftest.py"): - # The plugin name is assumed to be equal to plugin.__file__ - # for conftest plugins. The difference is that plugin_name - # has the correct capitalization on capital-insensitive - # systems (Windows). - p = absolutepath(plugin_name) + # Note: we explicitly do *not* use `plugin.__file__` here -- The + # difference is that plugin_name has the correct capitalization on + # case-insensitive systems (Windows) and other normalization issues + # (issue #11816). + conftestpath = absolutepath(plugin_name) try: - nodeid = str(p.parent.relative_to(self.config.rootpath)) + nodeid = str(conftestpath.parent.relative_to(self.config.rootpath)) except ValueError: nodeid = "" if nodeid == ".": nodeid = "" if os.sep != nodes.SEP: nodeid = nodeid.replace(os.sep, nodes.SEP) + else: + nodeid = None self.parsefactories(plugin, nodeid)