1

I came across the following (using Python 3.8.3):

from collections.abc import Iterable
from weakref import proxy

class Dummy:
   pass

isinstance(d := Dummy, Iterable)
# False (as expected)

isinstance(p := proxy(d), Iterable)
# True (why?!)

for _ in p:
    # raises TypeError
    pass

How could the proxy object pass the iterable-test?

1 Answer 1

2

It provides __iter__ in case the underlying type provides it. __iter__ must be implemented on the type to work, not the instance, so it can't conditionally define __iter__ without fragmenting into many different classes, not just a single proxy class.

Unfortunately, the Iterable test just checks if the class defines __iter__, not whether it works, and proxy doesn't know if it really works without calling the wrapped class's __iter__. If you want to check for iterability, just iterate it, and catch the TypeError if it fails. If you can't iterate it immediately, while it's subject to time-of-check/time-of-use race conditions, you could write your own simple tester that covers whether it can actually be iterated:

def is_iterable(maybeiter):
    try:
        iter(maybeiter)
    except TypeError:
        return False
    else:
        return True
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.