Author: Alex Gaynor <alex.gay...@gmail.com> Branch: Changeset: r68797:496deb64bcef Date: 2014-01-20 22:19 -0600 http://bitbucket.org/pypy/pypy/changeset/496deb64bcef/
Log: Move struct.Struct to be RPYthon so we can mark fields as immutable diff --git a/pypy/module/struct/__init__.py b/pypy/module/struct/__init__.py --- a/pypy/module/struct/__init__.py +++ b/pypy/module/struct/__init__.py @@ -49,11 +49,12 @@ 'calcsize': 'interp_struct.calcsize', 'pack': 'interp_struct.pack', 'unpack': 'interp_struct.unpack', - } + + 'Struct': 'interp_struct.W_Struct', + } appleveldefs = { 'error': 'app_struct.error', 'pack_into': 'app_struct.pack_into', 'unpack_from': 'app_struct.unpack_from', - 'Struct': 'app_struct.Struct', - } + } diff --git a/pypy/module/struct/app_struct.py b/pypy/module/struct/app_struct.py --- a/pypy/module/struct/app_struct.py +++ b/pypy/module/struct/app_struct.py @@ -4,6 +4,7 @@ """ import struct + class error(Exception): """Exception raised on various occasions; argument is a string describing what is wrong.""" @@ -21,21 +22,3 @@ raise error("unpack_from requires a buffer of at least %d bytes" % (size,)) return struct.unpack(fmt, data) - -# XXX inefficient -class Struct(object): - def __init__(self, format): - self.format = format - self.size = struct.calcsize(format) - - def pack(self, *args): - return struct.pack(self.format, *args) - - def unpack(self, s): - return struct.unpack(self.format, s) - - def pack_into(self, buffer, offset, *args): - return pack_into(self.format, buffer, offset, *args) - - def unpack_from(self, buffer, offset=0): - return unpack_from(self.format, buffer, offset) diff --git a/pypy/module/struct/interp_struct.py b/pypy/module/struct/interp_struct.py --- a/pypy/module/struct/interp_struct.py +++ b/pypy/module/struct/interp_struct.py @@ -1,15 +1,23 @@ -from pypy.interpreter.gateway import unwrap_spec -from pypy.interpreter.error import OperationError -from pypy.module.struct.formatiterator import PackFormatIterator, UnpackFormatIterator from rpython.rlib import jit from rpython.rlib.rstruct.error import StructError, StructOverflowError from rpython.rlib.rstruct.formatiterator import CalcSizeFormatIterator +from pypy.interpreter.baseobjspace import W_Root +from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.error import OperationError +from pypy.interpreter.typedef import ( + TypeDef, interp_attrproperty, interp_attrproperty_w +) +from pypy.module.struct.formatiterator import ( + PackFormatIterator, UnpackFormatIterator +) + @unwrap_spec(format=str) def calcsize(space, format): return space.wrap(_calcsize(space, format)) + def _calcsize(space, format): fmtiter = CalcSizeFormatIterator() try: @@ -52,3 +60,44 @@ w_error = space.getattr(w_module, space.wrap('error')) raise OperationError(w_error, space.wrap(e.msg)) return space.newtuple(fmtiter.result_w[:]) + + +class W_Struct(W_Root): + _immutable_fields_ = ["format", "size"] + + def __init__(self, space, format): + self.format = format + self.size = _calcsize(space, format) + + @unwrap_spec(format=str) + def descr__new__(space, w_subtype, format): + self = space.allocate_instance(W_Struct, w_subtype) + W_Struct.__init__(self, space, format) + return self + + def wrap_struct_method(name): + def impl(self, space, __args__): + w_module = space.getbuiltinmodule('struct') + w_method = space.getattr(w_module, space.wrap(name)) + return space.call_obj_args( + w_method, space.wrap(self.format), __args__ + ) + + return impl + + descr_pack = wrap_struct_method("pack") + descr_unpack = wrap_struct_method("unpack") + descr_pack_into = wrap_struct_method("pack_into") + descr_unpack_from = wrap_struct_method("unpack_from") + + +W_Struct.typedef = TypeDef("Struct", + __new__=interp2app(W_Struct.descr__new__.im_func), + format=interp_attrproperty("format", cls=W_Struct), + size=interp_attrproperty("size", cls=W_Struct), + + pack=interp2app(W_Struct.descr_pack), + unpack=interp2app(W_Struct.descr_unpack), + pack_into=interp2app(W_Struct.descr_pack_into), + unpack_from=interp2app(W_Struct.descr_unpack_from), +) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit