[pypy-commit] pypy remove-remaining-smm: Kill marshal_w multimethod and clean up interp_marshal.

Manuel Jacob noreply at buildbot.pypy.org
Tue Feb 25 03:24:58 CET 2014


Author: Manuel Jacob
Branch: remove-remaining-smm
Changeset: r69376:478e415bb18d
Date: 2014-02-25 03:24 +0100
http://bitbucket.org/pypy/pypy/changeset/478e415bb18d/

Log:	Kill marshal_w multimethod and clean up interp_marshal.

diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -1732,5 +1732,4 @@
     'newdict',
     'newslice',
     'call_args',
-    'marshal_w',
 ]
diff --git a/pypy/module/marshal/interp_marshal.py b/pypy/module/marshal/interp_marshal.py
--- a/pypy/module/marshal/interp_marshal.py
+++ b/pypy/module/marshal/interp_marshal.py
@@ -3,6 +3,7 @@
 from rpython.rlib.rarithmetic import intmask
 from rpython.rlib import rstackovf
 from pypy.module._file.interp_file import W_File
+from pypy.objspace.std.marshal_impl import marshal, get_unmarshallers
 
 
 Py_MARSHAL_VERSION = 2
@@ -136,6 +137,26 @@
         raise OperationError(space.w_ValueError, space.wrap(msg))
 
 class Marshaller(_Base):
+    """
+    atomic types including typecode:
+
+    atom(tc)                    puts single typecode
+    atom_int(tc, int)           puts code and int
+    atom_int64(tc, int64)       puts code and int64
+    atom_str(tc, str)           puts code, len and string
+    atom_strlist(tc, strlist)   puts code, len and list of strings
+
+    building blocks for compound types:
+
+    start(typecode)             sets the type character
+    put(s)                      puts a string with fixed length
+    put_short(int)              puts a short integer
+    put_int(int)                puts an integer
+    put_pascal(s)               puts a short string
+    put_w_obj(w_obj)            puts a wrapped object
+    put_tuple_w(TYPE, tuple_w)  puts tuple_w, an unwrapped list of wrapped objects
+    """
+
     # _annspecialcase_ = "specialize:ctr_location" # polymorphic
     # does not work with subclassing
 
@@ -214,7 +235,7 @@
         self.put(x)
 
     def put_w_obj(self, w_obj):
-        self.space.marshal_w(w_obj, self)
+        marshal(self.space, w_obj, self)
 
     def dump_w_obj(self, w_obj):
         space = self.space
@@ -235,7 +256,7 @@
         idx = 0
         while idx < lng:
             w_obj = lst_w[idx]
-            self.space.marshal_w(w_obj, self)
+            marshal(self.space, w_obj, self)
             idx += 1
 
     def _overflow(self):
@@ -338,14 +359,11 @@
         q = '"'
     u.raise_exc('invalid typecode in unmarshal: ' + q + s + q)
 
-def register(codes, func):
-    """NOT_RPYTHON"""
-    for code in codes:
-        Unmarshaller._dispatch[ord(code)] = func
-
 
 class Unmarshaller(_Base):
     _dispatch = [invalid_typecode] * 256
+    for tc, func in get_unmarshallers():
+        _dispatch[ord(tc)] = func
 
     def __init__(self, space, reader):
         self.space = space
diff --git a/pypy/module/marshal/test/test_marshalimpl.py b/pypy/module/marshal/test/test_marshalimpl.py
--- a/pypy/module/marshal/test/test_marshalimpl.py
+++ b/pypy/module/marshal/test/test_marshalimpl.py
@@ -75,7 +75,7 @@
         expected = marshal.dumps(long(x))
         w_obj = space.wraplong(x)
         m = FakeM()
-        space.marshal_w(w_obj, m)
+        interp_marshal.marshal(space, w_obj, m)
         assert ''.join(m.seen) == expected
         #
         u = interp_marshal.StringUnmarshaller(space, space.wrap(expected))
diff --git a/pypy/objspace/std/marshal_impl.py b/pypy/objspace/std/marshal_impl.py
--- a/pypy/objspace/std/marshal_impl.py
+++ b/pypy/objspace/std/marshal_impl.py
@@ -1,38 +1,26 @@
-# implementation of marshalling by multimethods
+from rpython.rlib.rarithmetic import LONG_BIT, r_longlong, r_uint
+from rpython.rlib.rstring import StringBuilder
+from rpython.rlib.rstruct import ieee
+from rpython.rlib.unroll import unrolling_iterable
 
