TypeError: 'type' object is not subscriptable in Python

PYTHON Updated Mar 5, 2026 7 mins read Leon Leon
TypeError: 'type' object is not subscriptable in Python cover image

Quick summary

Summarize this blog with AI

TypeError: 'type' object is not subscriptable means Python hit square brackets on a class or type object that does not support subscription. In real projects, this usually happens for one of four reasons: you indexed a class instead of an instance, you used list[str] or dict[str, int] on Python 3.8 or earlier, you wrote square brackets when you meant parentheses, or you subscripted a custom class that never implemented the right special method.

If you want the short version, start by checking the line that raised the exception and ask one question: am I using [] on a class, not on a list, dict, tuple, or another object that actually supports subscription? In many cases, that single check is enough to fix the bug in under a minute.

Quick answer

These are the fastest fixes for the most common versions of this error:

  • If you wrote MyClass[0], create an instance first: MyClass()[0] only works if the instance supports __getitem__().
  • If you wrote list[str], dict[str, int], or type[User] on Python 3.8 or earlier, switch to typing.List, typing.Dict, or typing.Type, or upgrade to Python 3.9+.
  • If you wrote my_function[0], you probably meant my_function()[0].
  • If you want a custom object to support obj[index], implement __getitem__(). If you want a class to support MyClass[T], implement __class_getitem__() or inherit from typing.Generic.
# Common fix when you indexed the class instead of the instance
class Numbers:
    def __getitem__(self, index):
        return [10, 20, 30][index]

# Wrong
Numbers[0]

# Right
Numbers()[0]

What the error means

In Python, an object is subscriptable if it can be used with square brackets, like obj[0] or obj["name"]. Lists, tuples, dictionaries, strings, and many other built-in containers are subscriptable. They either expose __getitem__() directly or are implemented in C with equivalent behavior.

The important detail here is the word type in the exception. Python is telling you that the thing on the left side of the brackets is a class object, not a normal container instance. That is why the message is not 'list' object is not subscriptable or 'int' object is not subscriptable. It is specifically complaining that a type object, meaning a class, does not know how to handle the brackets you used.

This distinction matters because the fix depends on whether you meant one of these two patterns:

  • instance[index], which relies on __getitem__()
  • ClassName[T], which relies on __class_getitem__() and is common in type hints and generic classes

Common causes and how to fix each one

You indexed a class instead of an instance

This is the most literal form of the error. You created a class with subscriptable instances, but then used brackets on the class itself.

class Team:
    def __init__(self):
        self.members = ["Ana", "Ben", "Chris"]

    def __getitem__(self, index):
        return self.members[index]

# Wrong
Team[0]

# Right
Team()[0]

If your class has __getitem__(), the instance can be subscripted. The class usually cannot. When you see this error, print the variable before the brackets and confirm whether it is the class object or an instance created from that class.

You used Python 3.9-style generic syntax on Python 3.8 or earlier

This is one of the highest-intent variants behind the keyword typeerror: 'type' object is not subscriptable. Code like this is valid in Python 3.9 and newer:

names: list[str] = ["Ada", "Grace"]
scores: dict[str, int] = {"sql": 10}
owner: type[int]

But on Python 3.8 and earlier, built-in collections and type are not runtime generics in the same way. That means code such as list[str] can raise TypeError: 'type' object is not subscriptable. The safe fix on older versions is to import those types from the official typing module:

from typing import Dict, List, Type

names: List[str] = ["Ada", "Grace"]
scores: Dict[str, int] = {"sql": 10}
owner: Type[int]

Python 3.9 added built-in generic support through PEP 585. So if you copied a modern tutorial and your environment is still on 3.8, version mismatch may be the whole problem.

You used square brackets when you meant parentheses

This bug looks small, but it happens often when you are moving quickly or refactoring code. Brackets index an existing object. Parentheses call a function and return a value.

def get_rows():
    return [["a", 1], ["b", 2]]

# Wrong
get_rows[0]

# Right
get_rows()[0]

