pytest-dev/pytest · error · TypeError

ext must not be None

Error message

ext must not be None

What it means

Thrown by Pytester._makefile() when the `ext` argument is None. The annotation says str but None slips in via makefile() callers; the guard converts it into a clear TypeError instead of an AttributeError later.

Solutions

  1. Pass a concrete extension string starting with '.', e.g. '.py' or '.txt'.
  2. Default the extension in your helper to '.py' instead of None.
  3. Use the dedicated shortcut methods (makepyfile, makeini, maketxtfile) which set the extension for you.

Example fix

// before
pytester.makefile(ext, "content")  # ext may be None
// after
pytester.makefile(ext or ".txt", "content")
Defensive patterns

Strategy: type-guard

Validate before calling

ext = ext if ext is not None else '.txt'
pytester.makefile(ext, content)

Type guard

def is_valid_ext(ext: object) -> bool:
    return isinstance(ext, str) and ext.startswith('.')

Prevention

When it happens

Trigger: Calling pytester.makefile(None, 'content') directly; a wrapper/helper that computes the extension dynamically and passes None when no extension was configured; programmatic test generation that forgets to set the extension.

Common situations: Test helper functions that accept an optional extension parameter; data-driven test frameworks building files dynamically; copy-paste from makepyfile()/maketxtfile() that hardcode extensions, into a generic makefile() call.

Related errors


AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11). Data as JSON: /api/errors/ee011038c8a7e7a7. Report an issue: GitHub.

Appendix: source

Thrown at src/_pytest/pytester.py:769

    def chdir(self) -> None:
        """Cd into the temporary directory.

        This is done automatically upon instantiation.
        """
        self._monkeypatch.chdir(self.path)

    def _makefile(
        self,
        ext: str,
        lines: Sequence[Any | bytes],
        files: Mapping[str, _FileContent],
        encoding: str = "utf-8",
    ) -> Path:
        items = list(files.items())

        if ext is None:
            raise TypeError("ext must not be None")

        if ext and not ext.startswith("."):
            raise ValueError(
                f"pytester.makefile expects a file extension, try .{ext} instead of {ext}"
            )

        def to_text(s: Any | bytes) -> str:
            return s.decode(encoding) if isinstance(s, bytes) else str(s)

        if lines:
            source = "\n".join(to_text(x) for x in lines)
            basename = self._name
            items.insert(0, (basename, source))

        ret = None
        for basename, value in items:
            p = self.path.joinpath(basename).with_suffix(ext)
            p.parent.mkdir(parents=True, exist_ok=True)

View on GitHub (pinned to 0d6fbdeffa)