pytest-dev/pytest · error · TypeError

use delattr(target, name) or delattr(target) with target bei

Error message

use delattr(target, name) or delattr(target) with target being a dotted import string

What it means

Raised by MonkeyPatch.delattr when called with a single argument that is not a dotted import string. pytest supports delattr(target, name) for an object plus attribute name, or delattr(target) where target is a dotted path like "pkg.mod.attr". Passing a bare object with no name is ambiguous and is rejected with TypeError.

Source

Thrown at src/_pytest/monkeypatch.py:270

        target: object | str,
        name: str | NotSetType = NOTSET,
        raising: bool = True,
    ) -> None:
        """Delete attribute ``name`` from ``target``.

        If no ``name`` is specified and ``target`` is a string
        it will be interpreted as a dotted import path with the
        last part being the attribute name.

        Raises AttributeError it the attribute does not exist, unless
        ``raising`` is set to False.
        """
        __tracebackhide__ = True
        import inspect

        if name is NOTSET:
            if not isinstance(target, str):
                raise TypeError(
                    "use delattr(target, name) or "
                    "delattr(target) with target being a dotted "
                    "import string"
                )
            name, target = derive_importpath(target, raising)

        if not hasattr(target, name):
            if raising:
                raise AttributeError(name)
        else:
            oldval = getattr(target, name, NOTSET)
            # Avoid class descriptors like staticmethod/classmethod.
            if inspect.isclass(target):
                oldval = target.__dict__.get(name, NOTSET)
            self._setattr.append((target, name, oldval))
            delattr(target, name)

    def setitem(self, dic: Mapping[K, V], name: K, value: V) -> None:

View on GitHub (pinned to 98b357f69e)

Solutions

  1. Pass the attribute name explicitly: monkeypatch.delattr(target, 'attr_name')
  2. If you want the single-arg form, pass a dotted import string: monkeypatch.delattr('package.module.attr')

Example fix

// before
monkeypatch.delattr(some_module)
// after
monkeypatch.delattr(some_module, 'attr_name')
Defensive patterns

Strategy: validation

Validate before calling

def safe_delattr(mpatch, target, name=None):
    import inspect
    if name is None:
        if not isinstance(target, str):
            raise TypeError("single-arg delattr requires a dotted import string")
        mpatch.delattr(target)
    else:
        mpatch.delattr(target, name)

Type guard

def is_dotted_import_path(target) -> bool:
    return isinstance(target, str) and '.' in target

Prevention

When it happens

Trigger: Calling monkeypatch.delattr(some_module) or monkeypatch.delattr(obj) where obj is a module/class/instance and the second positional `name` argument is omitted. The single-argument form only accepts str.

Common situations: Developers conflate the builtin delattr(obj, name) signature with pytest's monkeypatch.delattr and omit the name; or attempt the dotted-string shortcut with an actual object reference.

Related errors


AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04). Data as JSON: /data/errors/0e8525507e2b14fe.json. Report an issue: GitHub.