Author lukasz.langa
Recipients ecatmur, gvanrossum, lukasz.langa, rhettinger
Date 2013-06-29.17:24:37
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1372526677.94.0.12961643988.issue18244@psf.upfronthosting.co.za>
In-reply-to
Content
Looks like the priority ordering you mention is not yet documented
anywhere. It definitely makes sense but I'd like to take a step back for
a moment to consider the following questions:

1. What additional functionality do our users get with this ordering? In
   other words, what purpose does this new ordering have?

   Apart from solving the conflict we're discussing, I can't see any.

2. What disadvantages does this ordering bring to the table?

   I think that simplicity is a feature. This ordering creates
   additional complexity in the language.

   Firstly, there is currently no obvious way for users to distinguish
   between implicit subclassing (via implementation) or subclassing by
   `abc.register()`. This creates the dangerous situation where
   backwards incompatibility introduced by switching between those ABC
   registration mechanism is nearly impossible to debug.  Consider an
   example: version A of a library has a type which only implicitly
   subclasses an ABC. User code with singledispatch is created that
   works with the current state of things. Version B of the same library
   uses `ABC.register(Type)` and suddenly the dispatch changes without
   any way for the user to see what's going on.  A similar example with
   explicit subclassing and a different form of registration is easier
   to debug, but not much, really.

   Secondly, it creates this awkward situation where dispatch for any
   custom `MutableMapping` can be different from the dispatch for
   `dict`.  Although the latter is a `MutableMapping` "only" by means of
   `MutableMapping.register(dict)`, in reality the whole definition of
   what a mutable mapping is comes from the behaviour found in `dict`.
   Following your point of view, dict is less of a mutable mapping than
   a custom type subclassing the ABC explicitly. You're saying the user
   should "respect the choice of its author" but it's clearly suboptimal
   here. I strongly believe I should be able to swap a mutable mapping
   implementation with any other and get consistent dispatch.

   Thirdly, while I can't support this with any concrete examples,
   I have a gut feeling that considering all three ABC subclassing
   mechanisms to be equally binding will end up as a toolkit with better
   composability. The priority ordering on the other hand designs
   `abc.register()` and implicit subclassing as inferior MRO wannabes.

   Last but not least, the priority ordering will further complicate the
   implementation of `functools._compose_mro()` and friends. While the
   complexity of this code is not the reason of my stance on the matter,
   I think it nicely shows how much the user has to keep in her head to
   really know what's going on. Especially that we only consider this
   ordering to be decisive on a single interitance level.

3. Why is the ordering MRO -> register -> implicit?

   The reason I'm asking is that the whole existence of `abc.register()`
   seems to come from the following:

   * we want types that predate the creation of an ABC to be considered
     its subclasses;

   * we can't use implicit subclassing because either the existence of
     methods in question is not enough (e.g. Mapping versus Sequence);
     or the methods are added at runtime and don't appear in __dict__.

   Considering the above, one might argue that the following order is
   just as well justified: MRO -> implicit -> register. I'm aware that
   the decision to put register first is because if the user is unhappy
   with the dispatch, she can override the ordering by registering types
   which were implicit before. But, while I can register third-party
   types, I can't unregister any. In other words, I find this ordering
   arbitrary.

I hope you don't perceive my position as stubborn, I just care enough to
insist on this piece of machinery to be clearly defined and as simple as
possible (but not simpler, sure).
History
Date User Action Args
2013-06-29 17:24:38lukasz.langasetrecipients: + lukasz.langa, gvanrossum, rhettinger, ecatmur
2013-06-29 17:24:37lukasz.langasetmessageid: <1372526677.94.0.12961643988.issue18244@psf.upfronthosting.co.za>
2013-06-29 17:24:37lukasz.langalinkissue18244 messages
2013-06-29 17:24:37lukasz.langacreate