Issue 19022: Improve handling of type.abstractmethods descriptor (original) (raw)

Issue 10006 pointed out that attempting to access object.abstractmethods raises AttributeError. The solution was to ensure type.abstractmethods also raises AttributeError.

This is thoroughly confusing, since the name is clearly visible in the output of dir(type). While it's technically legal for a descriptor to always raise AttributeError, breaking the following typical assumed invariant is highly dubious:

all(hasattr(obj, x) for x in dir(obj))

I see three main alternatives for improving the situation:

  1. Make abstractmethods a read-only descriptor that returns something meaningful (like a frozenset(), the same as you get if you inherit from abc.ABCMeta without defining any abstract methods)

  2. Throw a better exception message that explains the broken invariant rather than the generic "AttributeError with attribute name" that is currently thrown.

  3. Implement type.dir to filter out the uncooperative descriptor

I like the 3rd alternative the most. It seems to me, that abstractmethods is currently an undocumented implementation detail of ABCs. The 1st alternative would cause every type to have an empty abstractmethods (which is technically correct, but probably not very useful). It seems to me that the 2nd alternative would not help very much in the original problem mentioned in (automatically looking up every name found in dir). So I think, that the best would be to fix type.dir this way. (Although, if we really want to document and use abstractmethods on every type, then of course we should do the 1st alternative.)