-"""
-The idea is to have an effective but flexible
-way to implement marshalling for the native types.
-
-The marshal_w operation is called with an object,
-a callback and a state variable.
-"""
-
-from pypy.interpreter.error import OperationError
-from pypy.objspace.std.register_all import register_all
-from rpython.rlib.rarithmetic import LONG_BIT, r_longlong, r_uint, intmask
-from pypy.objspace.std import model
-from pypy.objspace.std.dictmultiobject import W_DictMultiObject
+from pypy.interpreter.error import OperationError, oefmt
 from pypy.interpreter.special import Ellipsis
 from pypy.interpreter.pycode import PyCode
-from pypy.interpreter import gateway, unicodehelper
-from rpython.rlib.rstruct import ieee
-from rpython.rlib.rstring import StringBuilder
-
-from pypy.objspace.std.boolobject    import W_BoolObject
-from pypy.objspace.std.bytesobject  import W_BytesObject
+from pypy.interpreter import unicodehelper
+from pypy.objspace.std.boolobject import W_BoolObject
+from pypy.objspace.std.bytesobject import W_BytesObject
 from pypy.objspace.std.complexobject import W_ComplexObject
-from pypy.objspace.std.intobject     import W_IntObject
-from pypy.objspace.std.floatobject   import W_FloatObject
-from pypy.objspace.std.tupleobject   import W_AbstractTupleObject
-from pypy.objspace.std.listobject    import W_ListObject
-from pypy.objspace.std.typeobject    import W_TypeObject
-from pypy.objspace.std.longobject    import W_LongObject, newlong
-from pypy.objspace.std.smalllongobject import W_SmallLongObject
-from pypy.objspace.std.noneobject    import W_NoneObject
+from pypy.objspace.std.dictmultiobject import W_DictMultiObject
+from pypy.objspace.std.intobject import W_IntObject
+from pypy.objspace.std.floatobject import W_FloatObject
+from pypy.objspace.std.listobject import W_ListObject
+from pypy.objspace.std.longobject import W_AbstractLongObject
+from pypy.objspace.std.noneobject import W_NoneObject
+from pypy.objspace.std.setobject import W_FrozensetObject, W_SetObject
+from pypy.objspace.std.tupleobject import W_AbstractTupleObject
+from pypy.objspace.std.typeobject import W_TypeObject
 from pypy.objspace.std.unicodeobject import W_UnicodeObject
 
-from pypy.module.marshal.interp_marshal import register
 
 TYPE_NULL      = '0'
 TYPE_NONE      = 'N'
@@ -59,71 +47,87 @@
 TYPE_SET       = '<'
 TYPE_FROZENSET = '>'
 
-"""
-simple approach:
-a call to marshal_w has the following semantics:
-marshal_w receives a marshaller object which contains
-state and several methods.
 
+_marshallers = []
+_unmarshallers = []
 
-atomic types including typecode:
+def marshaller(type):
+    def _decorator(f):
+        _marshallers.append((type, f))
+        return f
+    return _decorator
 
-atom(tc)                    puts single typecode
-atom_int(tc, int)           puts code and int
-atom_int64(tc, int64)       puts code and int64
-atom_str(tc, str)           puts code, len and string
-atom_strlist(tc, strlist)   puts code, len and list of strings
+def unmarshaller(tc):
+    def _decorator(f):
+        _unmarshallers.append((tc, f))
+        return f
+    return _decorator
 
-building blocks for compound types:
+def marshal(space, w_obj, m):
+    # _marshallers_unroll is defined at the end of the file
+    for type, func in _marshallers_unroll:
+        if isinstance(w_obj, type):
+            func(space, w_obj, m)
+            return
 
-start(typecode)             sets the type character
-put(s)                      puts a string with fixed length
-put_short(int)              puts a short integer
-put_int(int)                puts an integer
-put_pascal(s)               puts a short string
-put_w_obj(w_obj)            puts a wrapped object
-put_tuple_w(TYPE, tuple_w)  puts tuple_w, an unwrapped list of wrapped objects
-"""
+    # any unknown object implementing the buffer protocol is
+    # accepted and encoded as a plain string
+    try:
+        s = space.bufferstr_w(w_obj)
+    except OperationError as e:
+        if e.match(space, space.w_TypeError):
+            raise oefmt(space.w_ValueError, "unmarshallable object")
+        raise
+    m.atom_str(TYPE_STRING, s)
 
