[Python-3000] Discussions with no PEPs (original) (raw)

Guido van Rossum guido at python.org
Mon Mar 12 22:27:59 CET 2007


On 3/12/07, Thomas Wouters <thomas at python.org> wrote:

On 3/8/07, Bill Janssen <janssen at parc.com> wrote: > There's an incomplete wiki page about a possible factoring of types at > http://wiki.python.org/moin/AbstractBaseClasses. The one thing that I have been unable to figure out (from that page, the python-dev/python-3000 messages on the subject and talking with Guido) is why ABCs are better than explicit interfaces like Twisted and Zope use. I think mixing in abstract baseclasses in the normal inheritance tree is a mistake, and if you have a separate tree, you really just have interfaces. I can think of a half dozen nagging warts that will pop up with using ABCs instead of interfaces, most of which I already griped to Guido about (but failed to convince him.)

And, to the contrary, I believe that if one mechanism can handle two requirements, that's better than having two separate mechanisms. I have a mandate to try and keep the language small.

- You can't take a third-party object, not participating in the ABC/interface craze, and say 'it inherits from this ABC' (which you can do for interfaces.)

In some cases, at least, this could be done by patching bases; not that I'm particularly advocating that. But I believe the last time we had this discussion this wasn't considered a particularly important requirement, as long as the standard library plays the ABC game consistently. I believe it is a requirement for zope/twisted interfaces mostly because the stdlib doesn't play their game.

- If the abstract classes hold actual attributes (as is the suggestion, as far as I can tell) rather than be completely empty, they can end up in the middle of the inheritance tree and mess up MRO.

I don't believe this. Can you show me an example? I would think that if done properly, the ABC defining a particular behavior would always be included as a base class for any class implementing that behavior, and thus it would automatically come in the MRO after all classes implementing the behavior, as it should. That seems entirely correct to me. Of course, there may be problems if one of the subclasses doesn't call its super method, but that problem can occur regardless of the use of ABCs.

- If the abstract classes are really completely empty, you need another mechanism for figuring out what a particular abstract class entails.

That's not what Bill or I are proposing, however. Take a look at the Py3k Lib/io.py module; it has several abstract base classes, esp. RawIOBase is close to my ideal use of ABC.

- You can't define any 'magic' on the abstract classes, things that are supposed to work on ABCs only, because any inherited class will of course automatically inherit the magic. If you use a magic metaclass for ABCs that works around that, people 'implementing' classes with their own metaclass will have to remember to subclass their metaclass from the ABC-magic-metaclass.

That's exactly what metaclasses are for, so I'm not sure what your problem is; obviously mixing metaclasses requires a convention for metaclasses to cooperate, but I imagine that unknowingly combining custom metaclasses with zope/twisted interfaces can also easily screw up.

- Because of the no-magic thing, you can't have the ABC do useful things, like asking it to verify if an implementation class has the right attributes or whether it can find an adapter for one ABC to another.

That's easily done as separate function though. Most meta-behavior is already done as separate functions; e.g. you write type(x), isinstance(x, C), issubclass(C, B) rather than using method notations for these. I don't see this as a disadvantage at all, unless you have suddenly got the OO-religion-disease (typically found in Java programmers migrating to Python and questioning len() :-).

- You can't un-inherit an ABC, ever. You can't inherit from a particular class to get some free implementation, but provide a slightly different (conflicting) interface. (Alright, probably not realistically a problem, but still.)

This should be done using proxies or wrappers or containment anyway, not inheritance.

- Mixing interface-definition and implementation like that makes it hard for new programmers to pick up the difference. It will be harder to explain the difference between 'dict' and 'Mapping' when they are both in the list of bases. How can you tell one from the other?

A naming convention? Documentation? The presence of unimplemented methods?

As far as I can see, there is tremendously little difference between ABCs and interfaces, at least the way Guido explained his ideas for ABCs to me.

Then why are you fighting them? :-)

The entirely Wiki page can be turned into a list of interfaces with a few textual edits. The only difference is that ABCs nestle in the normal MRO, which, in my eyes, is not a benefit at all. So... what's the actual benefit of ABCs over interfaces?

Well, to others, the nestling in the MRO is a feature, not a bug.

Please stay posted as I (slowly) work on a set of proposals for ABCs to go into the stdlib.

-- --Guido van Rossum (home page: http://www.python.org/~guido/)



More information about the Python-3000 mailing list