Hi Holger,

On Sat, May 07, 2005 at 10:17:36AM +0200, holger krekel wrote:
> > Log:
> > Replace the calls to xyz.__init__() with known calls to
> > XyzClass.__init__(xyz).  Avoids annotator surprizes.
> 
> When doing such (and other similarly non-obvious) changes 
> could you at least add a few lines in the RPython documentation 
> trying to pin down the "restriction"?  

It is difficult to describe in general terms.  It is not an RPython
restriction, so to say.  The log message should have put things in
context: it is only above the strange explicit-instance-creation points
that we have here and there in PyPy, e.g. in
Module.descr_module__new__():

        module = space.allocate_instance(Module, w_subtype)
        module.__init__(space, space.wrap('?'), space.w_None)
        return space.wrap(module)

The first line instantiates the class Module without actually calling
__init__().  Its purpose is that if w_subtype is a user subclass of the
<type 'module'>, allocate_instance() actually returns a fresh instance
of UserModule instead.  Anyway, the __init__ must be called explicitely.
(This is the only place where we call __init__() explicitely.)

The problem here, that is clear in hindsight, is that the annotator
assumes that 'module' can be an instance of any interp-level subclass of
Module -- as it be indeed: UserModule is a (automatically-defined)
subclass of Module, so 'module' can be an instance of one of these two
classes.  However, it cannot be an instance of LazyModule, although
LazyModule is also an interp-level subclass of Module.  This, the
annotator cannot know.  The problem is that LazyModule has a different
__init__() with a completely different signature.  This makes the
annotator unhappy (it crashes, complaining that we're calling a method
with the wrong number of arguments).

Hence the fix (this one done some time ago already) to call instead
explicitely the correct method:
        
        Module.__init__(module, space, space.wrap('?'), space.w_None)

Yesterday's fix was simply to apply the same fix systematically in all
places that use space.allocate_instance(), to avoid future problems when
more interp-level subclasses are introduced (as we did for
BuiltinFunction subclassing Function).

RPython is not easy to define simply, but -- more importantly -- it's
not easy at all to figure out when we actually followed RPython rules or
not, as this case shows.  The annotator needs to generate much better
error messages than it does currently.


A bientot,

Armin.
_______________________________________________
[email protected]
http://codespeak.net/mailman/listinfo/pypy-dev

Reply via email to