-handled_by_any = []
+def get_unmarshallers():
+    return _unmarshallers
 
-def raise_exception(space, msg):
-    raise OperationError(space.w_ValueError, space.wrap(msg))
 
-def marshal_w__None(space, w_none, m):
+ at marshaller(W_NoneObject)
+def marshal_none(space, w_none, m):
     m.atom(TYPE_NONE)
 
-def unmarshal_None(space, u, tc):
+ at unmarshaller(TYPE_NONE)
+def unmarshal_none(space, u, tc):
     return space.w_None
-register(TYPE_NONE, unmarshal_None)
 
-def marshal_w__Bool(space, w_bool, m):
+
+ at marshaller(W_BoolObject)
+def marshal_bool(space, w_bool, m):
     m.atom(TYPE_TRUE if w_bool.intval else TYPE_FALSE)
 
-def unmarshal_Bool(space, u, tc):
-    return space.newbool(tc == TYPE_TRUE)
-register(TYPE_TRUE + TYPE_FALSE, unmarshal_Bool)
+ at unmarshaller(TYPE_TRUE)
+def unmarshal_bool(space, u, tc):
+    return space.w_True
 
-def marshal_w__Type(space, w_type, m):
+ at unmarshaller(TYPE_FALSE)
+def unmarshal_false(space, u, tc):
+    return space.w_False
+
+
+ at marshaller(W_TypeObject)
+def marshal_stopiter(space, w_type, m):
     if not space.is_w(w_type, space.w_StopIteration):
-        raise_exception(space, "unmarshallable object")
+        raise oefmt(space.w_ValueError, "unmarshallable object")
     m.atom(TYPE_STOPITER)
 
-def unmarshal_Type(space, u, tc):
+ at unmarshaller(TYPE_STOPITER)
+def unmarshal_stopiter(space, u, tc):
     return space.w_StopIteration
-register(TYPE_STOPITER, unmarshal_Type)
 
-# not directly supported:
-def marshal_w_Ellipsis(space, w_ellipsis, m):
+
+ at marshaller(Ellipsis)
+def marshal_ellipsis(space, w_ellipsis, m):
     m.atom(TYPE_ELLIPSIS)
 
-model.MM.marshal_w.register(marshal_w_Ellipsis, Ellipsis)
+ at unmarshaller(TYPE_ELLIPSIS)
+def unmarshal_ellipsis(space, u, tc):
+    return space.w_Ellipsis
 
-def unmarshal_Ellipsis(space, u, tc):
-    return space.w_Ellipsis
-register(TYPE_ELLIPSIS, unmarshal_Ellipsis)
 
-def marshal_w__Int(space, w_int, m):
+ at marshaller(W_IntObject)
+def marshal_int(space, w_int, m):
     if LONG_BIT == 32:
         m.atom_int(TYPE_INT, w_int.intval)
     else:
@@ -133,11 +137,12 @@
         else:
             m.atom_int(TYPE_INT, w_int.intval)
 
-def unmarshal_Int(space, u, tc):
+ at unmarshaller(TYPE_INT)
+def unmarshal_int(space, u, tc):
     return space.newint(u.get_int())
-register(TYPE_INT, unmarshal_Int)
 
-def unmarshal_Int64(space, u, tc):
+ at unmarshaller(TYPE_INT64)
+def unmarshal_int64(space, u, tc):
     lo = u.get_int()    # get the first 32 bits
     hi = u.get_int()    # get the next 32 bits
     if LONG_BIT >= 64:
@@ -145,63 +150,10 @@
     else:
         x = (r_longlong(hi) << 32) | r_longlong(r_uint(lo))  # get a r_longlong
     return space.wrap(x)
-register(TYPE_INT64, unmarshal_Int64)
 
-def pack_float(f):
-    result = StringBuilder(8)
-    ieee.pack_float(result, f, 8, False)
-    return result.build()
 
