Author: Maciej Fijalkowski <[email protected]>
Branch:
Changeset: r63983:e13cd035c6ce
Date: 2013-05-11 15:34 +0200
http://bitbucket.org/pypy/pypy/changeset/e13cd035c6ce/
Log: merge
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -5,3 +5,5 @@
.. this is a revision shortly after release-2.0
.. startrev: a13c07067613
+.. branch: numpy-pickle
+Pickling of numpy arrays and dtypes (including record dtypes)
diff --git a/pypy/interpreter/mixedmodule.py b/pypy/interpreter/mixedmodule.py
--- a/pypy/interpreter/mixedmodule.py
+++ b/pypy/interpreter/mixedmodule.py
@@ -13,6 +13,7 @@
# imported yet, and when it has been, it is mod.__dict__.items() just
# after startup().
w_initialdict = None
+ lazy = False
def __init__(self, space, w_name):
""" NOT_RPYTHON """
diff --git a/pypy/module/micronumpy/__init__.py
b/pypy/module/micronumpy/__init__.py
--- a/pypy/module/micronumpy/__init__.py
+++ b/pypy/module/micronumpy/__init__.py
@@ -12,6 +12,7 @@
'zeros': 'interp_numarray.zeros',
'empty': 'interp_numarray.zeros',
'ones': 'interp_numarray.ones',
+ '_reconstruct' : 'interp_numarray._reconstruct',
'dot': 'interp_arrayops.dot',
'fromstring': 'interp_support.fromstring',
'flatiter': 'interp_flatiter.W_FlatIterator',
diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py
b/pypy/module/micronumpy/arrayimpl/concrete.py
--- a/pypy/module/micronumpy/arrayimpl/concrete.py
+++ b/pypy/module/micronumpy/arrayimpl/concrete.py
@@ -55,6 +55,9 @@
def get_size(self):
return self.size // self.dtype.itemtype.get_element_size()
+ def get_storage_size(self):
+ return self.size
+
def reshape(self, space, orig_array, new_shape):
# Since we got to here, prod(new_shape) == self.size
new_strides = None
@@ -328,13 +331,14 @@
class ConcreteArray(ConcreteArrayNotOwning):
- def __init__(self, shape, dtype, order, strides, backstrides):
- # we allocate the actual storage later because we need to compute
- # self.size first
+ def __init__(self, shape, dtype, order, strides, backstrides,
storage=lltype.nullptr(RAW_STORAGE)):
null_storage = lltype.nullptr(RAW_STORAGE)
ConcreteArrayNotOwning.__init__(self, shape, dtype, order, strides,
backstrides,
null_storage)
- self.storage = dtype.itemtype.malloc(self.size)
+ if storage == lltype.nullptr(RAW_STORAGE):
+ self.storage = dtype.itemtype.malloc(self.size)
+ else:
+ self.storage = storage
def __del__(self):
free_raw_storage(self.storage, track_allocation=False)
diff --git a/pypy/module/micronumpy/base.py b/pypy/module/micronumpy/base.py
--- a/pypy/module/micronumpy/base.py
+++ b/pypy/module/micronumpy/base.py
@@ -35,12 +35,17 @@
return W_NDimArray(impl)
@staticmethod
- def from_shape_and_storage(shape, storage, dtype, order='C'):
+ def from_shape_and_storage(shape, storage, dtype, order='C', owning=False):
from pypy.module.micronumpy.arrayimpl import concrete
assert shape
strides, backstrides = calc_strides(shape, dtype, order)
- impl = concrete.ConcreteArrayNotOwning(shape, dtype, order, strides,
- backstrides, storage)
+ if owning:
+ # Will free storage when GCd
+ impl = concrete.ConcreteArray(shape, dtype, order, strides,
+ backstrides, storage=storage)
+ else:
+ impl = concrete.ConcreteArrayNotOwning(shape, dtype, order,
strides,
+ backstrides, storage)
return W_NDimArray(impl)
@staticmethod
diff --git a/pypy/module/micronumpy/interp_dtype.py
b/pypy/module/micronumpy/interp_dtype.py
--- a/pypy/module/micronumpy/interp_dtype.py
+++ b/pypy/module/micronumpy/interp_dtype.py
@@ -133,11 +133,46 @@
space.wrap(offset)]))
return w_d
+ def set_fields(self, space, w_fields):
+ if w_fields == space.w_None:
+ self.fields = None
+ else:
+ ofs_and_items = []
+ size = 0
+ for key in space.listview(w_fields):
+ value = space.getitem(w_fields, key)
+
+ dtype = space.getitem(value, space.wrap(0))
+ assert isinstance(dtype, W_Dtype)
+
+ offset = space.int_w(space.getitem(value, space.wrap(1)))
+ self.fields[space.str_w(key)] = offset, dtype
+
+ ofs_and_items.append((offset, dtype.itemtype))
+ size += dtype.itemtype.get_element_size()
+
+ self.itemtype = types.RecordType(ofs_and_items, size)
+ self.name = "void" + str(8 * self.itemtype.get_element_size())
+
def descr_get_names(self, space):
if self.fieldnames is None:
return space.w_None
return space.newtuple([space.wrap(name) for name in self.fieldnames])
+ def set_names(self, space, w_names):
+ if w_names == space.w_None:
+ self.fieldnames = None
+ else:
+ self.fieldnames = []
+ iter = space.iter(w_names)
+ while True:
+ try:
+ self.fieldnames.append(space.str_w(space.next(iter)))
+ except OperationError, e:
+ if not e.match(space, space.w_StopIteration):
+ raise
+ break
+
@unwrap_spec(item=str)
def descr_getitem(self, space, item):
if self.fields is None:
@@ -180,6 +215,51 @@
def get_size(self):
return self.itemtype.get_element_size()
+ def descr_reduce(self, space):
+ w_class = space.type(self)
+
+ kind = self.kind
+ elemsize = self.itemtype.get_element_size()
+ builder_args = space.newtuple([space.wrap("%s%d" % (kind, elemsize)),
space.wrap(0), space.wrap(1)])
+
+ version = space.wrap(3)
+ order = space.wrap(byteorder_prefix if self.native else
nonnative_byteorder_prefix)
+ names = self.descr_get_names(space)
+ values = self.descr_get_fields(space)
+ if self.fields:
+ #TODO: Implement this when subarrays are implemented
+ subdescr = space.w_None
+ #TODO: Change this when alignment is implemented :
+ size = 0
+ for key in self.fields:
+ dtype = self.fields[key][1]
+ assert isinstance(dtype, W_Dtype)
+ size += dtype.get_size()
+ w_size = space.wrap(size)
+ alignment = space.wrap(1)
+ else:
+ subdescr = space.w_None
+ w_size = space.wrap(-1)
+ alignment = space.wrap(-1)
+ flags = space.wrap(0)
+
+ data = space.newtuple([version, order, subdescr, names, values,
w_size, alignment, flags])
+
+ return space.newtuple([w_class, builder_args, data])
+
+ def descr_setstate(self, space, w_data):
+ if space.int_w(space.getitem(w_data, space.wrap(0))) != 3:
+ raise OperationError(space.w_NotImplementedError,
space.wrap("Pickling protocol version not supported"))
+
+ self.native = space.str_w(space.getitem(w_data, space.wrap(1))) ==
byteorder_prefix
+
+ fieldnames = space.getitem(w_data, space.wrap(3))
+ self.set_names(space, fieldnames)
+
+ fields = space.getitem(w_data, space.wrap(4))
+ self.set_fields(space, fields)
+ print self.itemtype
+
class W_ComplexDtype(W_Dtype):
def __init__(self, itemtype, num, kind, name, char, w_box_type,
alternate_constructors=[], aliases=[],
@@ -238,8 +318,7 @@
num = 20
basename = 'void'
w_box_type = space.gettypefor(interp_boxes.W_VoidBox)
- raise OperationError(space.w_NotImplementedError, space.wrap(
- "pure void dtype"))
+ return dtype_from_list(space, space.newlist([]))
else:
assert char == 'U'
basename = 'unicode'
@@ -252,9 +331,10 @@
def dtype_from_spec(space, name):
raise OperationError(space.w_NotImplementedError, space.wrap(
- "dtype from spec"))
+ "dtype from spec"))
-def descr__new__(space, w_subtype, w_dtype):
+def descr__new__(space, w_subtype, w_dtype, w_align=None, w_copy=None):
+ # w_align and w_copy are necessary for pickling
cache = get_dtype_cache(space)
if space.is_none(w_dtype):
@@ -297,6 +377,9 @@
__ne__ = interp2app(W_Dtype.descr_ne),
__getitem__ = interp2app(W_Dtype.descr_getitem),
+ __reduce__ = interp2app(W_Dtype.descr_reduce),
+ __setstate__ = interp2app(W_Dtype.descr_setstate),
+
num = interp_attrproperty("num", cls=W_Dtype),
kind = interp_attrproperty("kind", cls=W_Dtype),
char = interp_attrproperty("char", cls=W_Dtype),
diff --git a/pypy/module/micronumpy/interp_numarray.py
b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -781,6 +781,42 @@
return space.float(self.descr_getitem(space, space.wrap(0)))
raise OperationError(space.w_TypeError, space.wrap("only length-1
arrays can be converted to Python scalars"))
+ def descr_reduce(self, space):
+ from rpython.rtyper.lltypesystem import rffi
+ from rpython.rlib.rstring import StringBuilder
+ from pypy.interpreter.mixedmodule import MixedModule
+
+ numpypy = space.getbuiltinmodule("_numpypy")
+ assert isinstance(numpypy, MixedModule)
+ multiarray = numpypy.get("multiarray")
+ assert isinstance(multiarray, MixedModule)
+ reconstruct = multiarray.get("_reconstruct")
+
+ parameters = space.newtuple([space.gettypefor(W_NDimArray),
space.newtuple([space.wrap(0)]), space.wrap("b")])
+
+ builder = StringBuilder()
+ builder.append_charpsize(self.implementation.get_storage(),
self.implementation.get_storage_size())
+
+ state = space.newtuple([
+ space.wrap(1), # version
+ self.descr_get_shape(space),
+ self.get_dtype(),
+ space.wrap(False), # is_fortran
+ space.wrap(builder.build()),
+ ])
+
+ return space.newtuple([reconstruct, parameters, state])
+
+ def descr_setstate(self, space, w_state):
+ from rpython.rtyper.lltypesystem import rffi
+
+ shape = space.getitem(w_state, space.wrap(1))
+ dtype = space.getitem(w_state, space.wrap(2))
+ assert isinstance(dtype, interp_dtype.W_Dtype)
+ isfortran = space.getitem(w_state, space.wrap(3))
+ storage = space.getitem(w_state, space.wrap(4))
+
+ self.implementation =
W_NDimArray.from_shape_and_storage([space.int_w(i) for i in
space.listview(shape)], rffi.str2charp(space.str_w(storage),
track_allocation=False), dtype, owning=True).implementation
@unwrap_spec(offset=int)
@@ -814,6 +850,7 @@
W_NDimArray.typedef = TypeDef(
"ndarray",
+ __module__ = "numpypy",
__new__ = interp2app(descr_new_array),
__len__ = interp2app(W_NDimArray.descr_len),
@@ -932,6 +969,8 @@
__pypy_data__ = GetSetProperty(W_NDimArray.fget___pypy_data__,
W_NDimArray.fset___pypy_data__,
W_NDimArray.fdel___pypy_data__),
+ __reduce__ = interp2app(W_NDimArray.descr_reduce),
+ __setstate__ = interp2app(W_NDimArray.descr_setstate),
)
@unwrap_spec(ndmin=int, copy=bool, subok=bool)
@@ -1008,6 +1047,9 @@
arr.fill(one)
return space.wrap(arr)
+def _reconstruct(space, w_subtype, w_shape, w_dtype):
+ return descr_new_array(space, w_subtype, w_shape, w_dtype)
+
W_FlatIterator.typedef = TypeDef(
'flatiter',
__iter__ = interp2app(W_FlatIterator.descr_iter),
diff --git a/pypy/module/micronumpy/test/test_base.py
b/pypy/module/micronumpy/test/test_base.py
--- a/pypy/module/micronumpy/test/test_base.py
+++ b/pypy/module/micronumpy/test/test_base.py
@@ -73,8 +73,8 @@
# Coerce to floats, some of these will eventually be float16, or
# whatever our smallest float type is.
- assert find_unaryop_result_dtype(space, bool_dtype,
promote_to_float=True) is float16_dtype
- assert find_unaryop_result_dtype(space, int8_dtype,
promote_to_float=True) is float16_dtype
+ assert find_unaryop_result_dtype(space, bool_dtype,
promote_to_float=True) is float16_dtype
+ assert find_unaryop_result_dtype(space, int8_dtype,
promote_to_float=True) is float16_dtype
assert find_unaryop_result_dtype(space, uint8_dtype,
promote_to_float=True) is float16_dtype
assert find_unaryop_result_dtype(space, int16_dtype,
promote_to_float=True) is float32_dtype
assert find_unaryop_result_dtype(space, uint16_dtype,
promote_to_float=True) is float32_dtype
diff --git a/pypy/module/micronumpy/test/test_dtypes.py
b/pypy/module/micronumpy/test/test_dtypes.py
--- a/pypy/module/micronumpy/test/test_dtypes.py
+++ b/pypy/module/micronumpy/test/test_dtypes.py
@@ -14,8 +14,9 @@
from rpython.rtyper.lltypesystem import rffi
ptr_size = rffi.sizeof(rffi.CCHARP)
cls.w_ptr_size = cls.space.wrap(ptr_size)
-
+
class AppTestDtypes(BaseAppTestDtypes):
+ spaceconfig = dict(usemodules=["micronumpy", "struct", "binascii"])
def test_dtype(self):
from numpypy import dtype
@@ -149,7 +150,7 @@
def test_bool_binop_types(self):
from numpypy import array, dtype
types = [
- '?', 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'f', 'd',
+ '?', 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'f', 'd',
'e'
]
a = array([True], '?')
@@ -270,6 +271,23 @@
]:
assert hash(tp(value)) == hash(value)
+ def test_pickle(self):
+ from numpypy import array, dtype
+ from cPickle import loads, dumps
+ a = array([1,2,3])
+ assert a.dtype.__reduce__() == (dtype, ('i8', 0, 1), (3, '<', None,
None, None, -1, -1, 0))
+ assert loads(dumps(a.dtype)) == a.dtype
+
+ def test_pickle_record(self):
+ from numpypy import array, dtype
+ from cPickle import loads, dumps
+
+ d = dtype([("x", "int32"), ("y", "int32"), ("z", "int32"), ("value",
float)])
+ assert d.__reduce__() == (dtype, ('V20', 0, 1), (3, '<', None, ('x',
'y', 'z', 'value'), {'y': (dtype('int32'), 4), 'x': (dtype('int32'), 0), 'z':
(dtype('int32'), 8), 'value': (dtype('float64'), 12)}, 20, 1, 0))
+
+ new_d = loads(dumps(d))
+
+ assert new_d.__reduce__() == d.__reduce__()
class AppTestTypes(BaseAppTestDtypes):
def test_abstract_types(self):
@@ -340,7 +358,7 @@
import numpypy as numpy
assert numpy.int8.mro() == [numpy.int8, numpy.signedinteger,
- numpy.integer, numpy.number,
+ numpy.integer, numpy.number,
numpy.generic, object]
a = numpy.array([1, 2, 3], numpy.int8)
@@ -363,8 +381,8 @@
def test_uint8(self):
import numpypy as numpy
- assert numpy.uint8.mro() == [numpy.uint8, numpy.unsignedinteger,
- numpy.integer, numpy.number,
+ assert numpy.uint8.mro() == [numpy.uint8, numpy.unsignedinteger,
+ numpy.integer, numpy.number,
numpy.generic, object]
a = numpy.array([1, 2, 3], numpy.uint8)
@@ -435,8 +453,8 @@
import numpypy as numpy
assert numpy.int_ is numpy.dtype(int).type
- assert numpy.int_.mro() == [numpy.int_, numpy.signedinteger,
- numpy.integer, numpy.number,
+ assert numpy.int_.mro() == [numpy.int_, numpy.signedinteger,
+ numpy.integer, numpy.number,
numpy.generic, int, object]
def test_int64(self):
@@ -444,12 +462,12 @@
import numpypy as numpy
if sys.maxint == 2 ** 63 -1:
- assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger,
- numpy.integer, numpy.number,
+ assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger,
+ numpy.integer, numpy.number,
numpy.generic, int, object]
else:
- assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger,
- numpy.integer, numpy.number,
+ assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger,
+ numpy.integer, numpy.number,
numpy.generic, object]
assert numpy.dtype(numpy.int64).type is numpy.int64
@@ -465,8 +483,8 @@
import sys
import numpypy as numpy
- assert numpy.uint64.mro() == [numpy.uint64, numpy.unsignedinteger,
- numpy.integer, numpy.number,
+ assert numpy.uint64.mro() == [numpy.uint64, numpy.unsignedinteger,
+ numpy.integer, numpy.number,
numpy.generic, object]
assert numpy.dtype(numpy.uint64).type is numpy.uint64
@@ -481,8 +499,8 @@
def test_float16(self):
import numpypy as numpy
- assert numpy.float16.mro() == [numpy.float16, numpy.floating,
- numpy.inexact, numpy.number,
+ assert numpy.float16.mro() == [numpy.float16, numpy.floating,
+ numpy.inexact, numpy.number,
numpy.generic, object]
assert numpy.float16(12) == numpy.float64(12)
@@ -493,8 +511,8 @@
def test_float32(self):
import numpypy as numpy
- assert numpy.float32.mro() == [numpy.float32, numpy.floating,
- numpy.inexact, numpy.number,
+ assert numpy.float32.mro() == [numpy.float32, numpy.floating,
+ numpy.inexact, numpy.number,
numpy.generic, object]
assert numpy.float32(12) == numpy.float64(12)
@@ -504,8 +522,8 @@
def test_float64(self):
import numpypy as numpy
- assert numpy.float64.mro() == [numpy.float64, numpy.floating,
- numpy.inexact, numpy.number,
+ assert numpy.float64.mro() == [numpy.float64, numpy.floating,
+ numpy.inexact, numpy.number,
numpy.generic, float, object]
a = numpy.array([1, 2, 3], numpy.float64)
@@ -856,7 +874,7 @@
# it can be float96 or float128
if numpy.longfloat != numpy.float64:
assert numpy.longfloat.mro()[1:] == [numpy.floating,
- numpy.inexact, numpy.number,
+ numpy.inexact, numpy.number,
numpy.generic, object]
a = numpy.array([1, 2, 3], numpy.longdouble)
assert type(a[1]) is numpy.longdouble
@@ -898,3 +916,4 @@
a = array([1, 2, 3], dtype=self.non_native_prefix + 'G') # clongdouble
assert a[0] == 1
assert (a + a)[1] == 4
+
diff --git a/pypy/module/micronumpy/test/test_numarray.py
b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -214,6 +214,7 @@
assert get(1, 1) == 3
class AppTestNumArray(BaseNumpyAppTest):
+ spaceconfig = dict(usemodules=["micronumpy", "struct", "binascii"])
def w_CustomIndexObject(self, index):
class CustomIndexObject(object):
def __init__(self, index):
@@ -1786,6 +1787,17 @@
assert raises(TypeError, "int(array([1, 2]))")
assert int(array([1.5])) == 1
+ def test__reduce__(self):
+ from numpypy import array, dtype
+ from cPickle import loads, dumps
+
+ a = array([1, 2], dtype="int64")
+ data = a.__reduce__()
+
+ assert data[2][4] ==
'\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00'
+
+ pickled_data = dumps(a)
+ assert (loads(pickled_data) == a).all()
class AppTestMultiDim(BaseNumpyAppTest):
def test_init(self):
@@ -2534,6 +2546,8 @@
class AppTestRecordDtype(BaseNumpyAppTest):
+ spaceconfig = dict(usemodules=["micronumpy", "struct", "binascii"])
+
def test_zeros(self):
from numpypy import zeros, integer
a = zeros(2, dtype=[('x', int), ('y', float)])
@@ -2666,6 +2680,25 @@
assert s.replace('\n', '') == \
"array(['abc', 'defg', 'ab'], dtype='|S4')"
+ def test_pickle(self):
+ from numpypy import dtype, array
+ from cPickle import loads, dumps
+
+ d = dtype([('x', str), ('y', 'int32')])
+ a = array([('a', 2), ('cde', 1)], dtype=d)
+
+ a = loads(dumps(a))
+ d = a.dtype
+
+ assert str(d.fields['x'][0]) == '|S0'
+ assert d.fields['x'][1] == 0
+ assert str(d.fields['y'][0]) == 'int32'
+ assert d.fields['y'][1] == 0
+ assert d.name == 'void32'
+
+ assert a[0]['y'] == 2
+ assert a[1]['y'] == 1
+
class AppTestPyPy(BaseNumpyAppTest):
def setup_class(cls):
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
@@ -1005,6 +1005,19 @@
"""
self.optimize_loop(ops, expected)
+ def test_virtual_array_of_struct_len(self):
+ ops = """
+ []
+ p0 = new_array(2, descr=complexarraydescr)
+ i0 = arraylen_gc(p0)
+ finish(i0)
+ """
+ expected = """
+ []
+ finish(2)
+ """
+ self.optimize_loop(ops, expected)
+
def test_nonvirtual_1(self):
ops = """
[i]
diff --git a/rpython/jit/metainterp/optimizeopt/virtualize.py
b/rpython/jit/metainterp/optimizeopt/virtualize.py
--- a/rpython/jit/metainterp/optimizeopt/virtualize.py
+++ b/rpython/jit/metainterp/optimizeopt/virtualize.py
@@ -332,6 +332,9 @@
self.arraydescr = arraydescr
self._items = [{} for _ in xrange(size)]
+ def getlength(self):
+ return len(self._items)
+
def getinteriorfield(self, index, ofs, default):
return self._items[index].get(ofs, default)
diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py
--- a/rpython/rlib/rbigint.py
+++ b/rpython/rlib/rbigint.py
@@ -1314,7 +1314,8 @@
assert t1.sign >= 0
assert 2*shift + t1.numdigits() <= ret.numdigits()
- ret._digits[2*shift : 2*shift + t1.numdigits()] = t1._digits
+ for i in range(t1.numdigits()):
+ ret._digits[2*shift + i] = t1._digits[i]
# Zero-out the digits higher than the ah*bh copy. */
## ignored, assuming that we initialize to zero
@@ -1327,7 +1328,8 @@
t2 = al.mul(bl)
assert t2.sign >= 0
assert t2.numdigits() <= 2*shift # no overlap with high digits
- ret._digits[:t2.numdigits()] = t2._digits
+ for i in range(t2.numdigits()):
+ ret._digits[i] = t2._digits[i]
# Zero out remaining digits.
## ignored, assuming that we initialize to zero
diff --git a/rpython/rtyper/lltypesystem/rffi.py
b/rpython/rtyper/lltypesystem/rffi.py
--- a/rpython/rtyper/lltypesystem/rffi.py
+++ b/rpython/rtyper/lltypesystem/rffi.py
@@ -446,7 +446,7 @@
TYPES += ['__int128_t']
except CompilationError:
pass
-
+
_TYPES_ARE_UNSIGNED = set(['size_t', 'uintptr_t']) # plus "unsigned *"
if os.name != 'nt':
TYPES.append('mode_t')
@@ -693,10 +693,13 @@
builder_class = UnicodeBuilder
# str -> char*
- def str2charp(s):
+ def str2charp(s, track_allocation=True):
""" str -> char*
"""
- array = lltype.malloc(TYPEP.TO, len(s) + 1, flavor='raw')
+ if track_allocation:
+ array = lltype.malloc(TYPEP.TO, len(s) + 1, flavor='raw',
track_allocation=True)
+ else:
+ array = lltype.malloc(TYPEP.TO, len(s) + 1, flavor='raw',
track_allocation=False)
i = len(s)
array[i] = lastchar
i -= 1
@@ -704,10 +707,13 @@
array[i] = s[i]
i -= 1
return array
- str2charp._annenforceargs_ = [strtype]
+ str2charp._annenforceargs_ = [strtype, bool]
- def free_charp(cp):
- lltype.free(cp, flavor='raw')
+ def free_charp(cp, track_allocation=True):
+ if track_allocation:
+ lltype.free(cp, flavor='raw', track_allocation=True)
+ else:
+ lltype.free(cp, flavor='raw', track_allocation=False)
# char* -> str
# doesn't free char*
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit