astral-sh/ruff · error
Missing argument `cls`
Error message
Missing argument `cls`
What it means
Same `isinstance` rewrite path, but for the `cls` argument: `assert isinstance(obj, cls)` needs both operands. When `args_map` lacks a `"cls"` entry, `generate_assert` returns this error and skips producing a fix.
Source
Thrown at crates/ruff_linter/src/rules/flake8_pytest_style/rules/unittest_assert.rs:383
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,
},
range_start: ruff_text_size::TextSize::default(),
node_index: ruff_python_ast::AtomicNodeIndex::NONE,
};View on GitHub (pinned to 15f3fe6b15)
Solutions
- Add the class argument: `self.assertIsInstance(value, ExpectedType)`.
- Suppress PT009 for that code if rewriting is not desired.
- While patching Ruff, check `args_map`'s positional zip — an extra/missing leading positional shifts names and drops `cls`.
- Re-run `ruff check --fix` to validate the rewrite completes.
Example fix
// before self.assertIsInstance(response) // after self.assertIsInstance(response, dict)
Defensive patterns
Strategy: validation
Validate before calling
def valid_isinstance_call(call_args, call_kwargs):
return (len(call_args) >= 2) or (len(call_args) == 1 and 'cls' in call_kwargs) Type guard
def has_cls(args: tuple, kwargs: dict) -> bool:
return len(args) >= 2 or 'cls' in kwargs Prevention
- Always supply the expected type as the second argument.
- When refactoring types, grep for assertIsInstance calls touching the renamed class.
- Prefer `# noqa: PT009` over converting custom helpers that lack the cls parameter.
- Run `ruff check` (no fix) on changed test files in CI.
When it happens
Trigger: `UnittestAssert::IsInstance | NotIsInstance.generate_assert` where the call supplied `obj` but no second positional arg and no `cls=` keyword, e.g. `self.assertIsInstance(value)`.
Common situations: Half-finished test assertions; class arguments removed during refactoring; non-unittest `assertIsInstance` helpers with different arity.
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
- Missing argument `first`
- Missing argument `second`
- Missing argument `member`
- Missing argument `container`
- Missing argument `obj`
AI-assisted analysis of astral-sh/ruff@15f3fe6b15 (2026-09-05).
Data as JSON: /api/errors/71853c5169b83deb.
Report an issue: GitHub.