-def unpack_float(s):
-    return ieee.unpack_float(s, False)
-
-def marshal_w__Float(space, w_float, m):
-    if m.version > 1:
-        m.start(TYPE_BINARY_FLOAT)
-        m.put(pack_float(w_float.floatval))
-    else:
-        m.start(TYPE_FLOAT)
-        m.put_pascal(space.str_w(space.repr(w_float)))
-
-def unmarshal_Float(space, u, tc):
-    return space.call_function(space.builtin.get('float'),
-                               space.wrap(u.get_pascal()))
-register(TYPE_FLOAT, unmarshal_Float)
-
-def unmarshal_Float_bin(space, u, tc):
-    return space.newfloat(unpack_float(u.get(8)))
-register(TYPE_BINARY_FLOAT, unmarshal_Float_bin)
-
-def marshal_w__Complex(space, w_complex, m):
-    if m.version > 1:
-        m.start(TYPE_BINARY_COMPLEX)
-        m.put(pack_float(w_complex.realval))
-        m.put(pack_float(w_complex.imagval))
-    else:
-        # XXX a bit too wrap-happy
-        w_real = space.wrap(w_complex.realval)
-        w_imag = space.wrap(w_complex.imagval)
-        m.start(TYPE_COMPLEX)
-        m.put_pascal(space.str_w(space.repr(w_real)))
-        m.put_pascal(space.str_w(space.repr(w_imag)))
-
-def unmarshal_Complex(space, u, tc):
-    w_real = space.call_function(space.builtin.get('float'),
-                                 space.wrap(u.get_pascal()))
-    w_imag = space.call_function(space.builtin.get('float'),
-                                 space.wrap(u.get_pascal()))
-    w_t = space.builtin.get('complex')
-    return space.call_function(w_t, w_real, w_imag)
-register(TYPE_COMPLEX, unmarshal_Complex)
-
-def unmarshal_Complex_bin(space, u, tc):
-    real = unpack_float(u.get(8))
-    imag = unpack_float(u.get(8))
-    return space.newcomplex(real, imag)
-register(TYPE_BINARY_COMPLEX, unmarshal_Complex_bin)
-
-def marshal_w__Long(space, w_long, m):
-    from rpython.rlib.rbigint import rbigint
+ at marshaller(W_AbstractLongObject)
+def marshal_long(space, w_long, m):
     from rpython.rlib.rarithmetic import r_ulonglong
     m.start(TYPE_LONG)
     SHIFT = 15
@@ -216,9 +168,9 @@
         next = num.abs_rshift_and_mask(bigshiftcount, MASK)
         m.put_short(next)
         bigshiftcount += SHIFT
-marshal_w__SmallLong = marshal_w__Long
 
-def unmarshal_Long(space, u, tc):
+ at unmarshaller(TYPE_LONG)
+def unmarshal_long(space, u, tc):
     from rpython.rlib.rbigint import rbigint
     lng = u.get_int()
     if lng < 0:
@@ -229,12 +181,68 @@
     digits = [u.get_short() for i in range(lng)]
     result = rbigint.from_list_n_bits(digits, 15)
     if lng and not result.tobool():
-        raise_exception(space, 'bad marshal data')
+        raise oefmt(space.w_ValueError, "bad marshal data")
     if negative:
         result = result.neg()