If the traceback points to a function name followed by brackets, fix the function call first. After that, subscript the return value if needed.

You subscripted a custom class that is not generic

If you are writing a framework, data structure, or typed utility, you may intentionally want syntax like Box[int]. That syntax only works when the class supports class-level subscription.

class Box:
    pass

# Raises TypeError
Box[int]

There are two common ways to fix this:

  • Use typing.Generic when you are defining a generic type for annotations.
  • Implement __class_getitem__() if you really need custom runtime behavior.
from typing import Generic, TypeVar

T = TypeVar("T")

class Box(Generic[T]):
    def __init__(self, value: T):
        self.value = value

Box[int]

The Python data model documentation covers the difference between __getitem__() and __class_getitem__() in more detail if you need the low-level behavior.

Why list[str] works in Python 3.9+ but fails in Python 3.8

This version split confuses a lot of developers because the code looks perfectly reasonable. Starting with Python 3.9, standard collections like list, dict, tuple, and even type gained support for generic parameterization at runtime. That is why list[str] now works in ordinary code.

On Python 3.8 and earlier, that syntax is not broadly available in runtime contexts. In practice, the easiest rule is this:

  • Python 3.9 and newer: use list[str], dict[str, int], and type[User]
  • Python 3.8 and earlier: use List[str], Dict[str, int], and Type[User] from typing
import sys

print(sys.version)

If you are debugging code from a shared repo, a copied Stack Overflow answer, or a tutorial written for a newer interpreter, always check the Python version before changing anything else. That one line can save a lot of wasted effort.

How to debug this error quickly

When you need to move fast, use this checklist:

  1. Read the exact line in the traceback. Find the object directly to the left of [].
  2. Print the object and its type. If you see <class '...', you are working with a class object.
  3. Check your Python version with sys.version.
  4. Decide whether you meant to index a container, call a function, or declare a type hint.
  5. If the object is custom, look for __getitem__() or __class_getitem__().
print(value)
print(type(value))

If you need a broader refresher on Python exceptions and tracebacks, see our Python exceptions guide. If the failing code uses lists heavily, this Python list tutorial is also a useful reference.

Best practices to avoid this error in new code

You do not need defensive programming everywhere, but a few habits reduce the odds of seeing this exception again:

  • Keep type hints aligned with your interpreter version. If a project is pinned to Python 3.8, do not mix in 3.9+ generic syntax.
  • Use clear variable names so classes and instances are easy to distinguish. team_cls and team are harder to confuse than two variables with nearly identical names.
  • Write small tests around typed helpers and custom containers. If a class is supposed to support obj[index] or Class[T], test that behavior directly.
  • Do not copy annotation syntax blindly from newer tutorials. Check the target Python version first.

In other words, this is usually not a complicated bug. It is a signal that the object on the left side of the brackets is not the one you think it is.

FAQ

Why do I get TypeError: 'type' object is not subscriptable with list[str]?

The most common reason is that you are running Python 3.8 or earlier. In those versions, built-in collections like list and dict do not support the newer generic syntax in normal runtime code. Use List[str] from typing or upgrade to Python 3.9+.

How do I fix this error in Python 3.8?

Replace built-in generic annotations such as list[str], dict[str, int], and type[User] with List[str], Dict[str, int], and Type[User] from typing. If the error is not related to type hints, confirm that you are subscripting an instance instead of a class.

Does this error mean the object is not iterable?

No. Iteration and subscription are related but different concepts. An object can be iterable without supporting direct indexing, and a custom object can support obj[index] without behaving like a full iterator. This specific error only tells you that the square-bracket operation is not supported for the object you used.

Can I make my own class support MyClass[T]?

Yes. For type-driven generic classes, the usual solution is to inherit from typing.Generic. For custom runtime behavior, you can implement __class_getitem__(). If you want instance-level indexing such as obj[0], implement __getitem__() instead.

Interview Prep

Begin Your SQL, Python, and R Journey

Master 230 interview-style coding questions and build the data skills needed for analyst, scientist, and engineering roles.

Related Articles

All Articles