The reason is that __iter__
always has to be an instance method. The Enum
base class has no __iter__
defined on it. Its metaclass EnumMeta
does.
Remember that enumeration members are also attributes of the class. The type of Enum
implements the iterable protocol. Specifically, EnumMeta.__iter__
returns the members of the class (in definition order).
That is the reason hasattr(Enum, "__iter__")
returns True
. That attribute is defined by its (meta) class.
In general, you should be careful in what you assume to be reflected in your autospecced mock objects. The more "exotic" your attributes/methods are, the less likely the spec is to be correct because it relies on introspection. When in doubt, I would suggest explicitly creating mock attributes as needed, instead of relying on autospec. The following is a passage from a chapter on Autospeccing in unittest.mock
:
[Autospeccing] isn't without caveats and limitations however, which is why it is not the default behaviour. In order to know what attributes are available on the spec object, autospec has to introspect (access attributes) the spec. As you traverse attributes on the mock a corresponding traversal of the original object is happening under the hood.
Currently, create_autospec
relies on dir
to inspect what attributes should be created/mocked. This alone brings a bunch of limitations with it.