-    w_long = newlong(space, result)
-    return w_long
-register(TYPE_LONG, unmarshal_Long)
+    return space.newlong_from_rbigint(result)
+
+
+def pack_float(f):
+    result = StringBuilder(8)
+    ieee.pack_float(result, f, 8, False)
+    return result.build()
+
+def unpack_float(s):
+    return ieee.unpack_float(s, False)
+
+ at marshaller(W_FloatObject)
+def marshal_float(space, w_float, m):
+    if m.version > 1:
+        m.start(TYPE_BINARY_FLOAT)
+        m.put(pack_float(w_float.floatval))
+    else:
+        m.start(TYPE_FLOAT)
+        m.put_pascal(space.str_w(space.repr(w_float)))
+
+ at unmarshaller(TYPE_FLOAT)
+def unmarshal_float(space, u, tc):
+    return space.call_function(space.builtin.get('float'),
+                               space.wrap(u.get_pascal()))
+
+ at unmarshaller(TYPE_BINARY_FLOAT)
+def unmarshal_float_bin(space, u, tc):
+    return space.newfloat(unpack_float(u.get(8)))
+
+
+ at marshaller(W_ComplexObject)
+def marshal_complex(space, w_complex, m):
+    if m.version > 1:
+        m.start(TYPE_BINARY_COMPLEX)
+        m.put(pack_float(w_complex.realval))
+        m.put(pack_float(w_complex.imagval))
+    else:
+        # XXX a bit too wrap-happy
+        w_real = space.wrap(w_complex.realval)
+        w_imag = space.wrap(w_complex.imagval)
+        m.start(TYPE_COMPLEX)
+        m.put_pascal(space.str_w(space.repr(w_real)))
+        m.put_pascal(space.str_w(space.repr(w_imag)))
+
+ at unmarshaller(TYPE_COMPLEX)
+def unmarshal_complex(space, u, tc):
+    w_real = space.call_function(space.builtin.get('float'),
+                                 space.wrap(u.get_pascal()))
+    w_imag = space.call_function(space.builtin.get('float'),
+                                 space.wrap(u.get_pascal()))
+    w_t = space.builtin.get('complex')
+    return space.call_function(w_t, w_real, w_imag)
+
+ at unmarshaller(TYPE_BINARY_COMPLEX)
+def unmarshal_complex_bin(space, u, tc):
+    real = unpack_float(u.get(8))
+    imag = unpack_float(u.get(8))
+    return space.newcomplex(real, imag)
+
 
 # XXX currently, intern() is at applevel,
 # and there is no interface to get at the
@@ -244,10 +252,8 @@
 def PySTRING_CHECK_INTERNED(w_str):
     return False
 
+ at marshaller(W_BytesObject)
 def marshal_bytes(space, w_str, m):
-    if not isinstance(w_str, W_BytesObject):
-        raise_exception(space, "unmarshallable object")
-
     s = space.str_w(w_str)
     if m.version >= 1 and PySTRING_CHECK_INTERNED(w_str):
         # we use a native rtyper stringdict for speed
@@ -260,63 +266,60 @@
             m.atom_str(TYPE_INTERNED, s)
     else:
         m.atom_str(TYPE_STRING, s)
-handled_by_any.append(('str', marshal_bytes))
 
+ at unmarshaller(TYPE_STRING)
 def unmarshal_bytes(space, u, tc):
     return space.wrap(u.get_str())
-register(TYPE_STRING, unmarshal_bytes)
 
+ at unmarshaller(TYPE_INTERNED)
 def unmarshal_interned(space, u, tc):
     w_ret = space.wrap(u.get_str())
     u.stringtable_w.append(w_ret)
     w_intern = space.builtin.get('intern')
     space.call_function(w_intern, w_ret)
     return w_ret
-register(TYPE_INTERNED, unmarshal_interned)
 
+ at unmarshaller(TYPE_STRINGREF)
 def unmarshal_stringref(space, u, tc):
     idx = u.get_int()
     try:
         return u.stringtable_w[idx]
     except IndexError:
-        raise_exception(space, 'bad marshal data')
-register(TYPE_STRINGREF, unmarshal_stringref)
+        raise oefmt(space.w_ValueError, "bad marshal data")
 
+
+ at marshaller(W_AbstractTupleObject)
 def marshal_tuple(space, w_tuple, m):
-    if not isinstance(w_tuple, W_AbstractTupleObject):
-        raise_exception(space, "unmarshallable object")
     items = w_tuple.tolist()
     m.put_tuple_w(TYPE_TUPLE, items)
-handled_by_any.append(('tuple', marshal_tuple))
 
+ at unmarshaller(TYPE_TUPLE)
 def unmarshal_tuple(space, u, tc):
     items_w = u.get_tuple_w()
     return space.newtuple(items_w)
-register(TYPE_TUPLE, unmarshal_tuple)
 
+
+ at marshaller(W_ListObject)
 def marshal_list(space, w_list, m):
-    if not isinstance(w_list, W_ListObject):
-        raise_exception(space, "unmarshallable object")
     items = w_list.getitems()[:]
     m.put_tuple_w(TYPE_LIST, items)
-handled_by_any.append(('list', marshal_list))
 
