pytest-dev/pytest · error · TypeError
parsefactories() requires holder or node_or_obj
Error message
parsefactories() requires holder or node_or_obj
What it means
FixtureManager.parsefactories (fixtures.py:2277) requires either the new 'holder' parameter or the legacy 'node_or_obj' parameter to identify the object holding fixture factories. If both are NOTSET, it raises TypeError immediately. This is an internal/extension-author API: regular test code never calls it directly.
Source
Thrown at src/_pytest/fixtures.py:2277
The preferred API uses keyword-only arguments:
- ``holder``: The object to scan for fixtures.
- ``node``: The node determining fixture visibility.
Legacy positional API (translated internally):
- ``parsefactories(node)``: Uses node.obj as holder, node for scope.
- ``parsefactories(obj, nodeid)``: Uses obj as holder, nodeid string for scope.
"""
# Translate legacy API to holder/node sources of truth
# Either effective_node or effective_nodeid will be set, not both
effective_node: nodes.Node | NotSetType = NOTSET
effective_nodeid: str | NotSetType | None = NOTSET
if holder is not NOTSET:
# New API: holder and node explicitly provided
holderobj = holder
effective_node = node
elif node_or_obj is NOTSET:
raise TypeError("parsefactories() requires holder or node_or_obj")
elif nodeid is not NOTSET:
# Legacy: parsefactories(obj, nodeid) - string-based scoping only.
warnings.warn(PARSEFACTORIES_NODEID_DEPRECATED, stacklevel=2)
holderobj = node_or_obj
effective_nodeid = nodeid
else:
# parsefactories(node) - node has .obj attribute
assert isinstance(node_or_obj, nodes.Node)
holderobj = cast(object, node_or_obj.obj) # type: ignore[attr-defined]
effective_node = node_or_obj
# Avoid accessing `@property` (and other descriptors) when iterating fixtures.
holderobj_tp: type | types.ModuleType
if not safe_isclass(holderobj) and not isinstance(holderobj, types.ModuleType):
holderobj_tp = type(holderobj)
else:
holderobj_tp = cast("type | types.ModuleType", holderobj)
View on GitHub (pinned to 0d6fbdeffa)
Solutions
- Pass 'holder=obj, node=node' using the new keyword API.
- If using legacy 'parsefactories(obj, nodeid)', pass obj as node_or_obj and the nodeid string as nodeid (expect a deprecation warning).
- Prefer registering fixtures via @pytest.fixture in conftest.py rather than calling parsefactories manually.
- Consult the docstring of parsefactories for the supported signatures before calling.
Example fix
// before fm.parsefactories() # missing args // after fm.parsefactories(holder=obj, node=node)
Defensive patterns
Strategy: validation
Validate before calling
# Plugin authors: validate before calling parsefactories
def safe_parsefactories(fm, holder=None, node=None, node_or_obj=None, nodeid=None):
if holder is None and node_or_obj is None:
raise TypeError('parsefactories() requires holder or node_or_obj')
return fm.parsefactories(holder=holder, node=node, node_or_obj=node_or_obj, nodeid=nodeid) Try / catch
try:
fm.parsefactories(holder=obj, node=node)
except TypeError as e:
if 'requires holder' in str(e):
# fallback to legacy signature
fm.parsefactories(obj, node.nodeid)
else:
raise Prevention
- Prefer registering fixtures via conftest.py over manual parsefactories.
- Pin to the new keyword API when extending pytest.
- Read the parsefactories docstring before calling.
When it happens
Trigger: A plugin or conftest calling FixtureManager.parsefactories() with neither holder nor node_or_obj; passing only nodeid without obj under the legacy signature; migrating a custom collection hook that previously relied on positional args.
Common situations: Third-party plugins using the deprecated parsefactories(obj, nodeid) signature and partially migrating; monkeypatching _pytest internals; custom dynamic fixture registration code.
Related errors
- Error evaluating {scope_callable} while defining fixture '{f
- {request.fixturename} did not yield a value
- errors while tearing down fixture "{self.argname}" of {node}
- class fixtures not supported (maybe in the future)
- @pytest.fixture is being applied more than once to the same
AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11).
Data as JSON: /api/errors/99a7aee67bb83965.
Report an issue: GitHub.