[pypy-commit] pypy default: Move struct.Struct to be RPYthon so we can mark fields as immutable
alex_gaynor
noreply at buildbot.pypy.org
Tue Jan 21 05:20:09 CET 2014
Author: Alex Gaynor <alex.gaynor at 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),
+)
More information about the pypy-commit
mailing list