TypeError: 'type' object is not subscriptable after python 3.9 upgrade
Fixes TypeError: 'type' object is not subscriptable surfacing after a Python 3.9 upgrade. Use it when builtin generics like list[int] fail because the interpreter actually running the code is older than expected, or the subscripted name was never generic. Key trigger: the exact not-subscriptable TypeError on a type.
TypeError: 'type' object is not subscriptable after python 3.9 upgrade
TL;DR: Something subscripts a type (like list[int]) where the running interpreter evaluates it eagerly, and the interpreter actually executing the code is usually older than you think - or the subscripted name was never generic at all. Verify the real interpreter with python --version on the exact binary running the code, then fix the annotation or the class.
TypeError: 'type' object is not subscriptable after python 3.9 upgradeSteps
Read the traceback and find the exact subscript expression that fails (often an annotation like
x: list[int]or a custom class being subscripted). Expected: you have the failing line and the name being subscripted.Check the real interpreter: run
which pythonand then that binary with--version. Stale venvs, containers, and CI images often still run 3.8 while your shell says 3.9+. Expected: you confirm whether the executing interpreter is genuinely 3.9 or newer.If it is older than 3.9: switch to the right interpreter, or rewrite with
typinggenerics (List[int]) and addfrom __future__ import annotationsfor annotation-only usage. Expected: the TypeError goes away.If it is 3.9+ and a builtin generic still fails, the name is shadowed by a non-generic import - inspect what it actually is. If it is your own class, add
__class_getitem__or inherit fromtyping.Generic. Expected: subscripting the class works.
Use this when
- The exact text
'type' object is not subscriptableappears after a Python upgrade. - The failing code uses builtin generics (
list[int],dict[str, int]) in annotations or at runtime. - The traceback points at a class definition, dataclass field, or annotation being evaluated.
Not for this skill when
- The error is
'X' object is not subscriptableon an instance - that is an instance problem, not a type problem. - The failing syntax is
X | Yunions - those need Python 3.10+, different fix. - A third-party class that was never generic is subscripted at runtime - that is a library usage error.
Variant phrasings
- type object is not subscriptable list int after upgrade
- python builtin generics not working 3.9
- subscriptable TypeError dataclass annotation
Why it happens
PEP 585 made builtin collections generic in Python 3.9, so on 3.9+ this error almost always means an older interpreter is actually running the code (the classic venv/container mismatch) - or the subscripted name is a plain class without __class_getitem__, which was never subscriptable on any version.
Edge cases
from __future__ import annotationsonly defers annotation evaluation - runtime subscripts (casts, validators, explicit subscripts in function bodies) still fail on old interpreters.- Dataclass and pydantic field types are evaluated eagerly, so they are the usual crash sites - check them first.
- Verify every interpreter in the chain (shell, venv, container, CI image) - fixing one while another runs the code changes nothing.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_5daLiyY4k9a-2Wr8ecH7CQ