+ at unmarshaller(TYPE_LIST)
 def unmarshal_list(space, u, tc):
     items_w = u.get_list_w()
     return space.newlist(items_w)
-register(TYPE_LIST, unmarshal_list)
 
-def marshal_w_dict(space, w_dict, m):
-    if not isinstance(w_dict, W_DictMultiObject):
-        raise_exception(space, "unmarshallable object")
+
+ at marshaller(W_DictMultiObject)
+def marshal_dict(space, w_dict, m):
     m.start(TYPE_DICT)
     for w_tuple in w_dict.items():
         w_key, w_value = space.fixedview(w_tuple, 2)
         m.put_w_obj(w_key)
         m.put_w_obj(w_value)
     m.atom(TYPE_NULL)
-handled_by_any.append(('dict', marshal_w_dict))
 
+ at unmarshaller(TYPE_DICT)
 def unmarshal_dict(space, u, tc):
     # since primitive lists are not optimized and we don't know
     # the dict size in advance, use the dict's setitem instead
@@ -329,14 +332,14 @@
         w_value = u.get_w_obj()
         space.setitem(w_dic, w_key, w_value)
     return w_dic
-register(TYPE_DICT, unmarshal_dict)
 
+ at unmarshaller(TYPE_NULL)
 def unmarshal_NULL(self, u, tc):
     return None
-register(TYPE_NULL, unmarshal_NULL)
 
-# this one is registered by hand:
-def marshal_w_pycode(space, w_pycode, m):
+
+ at marshaller(PyCode)
+def marshal_pycode(space, w_pycode, m):
     m.start(TYPE_CODE)
     # see pypy.interpreter.pycode for the layout
     x = space.interp_w(PyCode, w_pycode)
@@ -355,8 +358,6 @@
     m.put_int(x.co_firstlineno)
     m.atom_str(TYPE_STRING, x.co_lnotab)
 
-model.MM.marshal_w.register(marshal_w_pycode, PyCode)
-
 # helper for unmarshalling string lists of code objects.
 # unfortunately they now can be interned or referenced,
 # so we no longer can handle it in interp_marshal.atom_strlist
@@ -365,22 +366,16 @@
     w_obj = u.get_w_obj()
     try:
         return u.space.str_w(w_obj)
-    except OperationError, e:
+    except OperationError as e:
         if e.match(u.space, u.space.w_TypeError):
             u.raise_exc('invalid marshal data for code object')
-        else:
-            raise
+        raise
 
 def unmarshal_strlist(u, tc):
     lng = u.atom_lng(tc)
-    res = [None] * lng
-    idx = 0
-    space = u.space
-    while idx < lng:
-        res[idx] = unmarshal_str(u)
-        idx += 1
-    return res
+    return [unmarshal_str(u) for i in range(lng)]
 
+ at unmarshaller(TYPE_CODE)
 def unmarshal_pycode(space, u, tc):
     argcount    = u.get_int()
     nlocals     = u.get_int()
@@ -398,78 +393,39 @@
     name        = unmarshal_str(u)
     firstlineno = u.get_int()
     lnotab      = unmarshal_str(u)
