[pypy-svn] rev 1053 - in pypy/trunk/src/pypy: interpreter objspace/stdobjspace/std/test
arigo at codespeak.net
arigo at codespeak.net
Tue Jun 24 15:50:58 CEST 2003
Author: arigo
Date: Tue Jun 24 15:50:57 2003
New Revision: 1053
Modified:
pypy/trunk/src/pypy/interpreter/baseobjspace.py
pypy/trunk/src/pypy/objspace/std/dictobject.py
pypy/trunk/src/pypy/objspace/std/dicttype.py
pypy/trunk/src/pypy/objspace/std/floattype.py
pypy/trunk/src/pypy/objspace/std/inttype.py
pypy/trunk/src/pypy/objspace/std/listobject.py
pypy/trunk/src/pypy/objspace/std/listtype.py
pypy/trunk/src/pypy/objspace/std/objectobject.py
pypy/trunk/src/pypy/objspace/std/objecttype.py
pypy/trunk/src/pypy/objspace/std/objspace.py
pypy/trunk/src/pypy/objspace/std/register_all.py
pypy/trunk/src/pypy/objspace/std/slicetype.py
pypy/trunk/src/pypy/objspace/std/stringtype.py
pypy/trunk/src/pypy/objspace/std/test/test_dictobject.py
pypy/trunk/src/pypy/objspace/std/tupletype.py
pypy/trunk/src/pypy/objspace/std/typeobject.py
pypy/trunk/src/pypy/objspace/std/typetype.py
pypy/trunk/src/pypy/objspace/std/userobject.py
pypy/trunk/src/pypy/objspace/std/usertype.py
Log:
Got the __new__ and __init__ methods (probably) right.
Reorganized constructors of all object types accordingly.
Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/baseobjspace.py (original)
+++ pypy/trunk/src/pypy/interpreter/baseobjspace.py Tue Jun 24 15:50:57 2003
@@ -226,8 +226,6 @@
('get', 'get', 3, ['__get__']),
('set', 'set', 2, ['__set__']),
('delete', 'delete', 2, ['__delete__']),
- ('new', 'new', 3, ['__new__']),
- ('init', 'init', 3, ['__init__']),
]
ObjSpace.BuiltinModuleTable = [
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 Tue Jun 24 15:50:57 2003
@@ -88,6 +88,26 @@
result[space.unwrap(w_key)] = space.unwrap(cell.get())
return result
+def object_init__Dict_ANY_ANY(space, w_dict, w_args, w_kwds):
+ # w_kwds = w_kwds.copy() w unwrap & rewrap, but that should not be needed
+ dict_clear__Dict(space, w_dict)
+ args = space.unpackiterable(w_args)
+ if len(args) == 0:
+ pass
+ elif len(args) == 1:
+ # XXX do dict({...}) with dict_update__Dict_Dict()
+ list_of_w_pairs = space.unpackiterable(args[0])
+ for w_pair in list_of_w_pairs:
+ pair = space.unpackiterable(w_pair)
+ if len(pair)!=2:
+ raise OperationError(space.w_ValueError,
+ space.wrap("dict() takes a sequence of pairs"))
+ w_k, w_v = pair
+ setitem__Dict_ANY_ANY(space, w_dict, w_k, w_v)
+ else:
+ raise OperationError(space.w_TypeError,
+ space.wrap("dict() takes at most 1 argument"))
+
def getitem__Dict_ANY(space, w_dict, w_lookup):
data = w_dict.non_empties()
# XXX shouldn't this use hashing? -- mwh
Modified: pypy/trunk/src/pypy/objspace/std/dicttype.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/dicttype.py (original)
+++ pypy/trunk/src/pypy/objspace/std/dicttype.py Tue Jun 24 15:50:57 2003
@@ -28,26 +28,8 @@
registerimplementation(W_DictType)
-# XXX we'll worry about the __new__/__init__ distinction later
-def dicttype_new(space, w_listtype, w_args, w_kwds):
- # w_kwds = w_kwds.copy() w unwrap & rewrap, but that should not be needed
- args = space.unpackiterable(w_args)
- if len(args) == 0:
- pass
- elif len(args) == 1:
- list_of_w_pairs = space.unpackiterable(args[0])
- list_of_w_pairs.reverse()
- for pair_w in list_of_w_pairs:
- pair = space.unpackiterable(pair_w)
- if len(pair)!=2:
- raise OperationError(space.w_ValueError,
- space.wrap("dict() takes a sequence of pairs"))
- k, v = pair
- if not space.is_true(space.contains(w_kwds, k)):
- space.setitem(w_kwds, k, v)
- else:
- raise OperationError(space.w_TypeError,
- space.wrap("dict() takes at most 1 argument"))
- return w_kwds
-StdObjSpace.new.register(dicttype_new, W_DictType, W_ANY, W_ANY)
+def type_new__DictType_DictType_ANY_ANY(space, w_basetype, w_dicttype, w_args, w_kwds):
+ return space.newdict([]), True
+
+register_all(vars())
Modified: pypy/trunk/src/pypy/objspace/std/floattype.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/floattype.py (original)
+++ pypy/trunk/src/pypy/objspace/std/floattype.py Tue Jun 24 15:50:57 2003
@@ -8,24 +8,25 @@
registerimplementation(W_FloatType)
-def new__FloatType_ANY_ANY(space, w_inttype, w_args, w_kwds):
+
+def type_new__FloatType_FloatType_ANY_ANY(space, w_basetype, w_floattype, w_args, w_kwds):
if space.is_true(w_kwds):
raise OperationError(space.w_TypeError,
space.wrap("no keyword arguments expected"))
args = space.unpackiterable(w_args)
if len(args) == 0:
- return space.newint(0)
+ return space.newfloat(0), True
elif len(args) == 1:
arg = args[0]
if space.is_true(space.issubtype(space.type(arg),
space.w_str)):
try:
- return space.newfloat(float(space.unwrap(arg)))
+ return space.newfloat(float(space.unwrap(arg))), True
except TypeError:
raise OperationError(space.w_TypeError,
space.wrap("invalid literal for float()"))
else:
- return space.float(args[0])
+ return space.float(args[0]), True
else:
raise OperationError(space.w_TypeError,
space.wrap("float() takes at most 1 argument"))
Modified: pypy/trunk/src/pypy/objspace/std/inttype.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/inttype.py (original)
+++ pypy/trunk/src/pypy/objspace/std/inttype.py Tue Jun 24 15:50:57 2003
@@ -9,27 +9,26 @@
registerimplementation(W_IntType)
-# XXX we'll worry about the __new__/__init__ distinction later
-def inttype_new(space, w_inttype, w_args, w_kwds):
+def type_new__IntType_IntType_ANY_ANY(space, w_basetype, w_inttype, w_args, w_kwds):
if space.is_true(w_kwds):
raise OperationError(space.w_TypeError,
space.wrap("no keyword arguments expected"))
args = space.unpackiterable(w_args)
if len(args) == 0:
- return space.newint(0)
+ return space.newint(0), True
elif len(args) == 1:
arg = args[0]
if space.is_true(space.issubtype(space.type(arg),
space.w_str)):
try:
- return space.newint(int(space.unwrap(arg)))
+ return space.newint(int(space.unwrap(arg))), True
except TypeError:
raise OperationError(space.w_TypeError,
space.wrap("invalid literal for int()"))
else:
- return space.int(args[0])
+ return space.int(args[0]), True
else:
raise OperationError(space.w_TypeError,
space.wrap("int() takes at most 1 argument"))
-StdObjSpace.new.register(inttype_new, W_IntType, W_ANY, W_ANY)
+register_all(vars())
Modified: pypy/trunk/src/pypy/objspace/std/listobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/listobject.py (original)
+++ pypy/trunk/src/pypy/objspace/std/listobject.py Tue Jun 24 15:50:57 2003
@@ -35,6 +35,27 @@
items = [space.unwrap(w_item) for w_item in w_list.ob_item[:w_list.ob_size]]
return list(items)
+def object_init__List_ANY_ANY(space, w_list, w_args, w_kwds):
+ if space.is_true(w_kwds):
+ raise OperationError(space.w_TypeError,
+ space.wrap("no keyword arguments expected"))
+ w_list.ob_size = 0 # XXX think about it later
+ args = space.unpackiterable(w_args)
+ if len(args) == 0:
+ pass # empty list
+ elif len(args) == 1:
+ w_iterable = args[0]
+ w_iterator = space.iter(w_iterable)
+ while True:
+ try:
+ w_item = space.next(w_iterator)
+ except NoValue:
+ break # done
+ _ins1(w_list, w_list.ob_size, w_item)
+ else:
+ raise OperationError(space.w_TypeError,
+ space.wrap("list() takes at most 1 argument"))
+
def len__List(space, w_list):
result = w_list.ob_size
return W_IntObject(space, result)
@@ -158,23 +179,24 @@
items[idx] = w_any
return space.w_None
-# not trivial!
+# XXX not trivial!
def setitem__List_Slice_List(space, w_list, w_slice, w_list2):
- items = w_list.ob_item
- w_length = space.wrap(w_list.ob_size)
- w_start, w_stop, w_step, w_slicelength = w_slice.indices(w_length)
- start = space.unwrap(w_start)
- step = space.unwrap(w_step)
- slicelength = space.unwrap(w_slicelength)
- assert slicelength >= 0
- w_res = W_ListObject(space, [])
- _list_resize(w_res, slicelength)
- subitems = w_res.ob_item
- for i in range(slicelength):
- subitems[i] = items[start]
- start += step
- w_res.ob_size = slicelength
- return w_res
+ raise Exception, "not done!"
+## items = w_list.ob_item
+## w_length = space.wrap(w_list.ob_size)
+## w_start, w_stop, w_step, w_slicelength = w_slice.indices(w_length)
+## start = space.unwrap(w_start)
+## step = space.unwrap(w_step)
+## slicelength = space.unwrap(w_slicelength)
+## assert slicelength >= 0
+## w_res = W_ListObject(space, [])
+## _list_resize(w_res, slicelength)
+## subitems = w_res.ob_item
+## for i in range(slicelength):
+## subitems[i] = items[start]
+## start += step
+## w_res.ob_size = slicelength
+## return w_res
def repr__List(space, w_list):
w = space.wrap
Modified: pypy/trunk/src/pypy/objspace/std/listtype.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/listtype.py (original)
+++ pypy/trunk/src/pypy/objspace/std/listtype.py Tue Jun 24 15:50:57 2003
@@ -19,20 +19,7 @@
registerimplementation(W_ListType)
-# XXX right now, this is responsible for building a whole new list
-# XXX we'll worry about the __new__/__init__ distinction later
-def listtype_new(space, w_listtype, w_args, w_kwds):
- if space.is_true(w_kwds):
- raise OperationError(space.w_TypeError,
- space.wrap("no keyword arguments expected"))
- args = space.unpackiterable(w_args)
- if len(args) == 0:
- list_w = []
- elif len(args) == 1:
- list_w = space.unpackiterable(args[0])
- else:
- raise OperationError(space.w_TypeError,
- space.wrap("list() takes at most 1 argument"))
- return space.newlist(list_w)
+def type_new__ListType_ListType_ANY_ANY(space, w_basetype, w_listtype, w_args, w_kwds):
+ return space.newlist([]), True
-StdObjSpace.new.register(listtype_new, W_ListType, W_ANY, W_ANY)
+register_all(vars())
Modified: pypy/trunk/src/pypy/objspace/std/objectobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/objectobject.py (original)
+++ pypy/trunk/src/pypy/objspace/std/objectobject.py Tue Jun 24 15:50:57 2003
@@ -17,5 +17,8 @@
return W_ObjectObject(space)
delegate__ANY.priority = PRIORITY_PARENT_TYPE
+def object_init__Object_ANY_ANY(space, w_object, w_args, w_kwds):
+ pass
+
register_all(vars())
Modified: pypy/trunk/src/pypy/objspace/std/objecttype.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/objecttype.py (original)
+++ pypy/trunk/src/pypy/objspace/std/objecttype.py Tue Jun 24 15:50:57 2003
@@ -20,14 +20,16 @@
object_str = StdObjSpace.str
object_hash = StdObjSpace.hash
+ # this is a method in 'object' because it is not an object space operation
+ object_init = MultiMethod('__init__', 3, varargs=True, keywords=True)
+
registerimplementation(W_ObjectType)
-# XXX we'll worry about the __new__/__init__ distinction later
-def new__ObjectType_ANY_ANY(space, w_objecttype, w_args, w_kwds):
+def type_new__ObjectType_ObjectType_ANY_ANY(space, w_basetype, w_objecttype, w_args, w_kwds):
# XXX 2.2 behavior: ignoring all arguments
from objectobject import W_ObjectObject
- return W_ObjectObject(space)
+ return W_ObjectObject(space), True
### The following implementations are registered to the
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 Tue Jun 24 15:50:57 2003
@@ -302,5 +302,6 @@
# import the common base W_ObjectObject as well as
# default implementations of some multimethods for all objects
# that don't explicitely override them or that raise FailedToImplement
+from pypy.objspace.std.register_all import register_all
import pypy.objspace.std.objectobject
import pypy.objspace.std.default
Modified: pypy/trunk/src/pypy/objspace/std/register_all.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/register_all.py (original)
+++ pypy/trunk/src/pypy/objspace/std/register_all.py Tue Jun 24 15:50:57 2003
@@ -14,6 +14,9 @@
for registration.
"""
from pypy.objspace.std.objspace import StdObjSpace, W_ANY
+ namespaces = [StdObjSpace]
+ if alt_ns:
+ namespaces.insert(0, alt_ns)
for name, obj in module_dict.items():
if name.find('__')<1:
@@ -32,23 +35,40 @@
i, i, name)
l.append(icls)
- if len(l) != obj.func_code.co_argcount-1:
- raise ValueError, \
- "function name %s doesn't specify exactly %d arguments" % (
- repr(name), obj.func_code.co_argcount-1)
+ #XXX trying to be too clever at the moment for userobject.SpecialMethod
+ #if len(l) != obj.func_code.co_argcount-1:
+ # raise ValueError, \
+ # "function name %s doesn't specify exactly %d arguments" % (
+ # repr(name), obj.func_code.co_argcount-1)
funcname = _name_mappings.get(funcname, funcname)
- if hasattr(alt_ns, funcname):
- getattr(alt_ns, funcname).register(obj, *l)
- else:
- getattr(StdObjSpace, funcname).register(obj, *l)
+ func = hack_func_by_name(funcname, namespaces)
+ func.register(obj, *l)
add_extra_comparisons()
+def hack_func_by_name(funcname, namespaces):
+ for ns in namespaces:
+ if hasattr(ns, funcname):
+ return getattr(ns, funcname)
+ import typetype
+ try:
+ return getattr(typetype.W_TypeType, funcname)
+ except AttributeError:
+ pass # catches not only the getattr() but the typetype.W_TypeType
+ # in case it is not fully imported yet :-((((
+ import objecttype
+ try:
+ return getattr(objecttype.W_ObjectType, funcname)
+ except AttributeError:
+ pass # same comment
+ raise NameError, ("trying hard but not finding a multimethod named %s" %
+ funcname)
+
class Curry:
def __init__(self, fun, arg):
self.fun = fun
- self.pending = [arg]
+ self.pending = (arg,)
def __call__(self, *args):
return self.fun(*(self.pending + args))
Modified: pypy/trunk/src/pypy/objspace/std/slicetype.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/slicetype.py (original)
+++ pypy/trunk/src/pypy/objspace/std/slicetype.py Tue Jun 24 15:50:57 2003
@@ -8,7 +8,8 @@
registerimplementation(W_SliceType)
-def slicetype_new(space, w_slicetype, w_args, w_kwds):
+
+def type_new__SliceType_SliceType_ANY_ANY(space, w_basetype, w_slicetype, w_args, w_kwds):
if space.is_true(w_kwds):
raise OperationError(space.w_TypeError,
space.wrap("no keyword arguments expected"))
@@ -28,6 +29,6 @@
else:
raise OperationError(space.w_TypeError,
space.wrap("slice() takes at least 1 argument"))
- return space.newslice(start, stop, step)
+ return space.newslice(start, stop, step), True
-StdObjSpace.new.register(slicetype_new, W_SliceType, W_ANY, W_ANY)
+register_all(vars())
Modified: pypy/trunk/src/pypy/objspace/std/stringtype.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/stringtype.py (original)
+++ pypy/trunk/src/pypy/objspace/std/stringtype.py Tue Jun 24 15:50:57 2003
@@ -41,16 +41,15 @@
registerimplementation(W_StringType)
-# XXX we'll worry about the __new__/__init__ distinction later
-def new__StringType_ANY_ANY(space, w_stringtype, w_args, w_kwds):
+def type_new__StringType_StringType_ANY_ANY(space, w_basetype, w_stringtype, w_args, w_kwds):
if space.is_true(w_kwds):
raise OperationError(space.w_TypeError,
space.wrap("no keyword arguments expected"))
args = space.unpackiterable(w_args)
if len(args) == 0:
- return space.newstring([])
+ return space.newstring([]), True
elif len(args) == 1:
- return space.str(args[0])
+ return space.str(args[0]), True
else:
raise OperationError(space.w_TypeError,
space.wrap("str() takes at most 1 argument"))
Modified: pypy/trunk/src/pypy/objspace/std/test/test_dictobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/test/test_dictobject.py (original)
+++ pypy/trunk/src/pypy/objspace/std/test/test_dictobject.py Tue Jun 24 15:50:57 2003
@@ -84,7 +84,7 @@
w = space.wrap
wd = space.newdict
def mydict(w_args=w(()), w_kwds=w({})):
- return space.new(space.w_dict, w_args, w_kwds)
+ return space.call(space.w_dict, w_args, w_kwds)
def deepwrap(lp):
return [[w(a),w(b)] for a,b in lp]
d = mydict()
@@ -104,7 +104,7 @@
w = space.wrap
wd = space.newdict
def mydict(w_args=w(()), w_kwds=w({})):
- return space.new(space.w_dict, w_args, w_kwds)
+ return space.call(space.w_dict, w_args, w_kwds)
def deepwrap(lp):
return [[w(a),w(b)] for a,b in lp]
d = mydict(w_kwds=w({1:2, 3:4}))
@@ -129,7 +129,7 @@
space = self.space
w = space.wrap
def mydict(w_args=w(()), w_kwds=w({})):
- return space.new(space.w_dict, w_args, w_kwds)
+ return space.call(space.w_dict, w_args, w_kwds)
d = mydict(w_kwds=w({1:2, 3:4}))
get = space.getattr(d, w("get"))
self.assertEqual_w(space.call_function(get, w(1)), w(2))
Modified: pypy/trunk/src/pypy/objspace/std/tupletype.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/tupletype.py (original)
+++ pypy/trunk/src/pypy/objspace/std/tupletype.py Tue Jun 24 15:50:57 2003
@@ -9,8 +9,7 @@
registerimplementation(W_TupleType)
-# XXX we'll worry about the __new__/__init__ distinction later
-def tupletype_new(space, w_tupletype, w_args, w_kwds):
+def type_new__TupleType_TupleType_ANY_ANY(space, w_basetype, w_tupletype, w_args, w_kwds):
if space.is_true(w_kwds):
raise OperationError(space.w_TypeError,
space.wrap("no keyword arguments expected"))
@@ -22,6 +21,6 @@
else:
raise OperationError(space.w_TypeError,
space.wrap("tuple() takes at most 1 argument"))
- return space.newtuple(tuple_w)
+ return space.newtuple(tuple_w), True
-StdObjSpace.new.register(tupletype_new, W_TupleType, W_ANY, W_ANY)
+register_all(vars())
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 Tue Jun 24 15:50:57 2003
@@ -94,11 +94,13 @@
code = multimethods[name]
if code.bound_position < i:
continue
- if len(multimethod.specialnames) > 1:
- mmcls = SpecialMultimethodCode
- else:
- mmcls = PyMultimethodCode
- code = mmcls(multimethod, typeclass, i)
+ pycodeclass = multimethod.extras.get('pycodeclass')
+ if pycodeclass is None:
+ if len(multimethod.specialnames) > 1:
+ pycodeclass = SpecialMultimethodCode
+ else:
+ pycodeclass = PyMultimethodCode
+ code = pycodeclass(multimethod, typeclass, i)
multimethods[name] = code
# add some more multimethods with a special interface
code = NextMultimethodCode(spaceclass.next, typeclass)
@@ -182,10 +184,21 @@
result = self.do_call(space, w_globals, w_locals)
return space.newbool(result)
+class NewMultimethodCode(PyMultimethodCode):
+
+ def eval_code(self, space, w_globals, w_locals):
+ "Call the __new__() method of typetype.py."
+ w_result, callinit = self.do_call(space, w_globals, w_locals)
+ return w_result
+
def call__Type_ANY_ANY(space, w_type, w_args, w_kwds):
- w_newobject = space.new(w_type, w_args, w_kwds)
- # XXX call __init__() later
+ type_new = typetype.W_TypeType.type_new.get(space)
+ w_newobject, callinit = type_new(w_type, w_type, w_args, w_kwds)
+ if callinit:
+ import objecttype
+ object_init = objecttype.W_ObjectType.object_init.get(space)
+ object_init(w_newobject, w_args, w_kwds)
return w_newobject
def issubtype__Type_Type(space, w_type1, w_type2):
Modified: pypy/trunk/src/pypy/objspace/std/typetype.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/typetype.py (original)
+++ pypy/trunk/src/pypy/objspace/std/typetype.py Tue Jun 24 15:50:57 2003
@@ -1,5 +1,12 @@
from pypy.objspace.std.objspace import *
-from typeobject import W_TypeObject # , NewMultimethodCode
+from pypy.objspace.std.register_all import register_all
+from typeobject import W_TypeObject
+
+
+def NewMultimethodCode_builder(*args):
+ from typeobject import NewMultimethodCode # sadly necessary late import hack
+ return NewMultimethodCode(*args)
+
class W_TypeType(W_TypeObject):
"""The single instance of this class is the object the user sees as
@@ -7,22 +14,31 @@
typename = 'type'
-registerimplementation(W_TypeType)
+ # XXX this is worth tons of comments.
+ # the four arguments are (T, S, args, kw) for the expression
+ # T.__new__(S, *args, **kw). There is no (known?) way to get it as
+ # an unbound method, because 'type.__new__' means reading from the
+ # instance 'type' of the class 'type', as opposed to reading from
+ # the class 'type'.
+ # Attention, this internally returns a tuple (w_result, flag),
+ # where 'flag' specifies whether we would like __init__() to be called.
+ type_new = MultiMethod('__new__', 4, varargs=True, keywords=True,
+ pycodeclass=NewMultimethodCode_builder)
+registerimplementation(W_TypeType)
-# XXX we'll worry about the __new__/__init__ distinction later
-def new__TypeType_ANY_ANY(space, w_typetype, w_args, w_kwds):
+def type_new__TypeType_TypeType_ANY_ANY(space, w_basetype, w_typetype, w_args, w_kwds):
if space.is_true(w_kwds):
raise OperationError(space.w_TypeError,
space.wrap("no keyword arguments expected"))
args = space.unpackiterable(w_args)
if len(args) == 1:
- return space.type(args[0])
+ return space.type(args[0]), False # don't call __init__() on that
elif len(args) == 3:
from usertype import W_UserType
w_name, w_bases, w_dict = args
w_usertype = W_UserType(space, w_name, w_bases, w_dict)
- return w_usertype
+ return w_usertype, True
else:
raise OperationError(space.w_TypeError,
space.wrap("type() takes 1 or 3 arguments"))
Modified: pypy/trunk/src/pypy/objspace/std/userobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/userobject.py (original)
+++ pypy/trunk/src/pypy/objspace/std/userobject.py Tue Jun 24 15:50:57 2003
@@ -42,10 +42,11 @@
try:
return _bltin_subclass_cache[cls]
except:
- _bltin_subclass_cache[cls] = subcls = type(W_Object)("%s_sub" % cls.__name__,(cls,),
- {'statictype': W_UserType,
- 'bltbase': cls,
- 'dispatchtype': W_UserObject})
+ subcls = type(W_Object)("%s_sub" % cls.__name__, (cls,),
+ {'statictype' : W_UserType,
+ 'bltbase' : cls,
+ 'dispatchclass': W_UserObject})
+ _bltin_subclass_cache[cls] = subcls
return subcls
def morph_into_user_object(space,w_type,newobj):
@@ -109,12 +110,7 @@
self.method_name = method_name
self.bound_position = bound_position
- def do_call(self, space, args_w):
- # args_w is in the standard multimethod order
- # we need it in the Python-friendly order (i.e. swapped for __rxxx__)
- args_w = list(args_w)
- w_userobj = args_w.pop(self.bound_position)
- w_args = space.newtuple(args_w)
+ def internal_do_call(self, space, w_userobj, w_args, w_kwds):
w_key = space.wrap(self.method_name)
w_mro = space.getattr(w_userobj.w_type, space.wrap('__mro__'))
mro = space.unpacktuple(w_mro)
@@ -126,9 +122,17 @@
except KeyError:
continue
w_method = space.get(w_function, w_userobj, w_base)
- return space.call(w_method, w_args, space.newdict([]))
+ return space.call(w_method, w_args, w_kwds)
raise FailedToImplement
+ def do_call(self, space, args_w):
+ # args_w is in the standard multimethod order
+ # we need it in the Python-friendly order (i.e. swapped for __rxxx__)
+ args_w = list(args_w)
+ w_userobj = args_w.pop(self.bound_position)
+ w_args = space.newtuple(args_w)
+ return self.internal_do_call(space, w_userobj, w_args, space.newdict([]))
+
def normal_call(self, space, *args_w):
"Call a user-defined __xxx__ method and convert the result back."
w_result = self.do_call(space, args_w)
@@ -155,6 +159,10 @@
w_result = self.do_call(space, args_w)
return space.is_true(w_result)
+ def argskwds_call(self, space, w_userobj, w_args, w_kwds):
+ "For __init__()."
+ return self.internal_do_call(space, w_userobj, w_args, w_kwds)
+
import new
for multimethod in typeobject.hack_out_multimethods(StdObjSpace):
@@ -166,6 +174,6 @@
next__User = SpecialMethod('next').next_call
is_true__User = SpecialMethod('nonzero').nonzero_call
-
+object_init__User_ANY_ANY = SpecialMethod('__init__').argskwds_call
register_all(vars())
Modified: pypy/trunk/src/pypy/objspace/std/usertype.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/usertype.py (original)
+++ pypy/trunk/src/pypy/objspace/std/usertype.py Tue Jun 24 15:50:57 2003
@@ -53,17 +53,35 @@
# but we're documenting it here as there seems no better place!!!
# The problem is actually that, currently, several types such as
# int and float just cannot be CALLED -- this needs to be fixed soon.
-def new__UserType_ANY_ANY(space, w_usertype, w_args, w_kwds):
- from userobject import make_user_object
- newobj = make_user_object(space, w_usertype, w_args, w_kwds)
- try:
- init = space.getattr(newobj, space.wrap('__init__'))
- except OperationError, err:
- if not err.match(space, space.w_AttributeError):
- raise
- else:
- space.call(init, w_args, w_kwds)
- return newobj
+def type_new__UserType_UserType_ANY_ANY(space, w_basetype, w_usertype, w_args, w_kwds):
+ import typetype
+ # XXX this uses the following algorithm:
+ # walk the __mro__ of the user type
+ # for each *user* type t in there, just look for a __new__ in t.__dict__
+ # if we get to a *built-in* type t, we use t.__new__, which is a
+ # bound method from the type 'type'.
+ for w_looktype in w_basetype.getmro():
+ if not isinstance(w_looktype, W_UserType):
+ # no user-defined __new__ found
+ type_new = typetype.W_TypeType.type_new.get(space)
+ return type_new(w_looktype, w_usertype, w_args, w_kwds)
+ try:
+ w_new = w_looktype.lookup_exactly_here(space.wrap('__new__'))
+ except KeyError:
+ pass
+ else:
+ w_newobj = space.call_function(w_new, [w_usertype, w_args, w_kwds])
+ return w_newobj, True
+ raise AssertionError, "execution should not get here"
+
+def type_new__ANY_UserType_ANY_ANY(space, w_basetype, w_usertype, w_args, w_kwds):
+ import typetype
+ from userobject import morph_into_user_object, getsinglebuiltintype
+ assert w_basetype is getsinglebuiltintype(space, w_usertype)
+ type_new = typetype.W_TypeType.type_new.get(space)
+ w_newobject, callinit = type_new(w_basetype, w_basetype, w_args, w_kwds)
+ morph_into_user_object(space, w_usertype, w_newobject)
+ return w_newobject, True
def getdict__UserType(space, w_usertype):
return w_usertype.w_dict
More information about the Pypy-commit
mailing list