{"record":{"id":"32b0846d9de36f93","repo":"astral-sh/ruff","slug":"expected-namedtuple-definition-to-be-an-assignme","errorCode":null,"errorMessage":"Expected `NamedTuple` definition to be an assignment","messagePattern":"Expected `NamedTuple` definition to be an assignment","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ty_python_semantic/src/types/class/named_tuple.rs","lineNumber":453,"sourceCode":"                    TypeContext::default(),\n                )\n            })\n        }\n    }\n\n    fn spec(self, db: &'db dyn Db) -> NamedTupleSpec<'db> {\n        #[salsa::tracked(\n            returns(copy),\n            cycle_initial=|db, _, _| NamedTupleSpec::unknown(db),\n            heap_size=ruff_memory_usage::heap_size\n        )]\n        fn deferred_spec<'db>(db: &'db dyn Db, definition: Definition<'db>) -> NamedTupleSpec<'db> {\n            let python_file = definition.python_file(db);\n            let module = parsed_module(db, python_file).load(db);\n            let node = definition\n                .kind(db)\n                .value(&module)\n                .expect(\"Expected `NamedTuple` definition to be an assignment\")\n                .as_call_expr()\n                .expect(\"Expected `NamedTuple` definition r.h.s. to be a call expression\");\n            match definition_expression_type(db, definition, &node.arguments.args[1]) {\n                Type::KnownInstance(KnownInstanceType::NamedTupleSpec(spec)) => spec,\n                _ => NamedTupleSpec::unknown(db),\n            }\n        }\n\n        match self.anchor(db) {\n            DynamicNamedTupleAnchor::CollectionsDefinition { spec, .. }\n            | DynamicNamedTupleAnchor::ScopeOffset { spec, .. } => *spec,\n            DynamicNamedTupleAnchor::TypingDefinition(definition) => deferred_spec(db, *definition),\n        }\n    }\n\n    fn fields(self, db: &'db dyn Db) -> &'db [NamedTupleField<'db>] {\n        self.spec(db).fields(db)\n    }","sourceCodeStart":435,"sourceCodeEnd":471,"githubUrl":"https://github.com/astral-sh/ruff/blob/d1087a4b9e03d253a88703f34e0869ee4b805456/crates/ty_python_semantic/src/types/class/named_tuple.rs#L435-L471","documentation":"For functional NamedTuple syntax (`P = NamedTuple('P', [('x', int)])` resolved through the typing module), ty defers computing the field spec to `deferred_spec`. It re-reads the definition's value node and asserts the definition is an assignment; the expect fires when a `DynamicNamedTupleAnchor::TypingDefinition` points at a definition with no value expression in the module.","triggerScenarios":"Calling `spec()` on a `DynamicNamedTuple` anchored via `TypingDefinition(definition)` (named_tuple.rs match arm) where `definition.kind(db).value(&module)` is None - a non-assignment definition or one resolved against a different parse.","commonSituations":"Extending functional-NamedTuple detection (collections vs typing modules, bare call expressions, aliased assignments); refactors of `DefinitionKind`; anchors surviving a reparse in LSP mode.","solutions":["Guard at anchor construction: only create `TypingDefinition` for definitions whose `.value()` is Some.","Add an mdtest for the exact NamedTuple shape that panicked; run the ty_python_semantic mdtests.","Verify the module is parsed from `definition.python_file(db)`.","Report with a reproducer if stock ty panics."],"exampleFix":"// before\nlet node = definition.kind(db).value(&module)\n    .expect(\"Expected `NamedTuple` definition to be an assignment\");\n\n// after: bail out to the unknown spec instead of panicking\nlet Some(value) = definition.kind(db).value(&module) else {\n    return NamedTupleSpec::unknown(db);\n};","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"let spec = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {\n    named_tuple.spec(db)\n}))\n.unwrap_or_else(|_| NamedTupleSpec::unknown(db));","preventionTips":["Use the classic class-based NamedTuple syntax in code under check while a functional-syntax bug is pending.","Include the exact `NamedTuple(...)` statement in issue reports.","Contributors: add an mdtest for every new anchor shape you introduce."],"tags":["rust","panic","expect","ty","namedtuple","dynamic-class","definition"],"backgroundTag":"rust-expect-panic","analyzedSha":"d1087a4b9e03d253a88703f34e0869ee4b805456","analyzedAt":"2026-08-20T16:33:49.445Z","contentChangedAt":"2026-08-20T16:33:49.445Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}