-    code = PyCode(space, argcount, nlocals, stacksize, flags,
+    return PyCode(space, argcount, nlocals, stacksize, flags,
                   code, consts_w[:], names, varnames, filename,
                   name, firstlineno, lnotab, freevars, cellvars)
-    return space.wrap(code)
-register(TYPE_CODE, unmarshal_pycode)
 
+
+ at marshaller(W_UnicodeObject)
 def marshal_unicode(space, w_unicode, m):
-    if not isinstance(w_unicode, W_UnicodeObject):
-        raise_exception(space, "unmarshallable object")
     s = unicodehelper.encode_utf8(space, space.unicode_w(w_unicode))
     m.atom_str(TYPE_UNICODE, s)
-handled_by_any.append(('unicode', marshal_unicode))
 
+ at unmarshaller(TYPE_UNICODE)
 def unmarshal_unicode(space, u, tc):
     return space.wrap(unicodehelper.decode_utf8(space, u.get_str()))
-register(TYPE_UNICODE, unmarshal_unicode)
 
-app = gateway.applevel(r'''
-    def tuple_to_set(datalist, frozen=False):
-        if frozen:
-            return frozenset(datalist)
-        return set(datalist)
-''')
 
-tuple_to_set = app.interphook('tuple_to_set')
-
-# not directly supported:
-def marshal_w_set(space, w_set, m):
-    # cannot access this list directly, because it's
-    # type is not exactly known through applevel.
+ at marshaller(W_SetObject)
+def marshal_set(space, w_set, m):
     lis_w = space.fixedview(w_set)
     m.put_tuple_w(TYPE_SET, lis_w)
 
-handled_by_any.append( ('set', marshal_w_set) )
+ at unmarshaller(TYPE_SET)
+def unmarshal_set(space, u, tc):
+    return space.newset(u.get_tuple_w())
 
-# not directly supported:
-def marshal_w_frozenset(space, w_frozenset, m):
+
+ at marshaller(W_FrozensetObject)
+def marshal_frozenset(space, w_frozenset, m):
     lis_w = space.fixedview(w_frozenset)
     m.put_tuple_w(TYPE_FROZENSET, lis_w)
 
-handled_by_any.append( ('frozenset', marshal_w_frozenset) )
+ at unmarshaller(TYPE_FROZENSET)
+def unmarshal_frozenset(space, u, tc):
+    return space.newfrozenset(u.get_tuple_w())
 
-def unmarshal_set_frozenset(space, u, tc):
-    items_w = u.get_tuple_w()
-    if tc == TYPE_SET:
-        w_frozen = space.w_False
-    else:
-        w_frozen = space.w_True
-    w_tup = space.newtuple(items_w)
-    return tuple_to_set(space, w_tup, w_frozen)
-register(TYPE_SET + TYPE_FROZENSET, unmarshal_set_frozenset)
 
-# dispatching for all not directly dispatched types
-def marshal_w__ANY(space, w_obj, m):
-    w_type = space.type(w_obj)
-    for name, func in handled_by_any:
-        w_t = space.builtin.get(name)
-        if space.is_true(space.issubtype(w_type, w_t)):
-            func(space, w_obj, m)
-            return
-
-    # any unknown object implementing the buffer protocol is
-    # accepted and encoded as a plain string
-    try:
-        s = space.bufferstr_w(w_obj)
-    except OperationError, e:
-        if not e.match(space, space.w_TypeError):
-            raise
-    else:
-        m.atom_str(TYPE_STRING, s)
-        return
-
-    raise_exception(space, "unmarshallable object")
-
-register_all(vars())
+_marshallers_unroll = unrolling_iterable(_marshallers)
diff --git a/pypy/objspace/std/model.py b/pypy/objspace/std/model.py
--- a/pypy/objspace/std/model.py
+++ b/pypy/objspace/std/model.py
@@ -55,8 +55,6 @@
         from pypy.objspace.std import dictproxyobject
         from pypy.objspace.std import proxyobject
 
-        import pypy.objspace.std.marshal_impl # install marshal multimethods
-
 
         self.pythontypes = []
         self.pythontypes.append(objectobject.W_ObjectObject.typedef)
@@ -344,10 +342,6 @@
                                      general__args__=True)
     init    = StdObjSpaceMultiMethod('__init__', 1, general__args__=True)
     getnewargs = StdObjSpaceMultiMethod('__getnewargs__', 1)
-    # special visible multimethods
-    # NOTE: when adding more sometype_w() methods, you need to write a
-    # stub in default.py to raise a space.w_TypeError
-    marshal_w = StdObjSpaceMultiMethod('marshal_w', 1, [], extra_args=['marshaller'])
 
     # add all regular multimethods here
     for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable:
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -304,9 +304,15 @@
                 self, module=module, instance=instance,
                 strdict=strdict, kwargs=kwargs)
 
-    def newset(self):
-        from pypy.objspace.std.setobject import newset
-        return W_SetObject(self, None)
+    def newset(self, iterable_w=None):
+        if iterable_w is None:
+            return W_FrozensetObject(self, None)
+        return W_SetObject(self, self.newtuple(iterable_w))
+
+    def newfrozenset(self, iterable_w=None):
+        if iterable_w is None:
+            return W_FrozensetObject(self, None)
+        return W_FrozensetObject(self, self.newtuple(iterable_w))
 
     def newslice(self, w_start, w_end, w_step):
         return W_SliceObject(w_start, w_end, w_step)


More information about the pypy-commit mailing list