[pypy-svn] rev 696 - in pypy/trunk/src/pypy: interpreter objspace/std
arigo at codespeak.net
arigo at codespeak.net
Thu May 29 17:21:49 CEST 2003
Author: arigo
Date: Thu May 29 17:21:48 2003
New Revision: 696
Modified:
pypy/trunk/src/pypy/interpreter/baseobjspace.py
pypy/trunk/src/pypy/objspace/std/default.py
pypy/trunk/src/pypy/objspace/std/dictobject.py
pypy/trunk/src/pypy/objspace/std/funcobject.py
pypy/trunk/src/pypy/objspace/std/instmethobject.py
pypy/trunk/src/pypy/objspace/std/multimethod.py
pypy/trunk/src/pypy/objspace/std/objspace.py
pypy/trunk/src/pypy/objspace/std/tupleobject.py
pypy/trunk/src/pypy/objspace/std/typeobject.py
Log:
nice general methods for our built-in objects
Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/baseobjspace.py (original)
+++ pypy/trunk/src/pypy/interpreter/baseobjspace.py Thu May 29 17:21:48 2003
@@ -222,6 +222,7 @@
('iter', 'iter', 1, ['__iter__']),
('next', 'next', 1, ['next']), # iterator interface
('call', 'call', 3, ['__call__']),
+ ('get', 'get', 3, ['__get__']),
]
ObjSpace.BuiltinModuleTable = [
Modified: pypy/trunk/src/pypy/objspace/std/default.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/default.py (original)
+++ pypy/trunk/src/pypy/objspace/std/default.py Thu May 29 17:21:48 2003
@@ -49,13 +49,24 @@
#w_type = space.type(w_obj)
#w_typename = space.getattr(w_type, space.wrap('__name__'))
#...
-
- # XXX as long as don't have types...
+
+ w_type = space.type(w_obj)
if space.is_true(space.eq(w_attr, space.wrap('__class__'))):
- return space.wrap(space.unwrap(w_obj).__class__)
+ return w_type
+ # XXX implement lookup as a multimethod
+ from typeobject import W_TypeObject
+ if isinstance(w_type, W_TypeObject): # XXX must always be true at some point
+ try:
+ w_value = w_type.lookup(space, w_attr)
+ except KeyError:
+ pass
+ else:
+ return space.get(w_value, w_obj, w_type)
+
raise OperationError(space.w_AttributeError, w_attr)
+
StdObjSpace.getattr.register(default_getattr, W_ANY, W_ANY)
def default_setattr(space, w_obj, w_attr, w_value):
@@ -92,3 +103,23 @@
return space.w_True
StdObjSpace.contains.register(default_contains, W_ANY, W_ANY)
+
+
+# '__get__(descr, inst, cls)' returns 'descr' by default
+
+def default_get(space, w_descr, w_inst, w_cls):
+ return w_descr
+
+StdObjSpace.get.register(default_get, W_ANY, W_ANY, W_ANY)
+
+
+# static types
+
+def default_type(space, w_obj):
+ w_type = w_obj.statictype
+ if w_type is None:
+ # XXX remove me, temporary
+ return space.wrap(space.unwrap(w_obj).__class__)
+ return w_type
+
+StdObjSpace.type.register(default_type, W_ANY)
Modified: pypy/trunk/src/pypy/objspace/std/dictobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/dictobject.py (original)
+++ pypy/trunk/src/pypy/objspace/std/dictobject.py Thu May 29 17:21:48 2003
@@ -33,6 +33,7 @@
class W_DictObject(W_Object):
delegate_once = {}
+ statictypename = 'dict'
def __init__(w_self, space, list_pairs_w):
W_Object.__init__(w_self, space)
@@ -79,7 +80,13 @@
return space.newlist([ cell.get()
for w_key,cell in
w_self.non_empties()])
-
+
+ copy = implmethod().register(copy)
+ items = implmethod().register(items)
+ keys = implmethod().register(keys)
+ values = implmethod().register(values)
+
+
def dict_is_true(space, w_dict):
return not not w_dict.non_empties()
@@ -132,22 +139,22 @@
StdObjSpace.contains.register(contains_dict_any, W_DictObject, W_ANY)
-def getattr_dict(space, w_dict, w_attr):
- if space.is_true(space.eq(w_attr, space.wrap('copy'))):
- w_builtinfn = make_builtin_func(space, W_DictObject.copy)
- return W_InstMethObject(space, w_dict, w_builtinfn)
- if space.is_true(space.eq(w_attr, space.wrap('items'))):
- w_builtinfn = make_builtin_func(space, W_DictObject.items)
- return W_InstMethObject(space, w_dict, w_builtinfn)
- if space.is_true(space.eq(w_attr, space.wrap('keys'))):
- w_builtinfn = make_builtin_func(space, W_DictObject.keys)
- return W_InstMethObject(space, w_dict, w_builtinfn)
- if space.is_true(space.eq(w_attr, space.wrap('values'))):
- w_builtinfn = make_builtin_func(space, W_DictObject.values)
- return W_InstMethObject(space, w_dict, w_builtinfn)
- raise FailedToImplement(space.w_AttributeError)
+##def getattr_dict(space, w_dict, w_attr):
+## if space.is_true(space.eq(w_attr, space.wrap('copy'))):
+## w_builtinfn = make_builtin_func(space, W_DictObject.copy)
+## return W_InstMethObject(space, w_dict, w_builtinfn)
+## if space.is_true(space.eq(w_attr, space.wrap('items'))):
+## w_builtinfn = make_builtin_func(space, W_DictObject.items)
+## return W_InstMethObject(space, w_dict, w_builtinfn)
+## if space.is_true(space.eq(w_attr, space.wrap('keys'))):
+## w_builtinfn = make_builtin_func(space, W_DictObject.keys)
+## return W_InstMethObject(space, w_dict, w_builtinfn)
+## if space.is_true(space.eq(w_attr, space.wrap('values'))):
+## w_builtinfn = make_builtin_func(space, W_DictObject.values)
+## return W_InstMethObject(space, w_dict, w_builtinfn)
+## raise FailedToImplement(space.w_AttributeError)
-StdObjSpace.getattr.register(getattr_dict, W_DictObject, W_ANY)
+##StdObjSpace.getattr.register(getattr_dict, W_DictObject, W_ANY)
def eq_dict_dict(space, w_left, w_right):
if len(w_left.data) != len(w_right.data):
Modified: pypy/trunk/src/pypy/objspace/std/funcobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/funcobject.py (original)
+++ pypy/trunk/src/pypy/objspace/std/funcobject.py Thu May 29 17:21:48 2003
@@ -1,6 +1,7 @@
from __future__ import nested_scopes
from pypy.objspace.std.objspace import *
import pypy.interpreter.pyframe
+from pypy.objspace.std.instmethobject import W_InstMethObject
class W_FuncObject(W_Object):
@@ -35,3 +36,9 @@
return w_ret
StdObjSpace.call.register(func_call, W_FuncObject, W_ANY, W_ANY)
+
+
+def func_get(space, w_function, w_instance, w_cls):
+ return W_InstMethObject(space, w_instance, w_function)
+
+StdObjSpace.get.register(func_get, W_FuncObject, W_ANY, W_ANY)
Modified: pypy/trunk/src/pypy/objspace/std/instmethobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/instmethobject.py (original)
+++ pypy/trunk/src/pypy/objspace/std/instmethobject.py Thu May 29 17:21:48 2003
@@ -29,3 +29,6 @@
return w_ret
StdObjSpace.call.register(instmeth_call, W_InstMethObject, W_ANY, W_ANY)
+
+
+# XXX do __get__ for instance methods
Modified: pypy/trunk/src/pypy/objspace/std/multimethod.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/multimethod.py (original)
+++ pypy/trunk/src/pypy/objspace/std/multimethod.py Thu May 29 17:21:48 2003
@@ -103,7 +103,7 @@
w_value = self.space.wrap(message)
raise OperationError(self.space.w_TypeError, w_value)
- def perform_call(self, args, initialtypes):
+ def perform_call(self, args, initialtypes, prepend_space_argument=True):
extraargs = args[self.multimethod.arity:]
choicelist = self.multimethod.buildchoices(initialtypes)
firstfailure = None
@@ -114,8 +114,10 @@
arg = delegator(self.space, arg)
newargs.append(arg)
newargs = tuple(newargs) + extraargs
+ if prepend_space_argument:
+ newargs = (self.space,) + newargs
try:
- return function(self.space, *newargs)
+ return function(*newargs)
except FailedToImplement, e:
# we got FailedToImplement, record the first such error
if firstfailure is None:
Modified: pypy/trunk/src/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/objspace.py (original)
+++ pypy/trunk/src/pypy/objspace/std/objspace.py Thu May 29 17:21:48 2003
@@ -19,6 +19,18 @@
return w_self.__class__
+class implmethod(object):
+ def __init__(self):
+ self.dispatch_table = {}
+ def register(self, function, *types):
+ if types in self.dispatch_table:
+ raise error, "we already got an implementation for %r" % types
+ self.dispatch_table[types] = function
+ return self
+ def __get__(self, instance, cls=None):
+ raise "XXX come back later"
+
+
##################################################################
class StdObjSpace(ObjSpace):
@@ -37,10 +49,11 @@
'W_IntObject': 'intobject',
'W_FloatObject': 'floatobject',
#'W_ListObject': 'listobject',
+ 'W_DictObject': 'dictobject',
}
- TYPE_CACHE = {}
def initialize(self):
+ self.TYPE_CACHE = {}
from noneobject import W_NoneObject
from boolobject import W_BoolObject
from cpythonobject import W_CPythonObject
Modified: pypy/trunk/src/pypy/objspace/std/tupleobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/tupleobject.py (original)
+++ pypy/trunk/src/pypy/objspace/std/tupleobject.py Thu May 29 17:21:48 2003
@@ -5,6 +5,9 @@
class W_TupleObject(W_Object):
+ delegate_once = {}
+ statictypename = 'tuple'
+
def __init__(w_self, space, wrappeditems):
W_Object.__init__(w_self, space)
w_self.wrappeditems = wrappeditems # a list of wrapped values
Modified: pypy/trunk/src/pypy/objspace/std/typeobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/typeobject.py (original)
+++ pypy/trunk/src/pypy/objspace/std/typeobject.py Thu May 29 17:21:48 2003
@@ -1,5 +1,6 @@
from pypy.interpreter import pycode
from pypy.objspace.std.objspace import *
+from pypy.objspace.std.dictobject import W_DictObject
class W_TypeObject(W_Object):
@@ -10,12 +11,41 @@
W_Object.__init__(w_self, space)
w_self.w_tpname = w_tpname
w_self.builtin_implementations = []
- w_self.multimethods = [value for key, value in space.__dict__.iteritems()
- if isinstance(value, MultiMethod)]
+ w_self.multimethods = {}
+ # HACK to get to the multimethods of the space
+ for key, value in space.__class__.__dict__.iteritems():
+ if isinstance(value, MultiMethod):
+ for i in range(len(value.specialnames)):
+ w_self.multimethods[value.specialnames[i]] = value, i
def setup_builtin_type(w_self, implementation):
implementation.statictype = w_self
w_self.builtin_implementations.append(implementation)
+
+ for key, value in implementation.__dict__.iteritems():
+ if isinstance(value, implmethod):
+ try:
+ multimethod, bound_pos = w_self.multimethods[key]
+ except KeyError:
+ sample = value.dispatch_table.keys()[0]
+ multimethod = MultiMethod('%s()' % key, len(sample)+1, [])
+ w_self.multimethods[key] = multimethod, None
+ for types, func in value.dispatch_table.iteritems():
+ multimethod.register(func, implementation, *types)
+
+ def lookup(w_self, space, w_key):
+ "XXX at some point, turn this into a multimethod"
+ key = space.unwrap(w_key)
+ assert isinstance(key, str)
+ try:
+ multimethod, bound_pos = w_self.multimethods[key]
+ except KeyError:
+ raise KeyError
+ multimethod = multimethod.__get__(space, None)
+ code = PyMultimethodCode(multimethod, bound_pos, w_self)
+ if code.multimethod.is_empty():
+ raise KeyError
+ return space.newfunction(code, space.w_None, space.w_None)
def make_type_by_name(space, tpname):
@@ -33,8 +63,14 @@
pycode.PyBaseCode.__init__(self)
argnames = ['x%d'%(i+1) for i in range(multimethod.multimethod.arity)]
if w_type is not None:
- multimethod = multimethod.slicetable(bound_position, w_type)
- argnames.insert(0, argnames.pop(bound_position))
+ # 'bound_pos' hack mode on
+ multimethod = multimethod.slicetable(bound_position or 0, w_type)
+ # 'bound_pos' hack mode off
+ if bound_position:
+ argnames.insert(0, argnames.pop(bound_position))
+ # 'bound_pos' hack mode on
+ self.prepend_space_argument = bound_position is not None
+ # 'bound_pos' hack mode off
self.multimethod = multimethod
self.co_name = multimethod.multimethod.operatorsymbol
self.co_flags = 0
@@ -54,7 +90,8 @@
dispatchargs = tuple(dispatchargs)
initialtypes = tuple(initialtypes)
try:
- return multimethod.perform_call(dispatchargs, initialtypes)
+ return multimethod.perform_call(dispatchargs, initialtypes,
+ prepend_space_argument = self.prepend_space_argument)
except FailedToImplement, e:
if e.args:
raise OperationError(*e.args)
More information about the Pypy-commit
mailing list