[pypy-svn] r9160 - in pypy/branch/dist-interpapp/pypy: interpreter interpreter/test objspace/flow objspace/std
arigo at codespeak.net
arigo at codespeak.net
Sat Feb 12 15:13:43 CET 2005
Author: arigo
Date: Sat Feb 12 15:13:43 2005
New Revision: 9160
Modified:
pypy/branch/dist-interpapp/pypy/interpreter/baseobjspace.py
pypy/branch/dist-interpapp/pypy/interpreter/gateway.py
pypy/branch/dist-interpapp/pypy/interpreter/pyopcode.py
pypy/branch/dist-interpapp/pypy/interpreter/test/test_appinterp.py
pypy/branch/dist-interpapp/pypy/interpreter/test/test_gateway.py
pypy/branch/dist-interpapp/pypy/objspace/flow/flowcontext.py
pypy/branch/dist-interpapp/pypy/objspace/std/dicttype.py
pypy/branch/dist-interpapp/pypy/objspace/std/listtype.py
pypy/branch/dist-interpapp/pypy/objspace/std/slicetype.py
Log:
First try at gateway.applevel("""....""").
Modified: pypy/branch/dist-interpapp/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/branch/dist-interpapp/pypy/interpreter/baseobjspace.py (original)
+++ pypy/branch/dist-interpapp/pypy/interpreter/baseobjspace.py Sat Feb 12 15:13:43 2005
@@ -279,38 +279,28 @@
return statement.exec_code(self, w_globals, w_locals)
def appexec(self, posargs_w, source):
- """ return value from executing given source at applevel with
- the given list of wrapped arguments. The arguments are
- directly set as the fastscope of the underlyingly executing
- frame. No Argument parsing is performed at this point.
- Consider using gateway.appdef() if you need default
- arguments.
- """
- pypyco = self.loadfromcache(source, buildpypycode, self._codecache)
- frame = pypyco.create_frame(self, self.w_apphelper_globals)
- frame.setfastscope(posargs_w)
- return frame.run()
+ """ return value from executing given source at applevel.
+ The source must look like
+ '''(x, y):
+ do_stuff...
+ return result
+ '''
+ """
+ w_func = self.loadfromcache(source, buildappexecfunc, self._codecache)
+ args = Arguments(self, posargs_w)
+ return self.call_args(w_func, args)
-def buildpypycode(source, space):
+def buildappexecfunc(source, space):
""" NOT_RPYTHON """
# XXX will change once we have our own compiler
from pypy.interpreter.pycode import PyCode
from pypy.tool.pytestsupport import py # aehem
- argdecl, source = source.split(':', 1)
- argdecl = argdecl.strip()
- i = argdecl.find('(')
- if i >0:
- funcname, argdecl = argdecl[:i], argdecl[i:]
- else:
- funcname = 'anon'
- if not argdecl.startswith('(') or not argdecl.endswith(')'):
- raise SyntaxError("incorrect appexec header\n%s" % source)
- source = py.code.Source(source)
- source = source.putaround("def %s%s:" % (funcname, argdecl))
- d = {}
- exec source.compile() in d
- newco = d[funcname].func_code
- return PyCode(space)._from_code(newco)
+ source = source.lstrip()
+ assert source.startswith('('), "incorrect header in:\n%s" % (source,)
+ source = py.code.Source("def anonymous%s\n" % source)
+ w_glob = space.newdict([])
+ space.exec_(source.compile(), w_glob, w_glob)
+ return space.getitem(w_glob, space.wrap('anonymous'))
## Table describing the regular part of the interface of object spaces,
## namely all methods which only take w_ arguments and return a w_ result
Modified: pypy/branch/dist-interpapp/pypy/interpreter/gateway.py
==============================================================================
--- pypy/branch/dist-interpapp/pypy/interpreter/gateway.py (original)
+++ pypy/branch/dist-interpapp/pypy/interpreter/gateway.py Sat Feb 12 15:13:43 2005
@@ -592,87 +592,61 @@
# and now for something completly different ...
#
-pendingapphelpers = []
-def appdef(source):
- """ NOT_RPYTHON """
+class applevel:
+ """A container for app-level source code that should be executed
+ as a module in the object space; interphook() builds a static
+ interp-level function that invokes the callable with the given
+ name at app-level."""
+
+ def __init__(self, source):
+ "NOT_RPYTHON"
+ self.code = py.code.Source(source).compile()
+
+ def getdict(self, space):
+ return space.loadfromcache(self, applevel.builddict,
+ space._gatewaycache)
+
+ def builddict(self, space):
+ "NOT_RPYTHON"
+ w_glob = space.newdict([])
+ space.exec_(self.code, w_glob, w_glob)
+ return w_glob
+
+ def interphook(self, name):
+ "NOT_RPYTHON"
+ def appcaller(space, *args_w):
+ w_glob = self.getdict(space)
+ w_func = space.getitem(w_glob, space.wrap(name))
+ args = Arguments(space, args_w)
+ return space.call_args(w_func, args)
+ return hack.func_with_new_name(appcaller, name)
+
+
+def appdef(source, applevel=applevel):
+ """ NOT_RPYTHON: build an app-level helper function, like for example:
+ myfunc = appdef('''myfunc(x, y):
+ return x+y
+ ''')
+ """
from pypy.interpreter.pycode import PyCode
if not isinstance(source, str):
source = str(py.code.Source(source).strip())
assert source.startswith("def "), "can only transform functions"
source = source[4:]
- funcdecl, source = source.strip().split(':', 1)
- funcname, decl = funcdecl.split('(', 1)
- funcname = funcname.strip() or 'anonymous'
- decl = decl.strip()[:-1]
- wfuncdecl, wfastscope, defaulthandlingsource = specialargparse(decl)
-
- # get rid of w_
- fastscope = ", ".join([x.strip()[2:] for x in wfastscope.split(',')])
-
- # SOME MESS AHEAD !
- # construct the special app source passed to appexec
- appsource = py.code.Source(source).strip().putaround("%s(%s):" % (funcname, fastscope))
- sourcelines = ["def %(funcname)s(space, %(wfuncdecl)s):" % locals(),
- " while pendingapphelpers:",
- " ihook = pendingapphelpers.pop()",
- " space.setitem(space.w_apphelper_globals,",
- " space.wrap(ihook.name), space.wrap(ihook))", ]
- sourcelines.extend(defaulthandlingsource.indent().lines)
- sourcelines.append(
- " return space.appexec([%(wfastscope)s], '''" % locals())
- for line in appsource.indent().indent().lines:
- line = line.replace("\\", r"\\").replace("'", r"\'")
- sourcelines.append(line)
- sourcelines.append("''')")
- source = py.code.Source()
- source.lines = sourcelines
- #print str(source)
- glob = { 'pendingapphelpers' : pendingapphelpers }
- exec source.compile() in glob
- func = glob[funcname]
- pendingapphelpers.append(interp2app(func, func.func_name))
- return func
-
-def specialargparse(decl):
- """ NOT_RPYTHON """
- wfuncargs = []
- wfastnames = []
- defaultargs = []
- for name in decl.split(','):
- if not name.strip():
- continue
- name = "w_%s" % name.strip()
- if '=' in name:
- name, value = name.split('=')
- wfastnames.append(name)
- defaultargs.append((name, value))
- name += "=None"
- else:
- assert not defaultargs, "posarg follows defaultarg"
- wfastnames.append(name)
- wfuncargs.append(name)
-
- # now we generate some nice code for default arg checking
- # (which does not imply that the code doing it is nice :-)
- defaulthandlingsource = py.code.Source()
- while defaultargs:
- name, value = defaultargs.pop(0)
- defaulthandlingsource = defaulthandlingsource.putaround("""\
- if %s is None:
- %s = space.wrap(%s)
- """ % (name, name, value), "")
- wfuncdecl = ", ".join(wfuncargs)
- wfastdecl = ", ".join(wfastnames)
- return wfuncdecl, wfastdecl, defaulthandlingsource
-
-app2interp = appdef
-
-# for app2interp_temp (used for testing mainly) we can use *args
-class app2interp_temp(object):
- def __init__(self, func):
- """ NOT_RPYTHON """
- self.appfunc = appdef(func)
-
- def __call__(self, space, *args_w, **kwargs_w):
- """ NOT_RPYTHON """
- return self.appfunc(space, *args_w, **kwargs_w)
+ p = source.find('(')
+ assert p >= 0
+ funcname = source[:p].strip()
+ source = source[p:]
+ return applevel("def %s%s\n" % (funcname, source)).interphook(funcname)
+
+app2interp = appdef # backward compatibility
+
+
+# app2interp_temp is used for testing mainly
+class applevel_temp(applevel):
+ def getdict(self, space):
+ return self.builddict(space) # no cache
+
+def app2interp_temp(func):
+ """ NOT_RPYTHON """
+ return appdef(func, applevel_temp)
Modified: pypy/branch/dist-interpapp/pypy/interpreter/pyopcode.py
==============================================================================
--- pypy/branch/dist-interpapp/pypy/interpreter/pyopcode.py (original)
+++ pypy/branch/dist-interpapp/pypy/interpreter/pyopcode.py Sat Feb 12 15:13:43 2005
@@ -736,9 +736,6 @@
cls.dispatch_table = dispatch_table
- gateway.importall(locals()) # app_xxx() -> xxx()
-
-
### helpers written at the application-level ###
# Some of these functions are expected to be generally useful if other
# parts of the code needs to do the same thing as a non-trivial opcode,
@@ -747,6 +744,98 @@
# There are also a couple of helpers that are methods, defined in the
# class above.
+app = gateway.applevel('''
+
+ def file_softspace(file, newflag):
+ try:
+ softspace = file.softspace
+ except AttributeError:
+ softspace = 0
+ try:
+ file.softspace = newflag
+ except AttributeError:
+ pass
+ return softspace
+
+ def find_metaclass(bases, namespace, globals, builtins):
+ if '__metaclass__' in namespace:
+ return namespace['__metaclass__']
+ elif len(bases) > 0:
+ base = bases[0]
+ if hasattr(base, '__class__'):
+ return base.__class__
+ else:
+ return type(base)
+ elif '__metaclass__' in globals:
+ return globals['__metaclass__']
+ elif '__metaclass__' in builtins:
+ return builtins['__metaclass__']
+ else:
+ return type
+
+ def import_all_from(module, into_locals):
+ try:
+ all = module.__all__
+ except AttributeError:
+ try:
+ dict = module.__dict__
+ except AttributeError:
+ raise ImportError("from-import-* object has no __dict__ "
+ "and no __all__")
+ all = dict.keys()
+ skip_leading_underscores = True
+ else:
+ skip_leading_underscores = False
+ for name in all:
+ if skip_leading_underscores and name[0]=='_':
+ continue
+ into_locals[name] = getattr(module, name)
+
+ def prepare_exec(f, prog, globals, locals, compile_flags):
+ """Manipulate parameters to exec statement to (codeobject, dict, dict).
+ """
+ # XXX INCOMPLETE
+ if (globals is None and locals is None and
+ isinstance(prog, tuple) and
+ (len(prog) == 2 or len(prog) == 3)):
+ globals = prog[1]
+ if len(prog) == 3:
+ locals = prog[2]
+ prog = prog[0]
+ if globals is None:
+ globals = f.f_globals
+ if locals is None:
+ locals = f.f_locals
+ if locals is None:
+ locals = globals
+ if not isinstance(globals, dict):
+ raise TypeError("exec: arg 2 must be a dictionary or None")
+ elif not globals.has_key('__builtins__'):
+ globals['__builtins__'] = f.f_builtins
+ if not isinstance(locals, dict):
+ raise TypeError("exec: arg 3 must be a dictionary or None")
+ # XXX - HACK to check for code object
+ co = compile('1','<string>','eval')
+ if isinstance(prog, type(co)):
+ return (prog, globals, locals)
+ if not isinstance(prog, str):
+ ## if not (isinstance(prog, types.StringTypes) or
+ ## isinstance(prog, types.FileType)):
+ raise TypeError("exec: arg 1 must be a string, file, "
+ "or code object")
+ ## if isinstance(prog, types.FileType):
+ ## co = compile(prog.read(),prog.name,'exec',comple_flags,1)
+ ## return (co,globals,locals)
+ else: # prog is a string
+ co = compile(prog,'<string>','exec', compile_flags, 1)
+ return (co, globals, locals)
+''')
+
+file_softspace = app.interphook('file_softspace')
+find_metaclass = app.interphook('find_metaclass')
+import_all_from = app.interphook('import_all_from')
+prepare_exec = app.interphook('prepare_exec')
+
def print_expr(space, w_x):
try:
w_displayhook = space.getattr(space.w_sys, space.wrap('displayhook'))
@@ -756,19 +845,6 @@
raise OperationError(space.w_RuntimeError, "lost sys.displayhook")
space.call_function(w_displayhook, w_x)
-file_softspace = gateway.appdef("""
- (file, newflag):
- try:
- softspace = file.softspace
- except AttributeError:
- softspace = 0
- try:
- file.softspace = newflag
- except AttributeError:
- pass
- return softspace
- """)
-
def sys_stdout(space):
try:
return space.getattr(space.w_sys, space.wrap('stdout'))
@@ -784,8 +860,7 @@
# add a softspace unless we just printed a string which ends in a '\t'
# or '\n' -- or more generally any whitespace character but ' '
- w_skip = space.appexec([w_x], """
- app_skip_space(x):
+ w_skip = space.appexec([w_x], """(x):
return isinstance(x, str) and len(x) and \
x[-1].isspace() and x[-1]!=' '
""")
@@ -797,78 +872,3 @@
def print_newline_to(space, w_stream):
space.call_method(w_stream, 'write', space.wrap("\n"))
file_softspace(space, w_stream, space.w_False)
-
-def app_find_metaclass(bases, namespace, globals, builtins):
- if '__metaclass__' in namespace:
- return namespace['__metaclass__']
- elif len(bases) > 0:
- base = bases[0]
- if hasattr(base, '__class__'):
- return base.__class__
- else:
- return type(base)
- elif '__metaclass__' in globals:
- return globals['__metaclass__']
- elif '__metaclass__' in builtins:
- return builtins['__metaclass__']
- else:
- return type
-
-def app_import_all_from(module, into_locals):
- try:
- all = module.__all__
- except AttributeError:
- try:
- dict = module.__dict__
- except AttributeError:
- raise ImportError("from-import-* object has no __dict__ "
- "and no __all__")
- all = dict.keys()
- skip_leading_underscores = True
- else:
- skip_leading_underscores = False
- for name in all:
- if skip_leading_underscores and name[0]=='_':
- continue
- into_locals[name] = getattr(module, name)
-
-
-def app_prepare_exec(f, prog, globals, locals, compile_flags):
- """Manipulate parameters to exec statement to (codeobject, dict, dict).
- """
- # XXX INCOMPLETE
- if (globals is None and locals is None and
- isinstance(prog, tuple) and
- (len(prog) == 2 or len(prog) == 3)):
- globals = prog[1]
- if len(prog) == 3:
- locals = prog[2]
- prog = prog[0]
- if globals is None:
- globals = f.f_globals
- if locals is None:
- locals = f.f_locals
- if locals is None:
- locals = globals
- if not isinstance(globals, dict):
- raise TypeError("exec: arg 2 must be a dictionary or None")
- elif not globals.has_key('__builtins__'):
- globals['__builtins__'] = f.f_builtins
- if not isinstance(locals, dict):
- raise TypeError("exec: arg 3 must be a dictionary or None")
- # XXX - HACK to check for code object
- co = compile('1','<string>','eval')
- if isinstance(prog, type(co)):
- return (prog, globals, locals)
- if not isinstance(prog, str):
-## if not (isinstance(prog, types.StringTypes) or
-## isinstance(prog, types.FileType)):
- raise TypeError("exec: arg 1 must be a string, file, or code object")
-## if isinstance(prog, types.FileType):
-## co = compile(prog.read(),prog.name,'exec',comple_flags,1)
-## return (co,globals,locals)
- else: # prog is a string
- co = compile(prog,'<string>','exec', compile_flags, 1)
- return (co, globals, locals)
-
-gateway.importall(globals()) # app_xxx() -> xxx()
Modified: pypy/branch/dist-interpapp/pypy/interpreter/test/test_appinterp.py
==============================================================================
--- pypy/branch/dist-interpapp/pypy/interpreter/test/test_appinterp.py (original)
+++ pypy/branch/dist-interpapp/pypy/interpreter/test/test_appinterp.py Sat Feb 12 15:13:43 2005
@@ -1,6 +1,6 @@
import py
-from pypy.interpreter.gateway import appdef
+from pypy.interpreter.gateway import appdef, applevel
def test_execwith_novars(space):
val = space.appexec([], """
@@ -70,13 +70,21 @@
w_result = app(space)
assert space.eq_w(w_result, space.wrap(42))
+def test_applevel_object(space):
+ app = applevel('''
+ def f(x, y):
+ return x-y
+ def g(x, y):
+ return f(y, x)
+ ''')
+ g = app.interphook('g')
+ w_res = g(space, space.wrap(10), space.wrap(1))
+ assert space.eq_w(w_res, space.wrap(-9))
+
def app_test_something_at_app_level():
x = 2
assert x/2 == 1
-
+
class AppTestMethods:
def test_somee_app_test_method(self):
assert 2 == 2
-
-
-
Modified: pypy/branch/dist-interpapp/pypy/interpreter/test/test_gateway.py
==============================================================================
--- pypy/branch/dist-interpapp/pypy/interpreter/test/test_gateway.py (original)
+++ pypy/branch/dist-interpapp/pypy/interpreter/test/test_gateway.py Sat Feb 12 15:13:43 2005
@@ -57,10 +57,6 @@
class TestGateway:
- def setup_method(self, method):
- name = method.im_func.func_name
- if name in ('test_importall', 'test_exportall'):
- py.test.skip("sharing globals for app2interp'ed functions not supported")
def test_app2interp(self):
w = self.space.wrap
def app_g3(a, b):
@@ -195,26 +191,14 @@
def test_importall(self):
w = self.space.wrap
- g = {}
- exec """
-def app_g3(a, b):
- return a+b
-def app_g1(x):
- return g3('foo', x)
-""" in g
+ g = {'app_g3': app_g3}
gateway.importall(g, temporary=True)
- g1 = g['g1']
- assert self.space.eq_w(g1(self.space, w('bar')), w('foobar'))
+ g3 = g['g3']
+ assert self.space.eq_w(g3(self.space, w('bar')), w('foobar'))
- def test_exportall(self):
- w = self.space.wrap
- g = {}
- exec """
-def g3(space, w_a, w_b):
- return space.add(w_a, w_b)
-def app_g1(x):
- return g3('foo', x)
-""" in g
- gateway.exportall(g, temporary=True)
- g1 = gateway.app2interp_temp(g['app_g1'])
- assert self.space.eq_w(g1(self.space, w('bar')), w('foobar'))
+## def test_exportall(self):
+## not used any more
+
+
+def app_g3(b):
+ return 'foo'+b
Modified: pypy/branch/dist-interpapp/pypy/objspace/flow/flowcontext.py
==============================================================================
--- pypy/branch/dist-interpapp/pypy/objspace/flow/flowcontext.py (original)
+++ pypy/branch/dist-interpapp/pypy/objspace/flow/flowcontext.py Sat Feb 12 15:13:43 2005
@@ -112,9 +112,9 @@
self.closure)
def bytecode_trace(self, frame):
- assert frame is self.crnt_frame, "seeing an unexpected frame!"
if not isinstance(self.crnt_ops, list):
return
+ assert frame is self.crnt_frame, "seeing an unexpected frame!"
next_instr = frame.next_instr
self.crnt_offset = next_instr # save offset for opcode
varnames = frame.code.getvarnames()
Modified: pypy/branch/dist-interpapp/pypy/objspace/std/dicttype.py
==============================================================================
--- pypy/branch/dist-interpapp/pypy/objspace/std/dicttype.py (original)
+++ pypy/branch/dist-interpapp/pypy/objspace/std/dicttype.py Sat Feb 12 15:13:43 2005
@@ -20,75 +20,69 @@
#dict_str = StdObjSpace.str
# default application-level implementations for some operations
+# gateway is imported in the stdtypedef module
+app = gateway.applevel('''
-def app_dict_update__ANY_ANY(d, o):
- for k in o.keys():
- d[k] = o[k]
-
-def app_dict_popitem__ANY(d):
- k = d.keys()
- if not k:
- raise KeyError("popitem(): dictionary is empty")
- k = k[0]
- v = d[k]
- del d[k]
- return k, v
-
-def app_dict_get__ANY_ANY_ANY(d, k, v=None):
- if d.has_key(k):
- return d[k]
- return v
-
-def app_dict_setdefault__ANY_ANY_ANY(d, k, v):
- if d.has_key(k):
- return d[k]
- d[k] = v
- return v
-
-def app_dict_pop__ANY_ANY(d, k, default):
- if len(default) > 1:
- raise TypeError, "pop expected at most 2 arguments, got %d" % (
- 1 + len(default))
- try:
+ def update(d, o):
+ for k in o.keys():
+ d[k] = o[k]
+
+ def popitem(d):
+ k = d.keys()
+ if not k:
+ raise KeyError("popitem(): dictionary is empty")
+ k = k[0]
v = d[k]
del d[k]
- except KeyError, e:
- if default:
- return default[0]
+ return k, v
+
+ def get(d, k, v=None):
+ if k in d:
+ return d[k]
else:
- raise e
- return v
+ return v
-def app_dict_iteritems__ANY(d):
- return iter(d.items())
+ def setdefault(d, k, v=None):
+ if k in d:
+ return d[k]
+ else:
+ d[k] = v
+ return v
-def app_dict_iterkeys__ANY(d):
- return iter(d.keys())
+ def pop(d, k, defaults): # XXX defaults is actually *defaults
+ if len(defaults) > 1:
+ raise TypeError, "pop expected at most 2 arguments, got %d" % (
+ 1 + len(defaults))
+ try:
+ v = d[k]
+ del d[k]
+ except KeyError, e:
+ if defaults:
+ return defaults[0]
+ else:
+ raise e
+ return v
+
+ def iteritems(d):
+ return iter(d.items())
+
+ def iterkeys(d):
+ return iter(d.keys())
+
+ def itervalues(d):
+ return iter(d.values())
+''')
+#XXX what about dict.fromkeys()?
+
+dict_update__ANY_ANY = app.interphook("update")
+dict_popitem__ANY = app.interphook("popitem")
+dict_get__ANY_ANY_ANY = app.interphook("get")
+dict_setdefault__ANY_ANY_ANY = app.interphook("setdefault")
+dict_pop__ANY_ANY = app.interphook("pop")
+dict_iteritems__ANY = app.interphook("iteritems")
+dict_iterkeys__ANY = app.interphook("iterkeys")
+dict_itervalues__ANY = app.interphook("itervalues")
-def app_dict_itervalues__ANY(d):
- return iter(d.values())
-
-#def app_dict_fromkeys__ANY_List(d, seq, value):
-# d = {}
-# if value:
-# value = value[0]
-# else:
-# value = None
-# for item in seq:
-# d[item] = value
-# return d
-#XXX implement dict.fromkeys() which must be a static method
-#XXX accepting any iterable
-
-# This can return when multimethods have been fixed
-"""
-def app_dict_str__ANY(d):
- items = []
- for k, v in d.iteritems():
- items.append("%r: %r" % (k, v))
- return "{%s}" % ', '.join(items)
-"""
-gateway.importall(globals())
register_all(vars(), globals())
# ____________________________________________________________
Modified: pypy/branch/dist-interpapp/pypy/objspace/std/listtype.py
==============================================================================
--- pypy/branch/dist-interpapp/pypy/objspace/std/listtype.py (original)
+++ pypy/branch/dist-interpapp/pypy/objspace/std/listtype.py Sat Feb 12 15:13:43 2005
@@ -14,15 +14,16 @@
list_sort = MultiMethod('sort', 4, defaults=(None, None, False), argnames=['cmp', 'key', 'reverse'])
list_reversed = MultiMethod('__reversed__', 1)
-def app_list_reversed__ANY(lst):
- def reversed_gen(local_iterable):
- len_iterable = len(local_iterable)
- for index in range(len_iterable-1, -1, -1):
- yield local_iterable[index]
- return reversed_gen(lst)
-
# gateway is imported in the stdtypedef module
-gateway.importall(globals())
+app = gateway.applevel('''
+
+ def reversed(lst):
+ for index in range(len(lst)-1, -1, -1):
+ yield lst[index]
+
+''')
+
+list_reversed__ANY = app.interphook('reversed')
register_all(vars(), globals())
# ____________________________________________________________
Modified: pypy/branch/dist-interpapp/pypy/objspace/std/slicetype.py
==============================================================================
--- pypy/branch/dist-interpapp/pypy/objspace/std/slicetype.py (original)
+++ pypy/branch/dist-interpapp/pypy/objspace/std/slicetype.py Sat Feb 12 15:13:43 2005
@@ -6,65 +6,69 @@
slice_indices = MultiMethod('indices', 2)
# default application-level implementations for some operations
+# gateway is imported in the stdtypedef module
+app = gateway.applevel("""
-slice_indices__ANY_ANY = slice_indices3 = gateway.appdef(
- """slice_indices3(slice, length):
- # this is used internally, analogous to CPython's PySlice_GetIndicesEx
- step = slice.step
- if step is None:
- step = 1
- elif step == 0:
- raise ValueError, "slice step cannot be zero"
- if step < 0:
- defstart = length - 1
- defstop = -1
- else:
- defstart = 0
- defstop = length
-
- start = slice.start
- if start is None:
- start = defstart
- else:
- if start < 0:
- start += length
+ def indices(slice, length):
+ # this is used internally, analogous to CPython's PySlice_GetIndicesEx
+ step = slice.step
+ if step is None:
+ step = 1
+ elif step == 0:
+ raise ValueError, "slice step cannot be zero"
+ if step < 0:
+ defstart = length - 1
+ defstop = -1
+ else:
+ defstart = 0
+ defstop = length
+
+ start = slice.start
+ if start is None:
+ start = defstart
+ else:
if start < 0:
+ start += length
+ if start < 0:
+ if step < 0:
+ start = -1
+ else:
+ start = 0
+ elif start >= length:
if step < 0:
- start = -1
+ start = length - 1
else:
- start = 0
- elif start >= length:
- if step < 0:
- start = length - 1
- else:
- start = length
-
- stop = slice.stop
- if stop is None:
- stop = defstop
- else:
- if stop < 0:
- stop += length
- if stop < 0:
- stop = -1
- elif stop > length:
- stop = length
-
- return start, stop, step
- """)
-
-slice_indices4 = gateway.appdef("""slice_indices4(slice, sequencelength):
- start, stop, step = slice_indices3(slice, sequencelength)
- slicelength = stop - start
- lengthsign = cmp(slicelength, 0)
- stepsign = cmp(step, 0)
- if stepsign == lengthsign:
- slicelength = (slicelength - lengthsign) // step + 1
- else:
- slicelength = 0
+ start = length
- return start, stop, step, slicelength
- """)
+ stop = slice.stop
+ if stop is None:
+ stop = defstop
+ else:
+ if stop < 0:
+ stop += length
+ if stop < 0:
+ stop = -1
+ elif stop > length:
+ stop = length
+
+ return start, stop, step
+
+ def slice_indices4(slice, sequencelength):
+ start, stop, step = indices(slice, sequencelength)
+ slicelength = stop - start
+ lengthsign = cmp(slicelength, 0)
+ stepsign = cmp(step, 0)
+ if stepsign == lengthsign:
+ slicelength = (slicelength - lengthsign) // step + 1
+ else:
+ slicelength = 0
+
+ return start, stop, step, slicelength
+""")
+
+slice_indices__ANY_ANY = app.interphook("indices")
+slice_indices3 = slice_indices__ANY_ANY
+slice_indices4 = app.interphook("slice_indices4")
# utility functions
def indices3(space, w_slice, length):
More information about the Pypy-commit
mailing list