On Thu, May 23, 2013 at 10:10 PM, Antony Lee
Currently, the implementation of abstract methods is not possible outside of the class statement:
Good! Readability is very important; separating related logic is a bad idea. There may be times when patching something is the least of evils, but it certainly shouldn't be encouraged.
from abc import ABCMeta, abstractmethod class ABC(metaclass=ABCMeta): @abstractmethod def method(self): pass class C(ABC): pass
At this point, either C itself is also intended as abstract-only, or there is already an error.
C.method = lambda self: "actual implementation" C()
Much better to just create a new subclass of C. If that isn't isn't possible, then I suppose you do have to update __abstractmethods__. I usually write my "abstract" methods to either just pass (implement it if you want something to happen; safe to ignore it otherwise) or to return NotImplemented. The authors of ABC have gone out of their way to say "You MUST implement this." So requiring an extra "yes, I really meant that" step for code that violates the contract is not unreasonable.
I believe this behavior can be "fixed" (well, I don't know yet if this should actually be considered an error, and haven't actually tried to "fix" it) by defining ABCMeta.__setattr__ properly (to update __abstractmethods__ when necessary). What do you think?
It would work, but I don't think it would be a good idea. (1) What if the new implementation is still only a partial implementation, to used by super? Then the class *should* stay abstract. (2) Even if the new implementation of that method resolved the only enforced barrier, it still isn't clear that the class should change type. There are reasons to say "this class will never be instantiated". Removing that invariant is important enough that it should be an explicit choice, instead of an implicit side effect. -jJ