astral-sh/ruff · error

Missing argument `obj`

Error message

Missing argument `obj`

What it means

For `assertIsInstance`/`assertNotIsInstance`, `generate_assert` emits `assert isinstance(obj, cls)`. The rewrite first requires the `obj` argument; when the mapped call arguments contain no `"obj"` entry, the transformation fails with this error.

Source

Thrown at crates/ruff_linter/src/rules/flake8_pytest_style/rules/unittest_assert.rs:380

                    .get("expr")
                    .ok_or_else(|| anyhow!("Missing argument `expr`"))?;
                let msg = args.get("msg").copied();
                let cmp_op = if matches!(self, UnittestAssert::IsNone) {
                    CmpOp::Is
                } else {
                    CmpOp::IsNot
                };
                let node = Expr::NoneLiteral(ast::ExprNoneLiteral {
                    range: TextRange::default(),
                    node_index: ruff_python_ast::AtomicNodeIndex::NONE,
                });
                let expr = compare(expr, cmp_op, &node);
                Ok(assert(&expr, msg))
            }
            UnittestAssert::IsInstance | UnittestAssert::NotIsInstance => {
                let obj = args
                    .get("obj")
                    .ok_or_else(|| anyhow!("Missing argument `obj`"))?;
                let cls = args
                    .get("cls")
                    .ok_or_else(|| anyhow!("Missing argument `cls`"))?;
                let msg = args.get("msg").copied();
                let node = ast::ExprName {
                    id: Name::new_static("isinstance"),
                    ctx: ExprContext::Load,
                    range: TextRange::default(),
                    node_index: ruff_python_ast::AtomicNodeIndex::NONE,
                };
                let node1 = ast::ExprCall {
                    func: Box::new(node.into()),
                    arguments: Arguments {
                        args: [(**obj).clone(), (**cls).clone()].into(),
                        keywords: std::iter::empty().collect(),
                        range: TextRange::default(),
                        node_index: ruff_python_ast::AtomicNodeIndex::NONE,
                    },

View on GitHub (pinned to 15f3fe6b15)

Solutions

  1. Complete the call: `self.assertIsInstance(value, SomeClass)`.
  2. Ignore PT009 (per-file-ignores or global ignore) if the method is not unittest's.
  3. If maintaining Ruff, verify the `arg_spec = ['obj', 'cls', 'msg']` mapping in `args_map`.
  4. Check the reported source range to confirm the triggering call before changing configuration.

Example fix

// before
self.assertIsInstance(cls=MyClass)
// after
self.assertIsInstance(obj, MyClass)
Defensive patterns

Strategy: validation

Validate before calling

def valid_isinstance_call(call_args, call_kwargs):
    return len(call_args) >= 1 or 'obj' in call_kwargs

Type guard

def has_obj(args: tuple, kwargs: dict) -> bool:
    return len(args) >= 1 or 'obj' in kwargs

Prevention

When it happens

Trigger: `UnittestAssert::IsInstance | NotIsInstance.generate_assert` where the call is missing the first positional arg and has no `obj=` keyword — e.g. `self.assertIsInstance()` or a call passing only `cls`/`msg`.

Common situations: Incomplete type-check assertions in test suites run through `ruff --fix`; helper classes defining `assertIsInstance` with a different signature mistaken for unittest methods.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of astral-sh/ruff@15f3fe6b15 (2026-09-05). Data as JSON: /api/errors/f2183252d655bd90. Report an issue: GitHub.