In Python, there is an ABC for collections that matches all builtin container classes:
>>> isinstance(list(), collections.abc.Collection)
True
>>> isinstance(set(), collections.abc.Collection)
True
>>> isinstance(dict(), collections.abc.Collection)
True
However, it also matches immutable objects that happen to be sized and iterable:
>>> isinstance(str(), collections.abc.Collection)
True
>>> isinstance(bytes(), collections.abc.Collection)
True
Is there a good way to test for the first, but not the second group?
I have considered also testing for collections.abc.Hashable (any hashable object is non-mutable and is thus not a "container" in a normal sense), but this feels hacky and I'm not sure if this is a semantically correct solution.
I need this because I'm writing a metaprogramming hook that will transform function argument and class field defaults into factories. I need a way to match all classes that will normally result in "footguns" when used as default arguments/default field values.