Python
generator
object
type checking
programming

How to check if an object is a generator object in Python?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

If you specifically want to know whether an object is a generator object, the most direct check is against types.GeneratorType or inspect.isgenerator. The important distinction is that not every iterator is a generator, and not every callable that produces generators is itself a generator object.

Core Sections

What counts as a generator object

A generator object is what you get after calling a generator function. The function contains yield; the returned object implements lazy iteration and maintains execution state between yields.

python
1def numbers():
2    yield 1
3    yield 2
4
5gen = numbers()
6print(gen)

Here numbers is a generator function, while gen is the generator object.

The direct check with types.GeneratorType

If you need a strict runtime test, use types.GeneratorType.

python
1import types
2
3def numbers():
4    yield 1
5
6gen = numbers()
7data = [1, 2, 3]
8
9print(isinstance(gen, types.GeneratorType))   # True
10print(isinstance(data, types.GeneratorType))  # False

This is the clearest answer when the question is literally "is this object a generator object?"

inspect helpers and what they mean

The inspect module exposes related helpers, but they test different things.

python
1import inspect
2
3def numbers():
4    yield 1
5
6gen = numbers()
7
8print(inspect.isgenerator(gen))           # True
9print(inspect.isgeneratorfunction(numbers))  # True

Use:

  • 'inspect.isgenerator(obj) for generator objects'
  • 'inspect.isgeneratorfunction(func) for functions defined with yield'

Those are not interchangeable.

Generator versus iterator

A generator is always an iterator, but an iterator is not always a generator. Custom iterator classes implement __iter__() and __next__() without involving yield.

python
1class Countdown:
2    def __init__(self, start):
3        self.current = start
4
5    def __iter__(self):
6        return self
7
8    def __next__(self):
9        if self.current == 0:
10            raise StopIteration
11        self.current -= 1
12        return self.current + 1
13
14item = Countdown(3)

item is an iterator, but isinstance(item, types.GeneratorType) is False. That distinction matters if your code depends on generator-specific behavior rather than general iteration.

Async generators are different again

Python also has async generators created with async def and yield. They are not regular generator objects and should be checked separately.

python
1import inspect
2
3async def async_numbers():
4    yield 1
5
6agen = async_numbers()
7print(inspect.isasyncgen(agen))  # True

If your code handles both sync and async lazy sequences, do not use only GeneratorType and assume you covered everything.

Pick the narrowest test that matches your goal

Use these rules:

  • If you need "anything iterable", use iter(obj) in a try block.
  • If you need "any iterator", test for collections.abc.Iterator.
  • If you need a real generator object, use types.GeneratorType or inspect.isgenerator.

That keeps the type check aligned with the actual behavior your function requires.

Another practical benefit of being explicit is debugging. If a function promises a generator but returns a list or custom iterator instead, a strict generator check can catch interface drift early in tests.

Common Pitfalls

  • Checking whether a generator function is a generator object before calling it.
  • Treating all iterators as generators and then relying on generator-specific assumptions.
  • Consuming the generator while testing behavior and then forgetting it is now partially exhausted.
  • Ignoring async generators when your code handles asynchronous workflows.
  • Using overly broad type checks when a simple iter(obj) capability check would be enough.

Summary

  • A generator object is the result of calling a generator function.
  • Use isinstance(obj, types.GeneratorType) or inspect.isgenerator(obj) for a direct check.
  • 'inspect.isgeneratorfunction tests the function definition, not the returned object.'
  • Not every iterator is a generator, so choose your type test carefully.
  • Consider async generators separately if your code uses async def and yield.

Course illustration
Course illustration

All Rights Reserved.