{"record":{"id":"be1a4d92ca0a426b","repo":"astral-sh/ruff","slug":"missing-argument-second","errorCode":null,"errorMessage":"Missing argument `second`","messagePattern":"Missing argument `second`","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ruff_linter/src/rules/flake8_pytest_style/rules/unittest_assert.rs","lineNumber":324,"sourceCode":"            }\n            UnittestAssert::Equal\n            | UnittestAssert::Equals\n            | UnittestAssert::FailUnlessEqual\n            | UnittestAssert::NotEqual\n            | UnittestAssert::NotEquals\n            | UnittestAssert::FailIfEqual\n            | UnittestAssert::Greater\n            | UnittestAssert::GreaterEqual\n            | UnittestAssert::Less\n            | UnittestAssert::LessEqual\n            | UnittestAssert::Is\n            | UnittestAssert::IsNot => {\n                let first = args\n                    .get(\"first\")\n                    .ok_or_else(|| anyhow!(\"Missing argument `first`\"))?;\n                let second = args\n                    .get(\"second\")\n                    .ok_or_else(|| anyhow!(\"Missing argument `second`\"))?;\n                let msg = args.get(\"msg\").copied();\n                let cmp_op = match self {\n                    UnittestAssert::Equal\n                    | UnittestAssert::Equals\n                    | UnittestAssert::FailUnlessEqual => CmpOp::Eq,\n                    UnittestAssert::NotEqual\n                    | UnittestAssert::NotEquals\n                    | UnittestAssert::FailIfEqual => CmpOp::NotEq,\n                    UnittestAssert::Greater => CmpOp::Gt,\n                    UnittestAssert::GreaterEqual => CmpOp::GtE,\n                    UnittestAssert::Less => CmpOp::Lt,\n                    UnittestAssert::LessEqual => CmpOp::LtE,\n                    UnittestAssert::Is => CmpOp::Is,\n                    UnittestAssert::IsNot => CmpOp::IsNot,\n                    _ => unreachable!(),\n                };\n                let expr = compare(first, cmp_op, second);\n                Ok(assert(&expr, msg))","sourceCodeStart":306,"sourceCodeEnd":342,"githubUrl":"https://github.com/astral-sh/ruff/blob/15f3fe6b15a5f00172f34b0f542f8ea277f5a586/crates/ruff_linter/src/rules/flake8_pytest_style/rules/unittest_assert.rs#L306-L342","documentation":"Same PT009 assert-rewrite path, but for the `second` operand: `assertLess`/`assertLessEqual`/`assertIs`/`assertIsNot` require two comparands to emit `assert first <op> second`. When `args_map` has no `\"second\"` entry, `generate_assert` returns this error and no fix is produced.","triggerScenarios":"`generate_assert` for Less/LessEqual/Is/IsNot where the call supplied `first` (or nothing) but no `second`: e.g. `self.assertIs(x)` with one positional arg and no `second=` keyword.","commonSituations":"Truncated or hand-edited test calls; non-unittest classes defining `assertIs` with different arity being pattern-matched by PT009; running `--fix` on partially refactored test suites.","solutions":["Complete the call in the flagged test: `self.assertIs(result, None)`.","Suppress PT009 (ignore rule or per-file-ignores) if the call is not a real unittest method.","If developing Ruff, audit `args_map`'s positional zip and the keyword fill-in for off-by-one shifts.","Re-run the fixer after the test call is corrected."],"exampleFix":"// before\nself.assertIs(value)\n// after\nself.assertIs(value, expected)","handlingStrategy":"validation","validationCode":"import inspect\n\nsig = inspect.signature(self.assertIs)\nrequired = [p for p in sig.parameters.values() if p.default is inspect.Parameter.empty]\nassert len(required) >= 2, 'assertIs requires first and second'","typeGuard":"def has_second_operand(args: tuple, kwargs: dict) -> bool:\n    return len(args) >= 2 or ('second' in kwargs and len(args) >= 1)","tryCatchPattern":null,"preventionTips":["Never call assertIs/assertLess with a single operand; the rewrite requires both.","Run lint without --fix first to catch incomplete asserts before autofixing.","Review test diffs after removing an expected value — leftover one-arg asserts trigger this.","Do not shadow unittest assert names with helpers of different arity."],"tags":["linter","rust","pytest-style","argument-missing"],"backgroundTag":"missing-required-argument","analyzedSha":"15f3fe6b15a5f00172f34b0f542f8ea277f5a586","analyzedAt":"2026-09-05T10:32:37.492Z","contentChangedAt":"2026-09-05T10:32:37.492Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}