[pypy-dev] opcodes bundled in a class?

Armin Rigo arigo at tunes.org
Mon Aug 4 11:13:06 CEST 2003


Hello again,

On Mon, Jul 28, 2003 at 02:26:18PM +0200, holger krekel wrote:
> with the builtinrefactor branch i am at the point where i want
> to eliminate the 'appfile' concept alltogether in favour of 
> intermingling app-level and interp-level code directly.

Some issues we discussed (but couldn't conclude) over IRC with Holger about 
the details of:

def app_f(x):
  return x+1    # to be run at app-level, i.e. interpreted by PyPy
f = app2interp(app_f)

** Currently, this only works if app_f and f are methods of a class, whose
instances must have a 'space' attribute. You can then call 'self.f(w_x)',
where w_x is a wrapped object, and it automatically interprets app_f at
app-level in the object space given by 'self.space'. My objection to this
(beside the fact that it doesn't work for global functions) is that you must
tie 'self' to a particular object space in the first place, which is not
conceptually required for all interpreter-level objects. For example, I tend
to think about code objects as "literal objects" representing some source code
independently of any particular object space. So if we later want to run
several object spaces in a single PyPy instance it will probably come in the
way at some point.

The alternative is to ask that an interpreter-level call should *always*
specify 'space' explicitely (but still there is no 'space' argument in
'app_f', because it is implicit for all app-level code). So in the above
example we would not change the definition of 'app_f(x)' or 'f', but call it
with 'self.f(space, w_x)'.

** Visibility issues. Should anything that starts with 'app_' be visible at
app-level ? It means that even "internal" helpers would become visible to user
code (at least if the user can obtain a reference to the internal object). I
tend to think that it is not a problem; in Python itself everything is visible
by default (who uses the trick to make attributes and methods private to a
class?). If really we want to hide an app-level helper, we can use name
tricks:

def hidden_app_f(x):
  return x+1
f = app2interp(hidden_app_f)

This is invisible because it doesn't begin with 'app_', but still it is
app-level code because of the app2interp() wrapper.

** app2interp() wrappers vs. attribute magic: it would be easy (with a
__getattr__ or with metaclasses) to avoid the use of app2interp altogether:  
for any attribute 'app_foo' there would automatically be a corresponding
interpreter-level attribute 'foo = app2interp(app_foo)'. Against this idea are
arguments ranging from "this is magic" to "explicit is better than implicit".
Also, an explicit call to app2interp() is the perfect place to give additional
information if needed, e.g. "the argument 'x' must be an integer". This is
something that we will need anyway at least for the converse wrapper
interp2app():

class X:
  def f(self, space, w_obj, i):
    ...
  app_f = interp2app(f, typeof_i=int)

(just tentative syntax) publishing an app-level method 'f' that can be called
with two arguments (three including 'self'), saying that the interp-level
implementation expects the last argument to be an unwrapped integer (thus the
app-level call 'self.f("foo", "bar")' would give a TypeError).


A bientot,

Armin.


More information about the Pypy-dev mailing list