Method Object Is Not Iterable | Fix It In Minutes

The “method object is not iterable” error means your code tried to loop over a method itself, not the data it returns.

You’ll see this message when Python expects something it can step through item by item, yet it receives a method reference. It often shows up in a for loop, an in check, or a call like list(...). The fix is usually small, but it helps to know why the runtime complains so you can spot it fast next time.

Most fixes take one edit and a quick rerun alone.

This guide shows the patterns that trigger the error, how to confirm the real object, and how to fix it. A quick table and checklist are near the end.

Why This Error Shows Up

Python can loop only over an iterable: something that can produce items when you call iter(obj). Lists, tuples, strings, dicts, sets, and generators qualify. A method object does not.

When your code says for x in thing, Python calls iter(thing). If thing is a method, iteration fails and you see this error.

It’s a small slip, not a mystery.

Many developers hit the same wall with built-ins that look like containers but are actually methods, such as dict.items, dict.keys, and dict.values. It’s easy to forget the parentheses when you’re moving quickly, or when an autocomplete menu inserts a method name and you keep typing.

Method Object Is Not Iterable Fixes That Work

This is the fastest way to get moving again. Start with the missing-parentheses check, then confirm what the method returns, then adjust the loop. If you follow these steps in order, you’ll usually fix the bug in one pass.

  1. Add The Parentheses — If you wrote a method name inside a loop, call it: for x in obj.method(): instead of for x in obj.method:.
  2. Print The Type — Right before the failing line, run print(type(value)) to confirm you’re looping over a list-like object, not a method reference.
  3. Check The Return Value — If the method returns None, your loop will fail in a different way next, so adjust the method to return an iterable or loop over the right attribute.
  4. Pick The Correct Attribute — Many objects have both a method and a data field with similar names. Use the one that holds the actual items.
  5. Call The Correct Dict View — Use my_dict.items(), my_dict.keys(), or my_dict.values(), not the method object.

In day-to-day code, the missing call is the most common cause. A lot of reports for this TypeError come from trying to loop over a method like list.extend or a custom method that was meant to return a list, but was never called.

Spot The Real Object You’re Looping Over

When you’re staring at a traceback, it’s tempting to edit the line that crashed and re-run until it works. That can drag on. A quicker path is to confirm the exact object on the right side of in. Your goal is to answer two questions: is it callable, and if called, does it return something iterable?

Use A Tiny Probe

Drop a probe line right above the crash. Keep it simple, then delete it after you’re done.

  • Show The Valueprint(value) can reveal you’re holding a bound method like .
  • Show The Typeprint(type(value)) will say method, builtin_function_or_method, or a custom type.
  • Check Callabilityprint(callable(value)) returns True for methods and functions.

If the object prints as a bound method, you’re not holding the data. You’re holding the tool that produces the data. In that case, call it and inspect the result. If the call needs arguments, pass the same arguments your program uses in the normal path.

Confirm What The Method Returns

Even after you add parentheses, the loop can still break if the method returns a single object, returns None, or returns a string when you expected a list. A method returning a string is iterable, but it iterates over characters, so the loop will “work” while still doing the wrong thing. A one-line print saves you from that trap.

  1. Call It Once — Assign the result: items = obj.method().
  2. Inspect The Result — Print type(items) and, if it’s small, print the items too.
  3. Loop Over The Result — Use for x in items: after you confirm it’s the right shape.

This pattern also helps with frameworks and SDKs where an attribute that looks like a list is actually a property returning a method-like object. Treat it the same way: inspect, then loop.

Common Triggers And Clean Repairs

There are a handful of patterns that cause this error again and again. Once you can name them, you can fix them without thinking too hard. The table below maps typical code to the usual repair.

What You Wrote What It Means Fix
for x in d.items: You referenced the method, not its output. for x in d.items():
if k in obj.get: You tested membership against a method object. if k in obj.get(...): or check the right container.
list(my_list.append) You tried to convert a method into a list. Call it, or loop over my_list.
for x in foo.bar bar is a method with no call. for x in foo.bar():

Forgetting Parentheses After A Dict Method

This one is classic: d.items is a method, while d.items() is a view you can iterate over. The same applies to keys() and values(). When you see the error near dict code, scan the line for a dict method name without parentheses. Fixing that single character pair usually clears it.

