[Python-Dev] Comments2: PEP 252, PEP 253 and jython issues
Guido van Rossum
guido@python.org
Fri, 24 Aug 2001 13:36:59 -0400
[SP]
> > > The problem is that with the new mro possibly independently C
> > > defined things get interleaved with Python level code, so I
> > > imagine that the effect should be a bit disciplined ...
> >
> [GvR]
> >
> > I don't expect this to happen regularly. if you count on this I
> > think you're on really thin ice.
[SP]
> No I'm not counting on that, I'm worried about this scenario
>
> A subclasses object and redefines __getattr__
> B subclasses list
>
> then class C(B,A): ...
>
> will have the following mro:
>
> C B list A object
>
> In Jython codebase hypothetically but possibly list could contains
> calls like:
>
> __getattr__(...)
> and super.__getattr__
This is Java code, right?
> now A is in between list and object: what is the right thing here?
Just say that this is what happens. The MRO is inconsistent in this
case.
> I don't expect or invite users to do that, but your rules allow A to
> end up in that position in the mro, your philosophy seems to be
> this is thin ice and so let it be ...
Exactly.
> > > I saw that list_ass_slice calls list_slice directly, is that OK?
> >
> > It's certainly safe -- any subclass of list will share the same
> > structure lay-out (this is enforced by the subclassing machinery) so
> > the list_slice call will find the object properly inititialized.
> >
> > There are lots of places where the C code doesn't bother to look
> > for overridden methods -- the PyDict_* API is a common example. I
> > have no intention of fixing this.
> Fine with that, but ...
>
> > > Other OO languages like Smalltalk, Self, or Java allow only to
> > > define primitives or single methods to add lowel-level
> > > functionality, they don't try to allow subtyping at that level,
> > > the previous scenario in Python where you could define just
> > > opaque types, and in particular your C code never/normally got
> > > interleaved with Python
> > > behaviour was on that line.
> >
> > Well, if you like that better, maybe I should remove the
> > instructions for subclassing at the C level? :-)
> No, I'm just saying that you are moving from a world were you had
> documentable C black-boxes and clear Python semantics, to a world
> where (but you say that would be rare) you can have Python code
> whose behaviour depends on very fine-grained decision inside C code.
I would recommend that C programmers not indulge in this. They
should continue to write C types that can be treated as black boxes.
The C-level single inheritance is best seen as code sharing.
> On one side your rules make it very easy to interleave Python and C
> code in the mro, on the other hand I agree that will be rarely done
> by the wary user because it's just surprise-land, don't know about
> the unwary ...
On the third hand, if a C programmer *wants* to write a class with the
proper cooperative super calling, they can do so, it's just a bit
clumsy. Should I provide a C API to make this easier? I doubt that
it will be used much. If there's demand, it can be added later.
> > My intention is to make the maximum number of different paradigms
> > usable in Python. You can do cooperative multiple inheritance,
> > but only of all your classes are designed with cooperation in
> > mind. If some class uses C-level (or Java-level) inheritance and
> > is not written cooperatively, you have to be a little careful
> > using it as a base class in a cooperatively written class. I
> > don't want to enforce cooperative coding at the Python level
> > either: the "BaseClass.method(self, args)" approach is still
> > valid, but you have to beware of the consequences.
> Do you feel is that a good thing, especially if new-style classes become
> the default?
Time will tell. I expect that some people will design vast
cooperative class hierarchies. I expect that other people will stick
to single inheritance or very simple-minded uses of multiple
inheritance (for example, they could use the mix-in pattern that was
about the only sensible use of multiple inheritance with classic
classes).
Anyway, I expect new classes won't become the default until Python
3.0.
> It is not a rethoric question, Python is becoming a little single
> dispatch CLOS with a MOP, descriptors etc but CLOS has only
> next-method and strange beasts like method combinators and don't
> allow to interleave low-level coded behaviour in the class mro.
Nothing new: classic classes already allow you to cheat or mess up in
various ways by not calling your superclass method.
> > > At worst you could say that you allow subtyping but not code
> > > sharing, but then even a C method for an object should be very
> > > careful using another overridable method of the very same
> > > object.
> >
> > I definitely have to support code sharing. I think subclassing at
> > the C level is useful to create variations of built-in objects
> > with additional properties, e.g. numbers with additional
> > operations or formatting parameters, dictionaries with certain
> > restrictions on the keys, etc. I don't think such subclasses
> > should be used in complex multiple inheritance lattices.
> Better to enforce that?
Why? I can think of situations where you have a MRO like this:
C list B object
but where B doesn't override anything that list might use. In fact,
this is the typical mix-in situation. I don't want to forbid this.
> > > OK you could say: that's C level, everybody should care for
> > > herself, but with Java we cannot do the same.
> >
> > Why not?
> Because users would like writing Jython types to become easier,
Do you mean writing Jython types in Java, or in Python?
> and be possible using Java OOP model, without surprises, or
> undocumented subtlities, any deviation is an hard sell because Java
> has already an OOP model.
Recommend strongly that they stick to single inheritance for types
implemented in Java -- that should do the trick.
> > > > > It would make sense to use Java subclassing to implement
> > > > > type subclassing, at least at layout level this does not
> > > > > clash with the multiple inheritance rule in best_base.
> > > >
> > > > So you would rule out multiple inheritance of types? Fine
> > > > with me, but you may regret this a few yearsfrom now (when we
> > > > all code multiple inheritance all the time :-).
> >
> > > No it is ruled out at Java level, not Jython level.
> > > But it is not also ruled out in CPython at C level?
> >
> > Mostly because I don't provide a way to create multiple base
> > classes. That would not be hard to add though -- if there's
> > demand.
> But this is a path that Jython could not follow.
Correct -- another reason why it's not a good idea to encourage this.
What you could do though, even in Jython, is simulate everything that
goes on in a class statement: build your own dict, populate it with
function objects, and then call type.__new__(name, bases, dict).
Voila, instant class. :-)
> > > see above.
> > >
> > > > I propose that you just try to live with this.
> >
> > > Related e.g. to Zope porting projects there have been a lot of
> > > pressure on jython-dev regarding how to code new types and
> > > metaclasses, A Jython type writer expect to be able to use Java
> > > naturally (i.e. use inheritance), for that, so the situation
> > > isn't that easy, is not even easy with the current codebase,
> > > because given the new mro one can even put some Python behaviour
> > > between:
> > >
> > > PyList PythonLevelCode and PyObject :-( (*)
> >
> > Just sa no. :-)
> See above.
Sorry, my context stack just overflowed. If this is still an issue,
please start over. :-)
[snip]
> > > I had the same idea because this would make my life easier.
> >
> > Sounds good to me.
> >
> > > A problem: some of the Zope porters reported that there are
> > > classes that inherits from more than a single ExtensionClass in
> > > Zope :-( don't know if that is true. (**)
> >
> > Me neither. But the problem is probably shallow -- Zope mostly
> > uses mixins of various sorts, so these classes probably don't
> > override stuff -- they just define new methods. (I haven't looked
> > at what it would take to replace ExtensionClass with the new
> > metaclasses, but that's definitely on the agenda.)
> >
> > > > don't know if we should enforce this or just warn about it in
> > > > the documentation.
> >
> > > It would make our (jython-dev) life easier and avoid some
> > > impredictable problem even with CPython and code sharing, but
> > > see previous note (**)
> >
> > So enforce it and see how it turns out in practice.
> It's probably the best solution, at least for Jython,
> and could even make sense for CPython (see above points)
Good. We seem to agree.
> > > > I don't want to force you to call a cooperative super method
> > > > at the Java level -- it would be very slow, I suspect...
> >
> > > Yes ... very slow and we would have to use that also at the very
> > > core of the hierarchy, see (*) but the problem is more
> > > complicated, in Java given three classes
> > >
> > > C extends B extends A
> > > and a method m
> > > C.m overrides B.m overrides A.m
> > >
> > > there is not direct way (even using reflection)
> > > to apply B.m behaviour to a C object, unless
> > > the programmer has left some hook in C using super
> > > or in B ( a method B_m e.g.).
> >
> > I guess C.m has to call super.m to invoke B.m, right?
> Yup.
> > Does this mean that the following can't be made to work?
> >
> > class C(list):
> > def add_spam(self):
> > return list.append(self, "spam")
> >
> > It's legal Python (although in general questionable style of course).
> Yes, it can be made to work (it already works for Java subclassing
> and type subclassing would be some flavor of that), but the point is
> that your Java stuff should be at the top of the mro. Because then
> you can insert some hooks using super.
>
> regards.
I hope this discussion so far has been helpful -- I have to pack for
my trip and will soon be off to San Francisco until next Wednesday.
--Guido van Rossum (home page: http://www.python.org/~guido/)