astral-sh/ruff · error
Will return Some() when called on class literal
Error message
Will return Some() when called on class literal
What it means
`typed_dict_fallback_class_member` resolves a member on the TypedDict fallback class literal (from typing or typing_extensions, depending on `module`). The stated invariant: an MRO member lookup on a class literal always returns Some because the MRO terminates in `object`. The expect fires when the loaded typeshed does not contain the requested member anywhere in the fallback class's MRO.
Source
Thrown at crates/ty_python_semantic/src/types/class/typed_dict.rs:1086
)
}
pub(super) fn typed_dict_fallback_class_member<'db>(
db: &'db dyn Db,
env: &ProgramEnvironment<'db>,
module: TypingModule,
lookup_policy: MemberLookupPolicy,
name: &str,
) -> PlaceAndQualifiers<'db> {
let fallback = match module {
TypingModule::Typing => KnownClass::TypedDictFallback,
TypingModule::TypingExtensions => KnownClass::ExtensionTypedDictFallback,
};
fallback
.to_class_literal(db, env)
.find_name_in_mro_with_policy(db, env, name, lookup_policy)
.expect("Will return Some() when called on class literal")
}
pub(super) fn typed_dict_class_member<'db>(
db: &'db dyn Db,
env: &ProgramEnvironment<'db>,
class: ClassType<'db>,
module: TypingModule,
lookup_policy: MemberLookupPolicy,
name: &str,
) -> PlaceAndQualifiers<'db> {
let self_class = class.class_literal(db);
typed_dict_inherited_class_member(
db,
env,
TypedDictType::new(class),
module,
lookup_policy,View on GitHub (pinned to d1087a4b9e)
Solutions
- Run ty with the bundled vendored typeshed instead of a custom one.
- Update ty so its member requests match the typeshed version it vendors.
- If a custom typeshed is mandatory, sync it to the version ty's snapshot is pinned to and verify the missing member exists in the stub.
- Report the member name (visible in the panic backtrace) upstream if the bundled setup panics.
Example fix
# before: fallback stub missing the member ty looks up # <typeshed>/stdlib/typing.pyi: class TypedDict(metaclass=_TypedDictMeta): ... # after: restore/patch the stub so the member resolves, e.g. # class TypedDict(metaclass=_TypedDictMeta): # def __call__(self, *args, **kwargs) -> Any: ...
Defensive patterns
Strategy: validation
Validate before calling
# verify the member exists in the stubs ty will load (substitute the member # from your panic backtrace for __call__): grep -rn 'def __call__' <typeshed>/stdlib/typing.pyi <typeshed>/stdlib/builtins.pyi # no hits anywhere in the fallback MRO means this panic is expected
Prevention
- Use the typeshed version vendored with your ty build; do not override it with older stubs.
- Keep ty and any custom stub checkout in sync when typeshed APIs move.
- Capture the member name from the backtrace before reporting; it identifies the stub gap.
When it happens
Trigger: Member access on a TypedDict-shaped type that falls back to the stub class while the active typeshed's `typing.pyi`/`typing_extensions` fallback stubs lack the member (and `object` does not provide it either).
Common situations: Custom, stripped, or outdated typeshed directories; mixing a typeshed snapshot with a ty binary from a different era; typeshed API changes where a member moved or was renamed while ty still requests the old name.
Related errors
- `find_name_in_mro` should return `Some` for a class literal
- `object` should always be a non-generic class in typeshed
- TypedDict code generation should use a TypedDict instance
- TypedDictParams should be available for CodeGeneratorKind::T
- Expected `NamedTuple` definition to be an assignment
AI-assisted analysis of astral-sh/ruff@d1087a4b9e (2026-08-20).
Data as JSON: /api/errors/37c84e56f3e8bf35.
Report an issue: GitHub.