Accidentally Storing A Method Instead Of Its Result

This happens when you assign a method to a variable, planning to call it later, then you loop over that variable by mistake. It can also happen when you append a method reference into a list. Then you end up with a list full of methods, and a later loop fails when it tries to treat one of those methods like data. Stack traces can point to the later loop, so it helps to check where the list was built.

  1. Scan Assignments — Search for = obj.method with no parentheses.
  2. Scan Appends — Search for .append(obj.method) and confirm that’s what you meant.
  3. Store Results — Change it to = obj.method() or append obj.method().

Shadowing A List With A Method Name

In larger files, names collide. You might start with items = [], then later write items = obj.items by accident. Now items is a method, and the loop breaks. If you see the error after a refactor, search for the variable name and see where it last changed type.

Iterating Over A Property That Returns A Method

Some libraries expose attributes that are callable objects. They look like fields, so you try to loop over them. If the attribute is callable, treat it like a method: call it, then loop over the returned value. When the library docs are vague, the probe steps from earlier are the quickest way to learn what you’re dealing with.

Across these cases, the core rule stays the same: loop over data, not the callable that creates the data. Many guides point to this exact cause and repair.

Make Your Own Objects Iterable

Sometimes you’re on the other side of the error. Your code is clean, you’re calling the right method, yet the return value is a custom object that doesn’t allow iteration. When that happens, you can either return a built-in container, or you can make your object follow Python’s iteration protocol.

An object becomes iterable when it implements __iter__() and returns an iterator. The iterator then yields items through __next__(). Some objects also work with __getitem__() and integer indexes, but __iter__() is the clearest approach for new types.

Return A Built-In Container When You Can

If your class is mainly a wrapper over a list, you can keep things simple by returning the underlying list from a method. That keeps the calling code clean and avoids surprises. It also makes debugging easier because the loop runs over a familiar type.

  • Expose A List — Store items in self._items and return that list when asked.
  • Expose A Generator — Yield items from a method using yield so the caller can loop without building a list.

Implement __iter__ For Natural Loops

If you want your object to behave like a collection, adding __iter__ makes it feel native in a loop, in sum(), in any(), and in many library calls. Keep the implementation small and predictable. A common pattern is to return an iterator from an internal list.

  1. Store Items In One Place — Keep a list or tuple as the single source of truth.
  2. Return Its Iterator — In __iter__, return iter(self._items).
  3. Test With iter() — Run iter(obj) and a short loop to confirm it yields what you expect.

When __iter__ is missing or set to None, iter(obj) raises a TypeError, which is the same family of signal you’re seeing in this article. The docs spell out how iteration hooks work and when Python raises that error.

A Fast Checklist Before You Re-Run

Once you fix the crash, it’s worth spending thirty seconds to make sure you didn’t trade one bug for another. These checks keep the loop correct, not just error-free.

  • Re-Read The Right Side Of in — Confirm the thing after in is data, not a method name.
  • Confirm The Result Shape — If you called a method, print the returned value once and confirm it holds the items you want.
  • Watch For String Loops — If a method returns a string, your loop will run character by character, which can look like a logic bug.
  • Check None Returns — If the method returns None, fix the method or loop over a different value.
  • Rename Colliding Variables — If a variable name matches a method name, pick a clearer name to avoid shadowing.
  • Write A Tiny Test — Run a short test that builds the object and iterates it once, so the fix stays in place.

If you came here after seeing the phrase “method object is not iterable” in a traceback, the steps above should get you to a stable fix. If you still see the message, follow the probe method again and work backward to where the method reference got into your variable. That’s usually the real bug.

You can also keep one mental rule in your pocket: if it prints like , it’s not the data. Call it, then loop. That single habit prevents most repeats of this error.

Sources used while drafting (keep or remove):
https://docs.python.org/3.9/reference/datamodel.html?highlight=iterator
https://realpython.com/python-iterators-iterables/
https://stackoverflow.com/questions/68673677/python-typeerror-method-object-is-not-iterable
https://bobbyhadz.com/blog/python-typeerror-builtin-function-or-method-object-is-not-iterable