pytest-dev/pytest · error · TypeError
invalid type for lines2
Error message
invalid type for lines2: {type(lines2).__name__} What it means
Thrown by LineMatcher._match_lines() when the lines2 argument is not a collections.abc.Sequence (e.g. a generator, set, or mapping). fnmatch_lines/re_match_lines require indexable, re-iterable sequence input.
Solutions
- Wrap the iterable in list(): fnmatch_lines(list(...)).
- Pass a list or tuple literal directly.
- Materialize generators before the call.
Example fix
// before result.stdout.fnmatch_lines(l.upper() for l in expected) // after result.stdout.fnmatch_lines([l.upper() for l in expected])
Defensive patterns
Strategy: type-guard
Validate before calling
if not isinstance(lines2, collections.abc.Sequence):
lines2 = list(lines2)
result.stdout.fnmatch_lines(lines2) Type guard
import collections.abc
def is_sequence_for_match(lines2: object) -> bool:
return isinstance(lines2, collections.abc.Sequence) Prevention
- Pass lists or tuples to fnmatch_lines/re_match_lines.
- Materialize generators/iterators before the call.
- Avoid sets/dicts which are not Sequences.
When it happens
Trigger: Passing a generator expression to fnmatch_lines: result.stdout.fnmatch_lines(l.upper() for l in lines); passing a set or dict; passing an iterator object.
Common situations: Using a generator comprehension for brevity; passing a set of expected lines; transforming lines with map() which returns an iterator in Python 3.
Related errors
- ext must not be None
- line not found in output
- could not find test report matching
- example " " is not found as a file or directory
- Expected id to be a string or a `pytest.HIDDEN_PARAM`…
AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11).
Data as JSON: /api/errors/5ab1b6753d717bd8.
Report an issue: GitHub.
Appendix: source
Thrown at src/_pytest/pytester.py:1703
consecutive: bool = False,
) -> None:
"""Underlying implementation of ``fnmatch_lines`` and ``re_match_lines``.
:param Sequence[str] lines2:
List of string patterns to match. The actual format depends on
``match_func``.
:param match_func:
A callable ``match_func(line, pattern)`` where line is the
captured line from stdout/stderr and pattern is the matching
pattern.
:param str match_nickname:
The nickname for the match function that will be logged to stdout
when a match occurs.
:param consecutive:
Match lines consecutively?
"""
if not isinstance(lines2, collections.abc.Sequence):
raise TypeError(f"invalid type for lines2: {type(lines2).__name__}")
lines2 = self._getlines(lines2)
lines1 = self.lines[:]
extralines = []
__tracebackhide__ = True
wnick = len(match_nickname) + 1
started = False
for line in lines2:
nomatchprinted = False
while lines1:
nextline = lines1.pop(0)
if line == nextline:
self._log("exact match:", repr(line))
started = True
break
elif match_func(nextline, line):
self._log(f"{match_nickname}:", repr(line))
self._log(
"{:>{width}}".format("with:", width=wnick), repr(nextline)View on GitHub (pinned to 0d6fbdeffa)