Author: Antonio Cuni <[email protected]>
Branch: ndarray-buffer
Changeset: r68316:eda923010bdb
Date: 2013-11-25 11:44 +0100
http://bitbucket.org/pypy/pypy/changeset/eda923010bdb/
Log: hg merge default
diff --git a/lib-python/2.7/socket.py b/lib-python/2.7/socket.py
--- a/lib-python/2.7/socket.py
+++ b/lib-python/2.7/socket.py
@@ -335,9 +335,10 @@
s = self._sock
self._sock = None
if s is not None:
- s._drop()
if self._close:
s.close()
+ else:
+ s._drop()
def __del__(self):
try:
diff --git a/lib_pypy/pyrepl/simple_interact.py
b/lib_pypy/pyrepl/simple_interact.py
--- a/lib_pypy/pyrepl/simple_interact.py
+++ b/lib_pypy/pyrepl/simple_interact.py
@@ -63,3 +63,6 @@
except KeyboardInterrupt:
console.write("\nKeyboardInterrupt\n")
console.resetbuffer()
+ except MemoryError:
+ console.write("\nMemoryError\n")
+ console.resetbuffer()
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
@@ -15,3 +15,6 @@
.. branch: armhf-singlefloat
JIT support for singlefloats on ARM using the hardfloat ABI
+
+.. branch: voidtype_strformat
+Better support for record numpy arrays
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -26,6 +26,7 @@
from pypy.module.__builtin__.descriptor import W_Property
from pypy.module.__builtin__.interp_classobj import W_ClassObject
from pypy.module.__builtin__.interp_memoryview import W_MemoryView
+from pypy.module.micronumpy.base import W_NDimArray
from rpython.rlib.entrypoint import entrypoint_lowlevel
from rpython.rlib.rposix import is_valid_fd, validate_fd
from rpython.rlib.unroll import unrolling_iterable
@@ -469,6 +470,7 @@
"Complex": "space.w_complex",
"ByteArray": "space.w_bytearray",
"MemoryView": "space.gettypeobject(W_MemoryView.typedef)",
+ "Array": "space.gettypeobject(W_NDimArray.typedef)",
"BaseObject": "space.w_object",
'None': 'space.type(space.w_None)',
'NotImplemented': 'space.type(space.w_NotImplemented)',
diff --git a/pypy/module/cpyext/include/pyconfig.h
b/pypy/module/cpyext/include/pyconfig.h
--- a/pypy/module/cpyext/include/pyconfig.h
+++ b/pypy/module/cpyext/include/pyconfig.h
@@ -25,6 +25,22 @@
#define Py_UNICODE_SIZE 2
#endif
+#ifndef Py_BUILD_CORE /* not building the core - must be an ext */
+# if defined(_MSC_VER)
+ /* So MSVC users need not specify the .lib file in
+ * their Makefile (other compilers are generally
+ * taken care of by distutils.) */
+# ifdef _DEBUG
+# error("debug first with cpython")
+# pragma comment(lib,"python27.lib")
+# else
+# pragma comment(lib,"python27.lib")
+# endif /* _DEBUG */
+# endif
+#endif /* _MSC_VER */
+
+
+
#ifdef __cplusplus
}
#endif
diff --git a/pypy/module/cpyext/src/ndarrayobject.c
b/pypy/module/cpyext/src/ndarrayobject.c
--- a/pypy/module/cpyext/src/ndarrayobject.c
+++ b/pypy/module/cpyext/src/ndarrayobject.c
@@ -3,8 +3,6 @@
#include "numpy/arrayobject.h"
#include <string.h> /* memset, memcpy */
-PyTypeObject PyArray_Type;
-
void
_PyArray_FILLWBYTE(PyObject* obj, int val) {
memset(PyArray_DATA(obj), val, PyArray_NBYTES(obj));
diff --git a/pypy/module/cpyext/test/test_ndarrayobject.py
b/pypy/module/cpyext/test/test_ndarrayobject.py
--- a/pypy/module/cpyext/test/test_ndarrayobject.py
+++ b/pypy/module/cpyext/test/test_ndarrayobject.py
@@ -286,3 +286,19 @@
assert dt.num == 11
+ def test_pass_ndarray_object_to_c(self):
+ from _numpypy.multiarray import ndarray
+ mod = self.import_extension('foo', [
+ ("check_array", "METH_VARARGS",
+ '''
+ PyObject* obj;
+ if (!PyArg_ParseTuple(args, "O!", &PyArray_Type, &obj))
+ return NULL;
+ Py_INCREF(obj);
+ return obj;
+ '''),
+ ], prologue='#include <numpy/arrayobject.h>')
+ array = ndarray((3, 4), dtype='d')
+ assert mod.check_array(array) is array
+ raises(TypeError, "mod.check_array(42)")
+
diff --git a/pypy/module/itertools/interp_itertools.py
b/pypy/module/itertools/interp_itertools.py
--- a/pypy/module/itertools/interp_itertools.py
+++ b/pypy/module/itertools/interp_itertools.py
@@ -342,10 +342,8 @@
if space.is_w(w_startstop, space.w_None):
start = 0
else:
- start = space.int_w(w_startstop)
- if start < 0:
- raise OperationError(space.w_ValueError, space.wrap(
- "Indicies for islice() must be non-negative integers."))
+ start = self.arg_int_w(w_startstop, 0,
+ "Indicies for islice() must be None or non-negative integers")
w_stop = args_w[0]
else:
raise OperationError(space.w_TypeError, space.wrap("islice() takes
at most 4 arguments (" + str(num_args) + " given)"))
@@ -353,10 +351,8 @@
if space.is_w(w_stop, space.w_None):
stop = -1
else:
- stop = space.int_w(w_stop)
- if stop < 0:
- raise OperationError(space.w_ValueError, space.wrap(
- "Stop argument must be a non-negative integer or None."))
+ stop = self.arg_int_w(w_stop, 0,
+ "Stop argument must be a non-negative integer or None.")
stop = max(start, stop) # for obscure CPython compatibility
if num_args == 2:
@@ -364,10 +360,8 @@
if space.is_w(w_step, space.w_None):
step = 1
else:
- step = space.int_w(w_step)
- if step < 1:
- raise OperationError(space.w_ValueError, space.wrap(
- "Step must be one or lager for islice()."))
+ step = self.arg_int_w(w_step, 1,
+ "Step for islice() must be a positive integer or None")
else:
step = 1
@@ -375,6 +369,18 @@
self.start = start
self.stop = stop
+ def arg_int_w(self, w_obj, minimum, errormsg):
+ space = self.space
+ try:
+ result = space.int_w(w_obj)
+ except OperationError, e:
+ if e.async(space):
+ raise
+ result = -1
+ if result < minimum:
+ raise OperationError(space.w_ValueError, space.wrap(errormsg))
+ return result
+
def iter_w(self):
return self.space.wrap(self)
diff --git a/pypy/module/itertools/test/test_itertools.py
b/pypy/module/itertools/test/test_itertools.py
--- a/pypy/module/itertools/test/test_itertools.py
+++ b/pypy/module/itertools/test/test_itertools.py
@@ -304,6 +304,11 @@
raises(TypeError, itertools.islice, [], 0, 0, 0, 0)
+ # why not TypeError? Because CPython
+ raises(ValueError, itertools.islice, [], "a", 1, 2)
+ raises(ValueError, itertools.islice, [], 0, "a", 2)
+ raises(ValueError, itertools.islice, [], 0, 1, "a")
+
def test_chain(self):
import itertools
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
@@ -56,6 +56,8 @@
self.aliases = aliases
self.float_type = float_type
self.fields = fields
+ if fieldnames is None:
+ fieldnames = []
self.fieldnames = fieldnames
self.shape = list(shape)
self.subdtype = subdtype
@@ -214,15 +216,15 @@
self.name = "void" + str(8 * self.get_size())
def descr_get_names(self, space):
- if self.fieldnames is None:
+ if len(self.fieldnames) == 0:
return space.w_None
return space.newtuple([space.wrap(name) for name in self.fieldnames])
def set_names(self, space, w_names):
+ self.fieldnames = []
if w_names == space.w_None:
- self.fieldnames = None
+ return
else:
- self.fieldnames = []
iter = space.iter(w_names)
while True:
try:
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
@@ -252,12 +252,13 @@
return space.wrap(self.dump_data())
return space.call_function(cache.w_array_str, self)
- def dump_data(self):
+ def dump_data(self, prefix='array(', suffix=')'):
i = self.create_iter()
first = True
dtype = self.get_dtype()
s = StringBuilder()
- s.append('array([')
+ s.append(prefix)
+ s.append('[')
while not i.done():
if first:
first = False
@@ -265,7 +266,8 @@
s.append(', ')
s.append(dtype.itemtype.str_format(i.getitem()))
i.next()
- s.append('])')
+ s.append(']')
+ s.append(suffix)
return s.build()
def create_iter(self, shape=None, backward_broadcast=False,
require_index=False):
diff --git a/pypy/module/micronumpy/iter.py b/pypy/module/micronumpy/iter.py
--- a/pypy/module/micronumpy/iter.py
+++ b/pypy/module/micronumpy/iter.py
@@ -61,10 +61,22 @@
def apply(self, space, orig_arr):
arr = orig_arr.implementation
ofs, subdtype = arr.dtype.fields[self.name]
- # strides backstrides are identical, ofs only changes start
- return W_NDimArray.new_slice(space, arr.start + ofs, arr.get_strides(),
- arr.get_backstrides(),
- arr.shape, arr, orig_arr, subdtype)
+ # ofs only changes start
+ # create a view of the original array by extending
+ # the shape, strides, backstrides of the array
+ from pypy.module.micronumpy.support import calc_strides
+ strides, backstrides = calc_strides(subdtype.shape,
+ subdtype.subdtype, arr.order)
+ final_shape = arr.shape + subdtype.shape
+ final_strides = arr.get_strides() + strides
+ final_backstrides = arr.get_backstrides() + backstrides
+ final_dtype = subdtype
+ print self.name,'strides',arr.get_strides(),strides
+ if subdtype.subdtype:
+ final_dtype = subdtype.subdtype
+ return W_NDimArray.new_slice(space, arr.start + ofs, final_strides,
+ final_backstrides,
+ final_shape, arr, orig_arr, final_dtype)
class Chunks(BaseChunk):
def __init__(self, l):
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
@@ -3138,7 +3138,9 @@
]
h = np.array(buf, dtype=descr)
assert len(h) == 2
- skip('broken') # XXX
+ assert h['x'].shape == (2, 2)
+ assert h['y'].strides == (41, 16, 8)
+ assert h['z'].shape == (2,)
for v in (h, h[0], h['x']):
repr(v) # check for crash in repr
assert (h['x'] == np.array([buf[0][0],
@@ -3169,6 +3171,22 @@
assert len(list(a[0])) == 2
+ def test_3d_record(self):
+ from numpypy import dtype, array
+ dt = dtype([('name', 'S4'), ('x', float), ('y', float),
+ ('block', int, (2, 2, 3))])
+ a = array([('aaaa', 1.0, 8.0, [[[1, 2, 3], [4, 5, 6]],
+ [[7, 8, 9], [10, 11, 12]]])],
+ dtype=dt)
+ s = str(a)
+ i = a.item()
+ assert isinstance(i, tuple)
+ assert len(i) == 4
+ skip('incorrect formatting via dump_data')
+ assert s.endswith("[('aaaa', 1.0, 8.0, [[[1, 2, 3], [4, 5, 6]], "
+ "[[7, 8, 9], [10, 11, 12]]])]")
+
+
def test_issue_1589(self):
import numpypy as numpy
c = numpy.array([[(1, 2, 'a'), (3, 4, 'b')], [(5, 6, 'c'), (7, 8,
'd')]],
diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py
--- a/pypy/module/micronumpy/types.py
+++ b/pypy/module/micronumpy/types.py
@@ -1789,6 +1789,40 @@
dtype.subdtype)
return W_NDimArray(implementation)
+ def read(self, arr, i, offset, dtype=None):
+ if dtype is None:
+ dtype = arr.dtype
+ return interp_boxes.W_VoidBox(arr, i + offset, dtype)
+
+ @jit.unroll_safe
+ def str_format(self, box):
+ assert isinstance(box, interp_boxes.W_VoidBox)
+ arr = self.readarray(box.arr, box.ofs, 0, box.dtype)
+ return arr.dump_data(prefix='', suffix='')
+
+ def to_builtin_type(self, space, item):
+ ''' From the documentation of ndarray.item():
+ "Void arrays return a buffer object for item(),
+ unless fields are defined, in which case a tuple is returned."
+ '''
+ assert isinstance(item, interp_boxes.W_VoidBox)
+ dt = item.arr.dtype
+ ret_unwrapped = []
+ for name in dt.fieldnames:
+ ofs, dtype = dt.fields[name]
+ if isinstance(dtype.itemtype, VoidType):
+ read_val = dtype.itemtype.readarray(item.arr, ofs, 0, dtype)
+ else:
+ read_val = dtype.itemtype.read(item.arr, ofs, 0, dtype)
+ if isinstance (read_val, interp_boxes.W_StringBox):
+ # StringType returns a str
+ read_val = space.wrap(dtype.itemtype.to_str(read_val))
+ ret_unwrapped = ret_unwrapped + [read_val,]
+ if len(ret_unwrapped) == 0:
+ raise OperationError(space.w_NotImplementedError, space.wrap(
+ "item() for Void aray with no fields not implemented"))
+ return space.newtuple(ret_unwrapped)
+
class RecordType(FlexibleType):
T = lltype.Char
@@ -1848,7 +1882,8 @@
first = False
else:
pieces.append(", ")
- pieces.append(tp.str_format(tp.read(box.arr, box.ofs, ofs)))
+ val = tp.read(box.arr, box.ofs, ofs, subdtype)
+ pieces.append(tp.str_format(val))
pieces.append(")")
return "".join(pieces)
diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py
--- a/rpython/annotator/bookkeeper.py
+++ b/rpython/annotator/bookkeeper.py
@@ -371,15 +371,19 @@
listdef.generalize(self.immutablevalue(e, False))
result = SomeList(listdef)
elif tp is dict or tp is r_dict or tp is SomeOrderedDict.knowntype:
+ if tp is SomeOrderedDict.knowntype:
+ cls = SomeOrderedDict
+ else:
+ cls = SomeDict
if need_const:
key = Constant(x)
try:
return self.immutable_cache[key]
except KeyError:
- result = SomeDict(DictDef(self,
- s_ImpossibleValue,
- s_ImpossibleValue,
- is_r_dict = tp is r_dict))
+ result = cls(DictDef(self,
+ s_ImpossibleValue,
+ s_ImpossibleValue,
+ is_r_dict = tp is r_dict))
self.immutable_cache[key] = result
if tp is r_dict:
s_eqfn = self.immutablevalue(x.key_eq)
@@ -412,10 +416,7 @@
dictdef.generalize_key(self.immutablevalue(ek, False))
dictdef.generalize_value(self.immutablevalue(ev, False))
dictdef.seen_prebuilt_key(ek)
- if tp is SomeOrderedDict.knowntype:
- result = SomeOrderedDict(dictdef)
- else:
- result = SomeDict(dictdef)
+ result = cls(dictdef)
elif tp is weakref.ReferenceType:
x1 = x()
if x1 is None:
diff --git a/rpython/annotator/test/test_annrpython.py
b/rpython/annotator/test/test_annrpython.py
--- a/rpython/annotator/test/test_annrpython.py
+++ b/rpython/annotator/test/test_annrpython.py
@@ -4148,6 +4148,19 @@
a.build_types(f, [str, str])
assert ("format() is not RPython" in exc.value.msg)
+ def test_prebuilt_ordered_dict(self):
+ try:
+ from collections import OrderedDict
+ except ImportError:
+ py.test.skip("Please upgrade to python 2.7")
+ d = OrderedDict([("aa", 1)])
+
+ def f():
+ return d
+
+ a = self.RPythonAnnotator()
+ assert isinstance(a.build_types(f, []), annmodel.SomeOrderedDict)
+
def g(n):
return [0, 1, 2, n]
diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py
--- a/rpython/annotator/unaryop.py
+++ b/rpython/annotator/unaryop.py
@@ -460,13 +460,13 @@
check_negative_slice(start, end, "count")
return SomeInteger(nonneg=True)
- def method_strip(str, chr):
+ def method_strip(str, chr=None):
return str.basestringclass(no_nul=str.no_nul)
- def method_lstrip(str, chr):
+ def method_lstrip(str, chr=None):
return str.basestringclass(no_nul=str.no_nul)
- def method_rstrip(str, chr):
+ def method_rstrip(str, chr=None):
return str.basestringclass(no_nul=str.no_nul)
def method_join(str, s_list):
diff --git a/rpython/jit/backend/x86/test/test_ztranslation_basic.py
b/rpython/jit/backend/x86/test/test_ztranslation_basic.py
--- a/rpython/jit/backend/x86/test/test_ztranslation_basic.py
+++ b/rpython/jit/backend/x86/test/test_ztranslation_basic.py
@@ -1,11 +1,11 @@
from rpython.jit.backend.llsupport.test.ztranslation_test import
TranslationTest
from rpython.jit.backend.x86.arch import WORD
+import sys
class TestTranslationX86(TranslationTest):
def _check_cbuilder(self, cbuilder):
- # We assume here that we have sse2. If not, the CPUClass
- # needs to be changed to CPU386_NO_SSE2, but well.
- if WORD == 4:
+ # msse2 and sse are always on on x86-64
+ if WORD == 4 and sys.platform != 'win32':
assert '-msse2' in cbuilder.eci.compile_extra
assert '-mfpmath=sse' in cbuilder.eci.compile_extra
diff --git a/rpython/jit/backend/x86/test/test_ztranslation_call_assembler.py
b/rpython/jit/backend/x86/test/test_ztranslation_call_assembler.py
--- a/rpython/jit/backend/x86/test/test_ztranslation_call_assembler.py
+++ b/rpython/jit/backend/x86/test/test_ztranslation_call_assembler.py
@@ -1,11 +1,13 @@
from rpython.jit.backend.llsupport.test.ztranslation_test import
TranslationTestCallAssembler
from rpython.translator.translator import TranslationContext
from rpython.config.translationoption import DEFL_GC
-
+from rpython.jit.backend.x86.arch import WORD
+import sys
class TestTranslationCallAssemblerX86(TranslationTestCallAssembler):
def _check_cbuilder(self, cbuilder):
- # We assume here that we have sse2. If not, the CPUClass
+ #We assume here that we have sse2. If not, the CPUClass
# needs to be changed to CPU386_NO_SSE2, but well.
- assert '-msse2' in cbuilder.eci.compile_extra
- assert '-mfpmath=sse' in cbuilder.eci.compile_extra
\ No newline at end of file
+ if WORD == 4 and sys.platform != 'win32':
+ assert '-msse2' in cbuilder.eci.compile_extra
+ assert '-mfpmath=sse' in cbuilder.eci.compile_extra
diff --git a/rpython/jit/backend/x86/test/test_ztranslation_jit_stats.py
b/rpython/jit/backend/x86/test/test_ztranslation_jit_stats.py
--- a/rpython/jit/backend/x86/test/test_ztranslation_jit_stats.py
+++ b/rpython/jit/backend/x86/test/test_ztranslation_jit_stats.py
@@ -1,11 +1,14 @@
from rpython.jit.backend.llsupport.test.ztranslation_test import
TranslationTestJITStats
from rpython.translator.translator import TranslationContext
from rpython.config.translationoption import DEFL_GC
+from rpython.jit.backend.x86.arch import WORD
+import sys
class TestTranslationJITStatsX86(TranslationTestJITStats):
def _check_cbuilder(self, cbuilder):
- # We assume here that we have sse2. If not, the CPUClass
+ #We assume here that we have sse2. If not, the CPUClass
# needs to be changed to CPU386_NO_SSE2, but well.
- assert '-msse2' in cbuilder.eci.compile_extra
- assert '-mfpmath=sse' in cbuilder.eci.compile_extra
\ No newline at end of file
+ if WORD == 4 and sys.platform != 'win32':
+ assert '-msse2' in cbuilder.eci.compile_extra
+ assert '-mfpmath=sse' in cbuilder.eci.compile_extra
diff --git a/rpython/rlib/rdtoa.py b/rpython/rlib/rdtoa.py
--- a/rpython/rlib/rdtoa.py
+++ b/rpython/rlib/rdtoa.py
@@ -38,6 +38,10 @@
],
)
+# dtoa.c is limited to 'int', so we refuse to pass it
+# strings or integer arguments bigger than ~2GB
+_INT_LIMIT = 0x7ffff000
+
dg_strtod = rffi.llexternal(
'_PyPy_dg_strtod', [rffi.CCHARP, rffi.CCHARPP], rffi.DOUBLE,
compilation_info=eci, sandboxsafe=True)
@@ -52,6 +56,8 @@
compilation_info=eci, sandboxsafe=True)
def strtod(input):
+ if len(input) > _INT_LIMIT:
+ raise MemoryError
end_ptr = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw')
try:
ll_input = rffi.str2charp(input)
@@ -232,6 +238,8 @@
def dtoa(value, code='r', mode=0, precision=0, flags=0,
special_strings=lower_special_strings, upper=False):
+ if precision > _INT_LIMIT:
+ raise MemoryError
decpt_ptr = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
try:
sign_ptr = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
diff --git a/rpython/rlib/rdynload.py b/rpython/rlib/rdynload.py
--- a/rpython/rlib/rdynload.py
+++ b/rpython/rlib/rdynload.py
@@ -4,7 +4,6 @@
from rpython.rtyper.tool import rffi_platform
from rpython.rtyper.lltypesystem import rffi
from rpython.rlib.rarithmetic import r_uint
-from rpython.rlib.objectmodel import we_are_translated
from rpython.translator.tool.cbuild import ExternalCompilationInfo
from rpython.translator.platform import platform
@@ -80,38 +79,6 @@
RTLD_NOW = cConfig.RTLD_NOW
RTLD_LAZY = cConfig.RTLD_LAZY
- _t_opened = {}
-
- def t_dlopen(name):
- # for direct execution: can't use the regular way on FreeBSD :-(
- #
http://factor-language.blogspot.de/2009/02/note-about-libdl-functions-on-netbsd.html
- import ctypes
- if name:
- name = rffi.charp2str(name)
- else:
- name = None
- try:
- res = ctypes.cdll.LoadLibrary(name)
- except OSError, e:
- raise DLOpenError(str(e))
- h = rffi.cast(rffi.VOIDP, res._handle)
- _t_opened[rffi.cast(rffi.LONG, h)] = res
- return h
-
- def t_dlclose(handle):
- _t_opened.pop(rffi.cast(rffi.LONG, handle))
- return rffi.cast(rffi.INT, 0)
-
- def t_dldym(handle, name):
- import ctypes
- lib = _t_opened[rffi.cast(rffi.LONG, handle)]
- try:
- symbol = lib[name]
- except AttributeError:
- raise KeyError(name)
- res = ctypes.cast(symbol, ctypes.c_void_p)
- return rffi.cast(rffi.VOIDP, res.value or 0)
-
def dlerror():
# XXX this would never work on top of ll2ctypes, because
# ctypes are calling dlerror itself, unsure if I can do much in this
@@ -124,8 +91,6 @@
def dlopen(name, mode=-1):
""" Wrapper around C-level dlopen
"""
- if not we_are_translated():
- return t_dlopen(name)
if mode == -1:
if RTLD_LOCAL is not None:
mode = RTLD_LOCAL
@@ -139,16 +104,11 @@
raise DLOpenError(err)
return res
- def dlclose(handle):
- if not we_are_translated():
- return t_dlclose(handle)
- return c_dlclose(handle)
+ dlclose = c_dlclose
def dlsym(libhandle, name):
""" Wrapper around C-level dlsym
"""
- if not we_are_translated():
- return t_dldym(libhandle, name)
res = c_dlsym(libhandle, name)
if not res:
raise KeyError(name)
diff --git a/rpython/rlib/test/test_rdynload.py
b/rpython/rlib/test/test_rdynload.py
--- a/rpython/rlib/test/test_rdynload.py
+++ b/rpython/rlib/test/test_rdynload.py
@@ -21,4 +21,3 @@
lltype.Signed)), dlsym(lib, 'abs'))
assert 1 == handle(1)
assert 1 == handle(-1)
- dlclose(lib)
diff --git a/rpython/rtyper/lltypesystem/rstr.py
b/rpython/rtyper/lltypesystem/rstr.py
--- a/rpython/rtyper/lltypesystem/rstr.py
+++ b/rpython/rtyper/lltypesystem/rstr.py
@@ -9,6 +9,7 @@
from rpython.rlib.rarithmetic import ovfcheck
from rpython.rtyper.error import TyperError
from rpython.rtyper.lltypesystem import ll_str, llmemory
+from rpython.rtyper.lltypesystem.lloperation import llop
from rpython.rtyper.lltypesystem.lltype import (GcStruct, Signed, Array, Char,
UniChar, Ptr, malloc, Bool, Void, GcArray, nullptr, cast_primitive,
typeOf, staticAdtMethod, GcForwardReference)
@@ -402,6 +403,46 @@
return result
@jit.elidable
+ def ll_strip_default(s, left, right):
+ s_len = len(s.chars)
+ if s_len == 0:
+ return s.empty()
+ lpos = 0
+ rpos = s_len - 1
+ if left:
+ while lpos < rpos and s.chars[lpos].isspace():
+ lpos += 1
+ if right:
+ while lpos < rpos + 1 and s.chars[rpos].isspace():
+ rpos -= 1
+ if rpos < lpos:
+ return s.empty()
+ r_len = rpos - lpos + 1
+ result = s.malloc(r_len)
+ s.copy_contents(s, result, lpos, 0, r_len)
+ return result
+
+ @jit.elidable
+ def ll_strip_multiple(s, s2, left, right):
+ s_len = len(s.chars)
+ if s_len == 0:
+ return s.empty()
+ lpos = 0
+ rpos = s_len - 1
+ if left:
+ while lpos < rpos and LLHelpers.ll_contains(s2, s.chars[lpos]):
+ lpos += 1
+ if right:
+ while lpos < rpos + 1 and LLHelpers.ll_contains(s2, s.chars[rpos]):
+ rpos -= 1
+ if rpos < lpos:
+ return s.empty()
+ r_len = rpos - lpos + 1
+ result = s.malloc(r_len)
+ s.copy_contents(s, result, lpos, 0, r_len)
+ return result
+
+ @jit.elidable
def ll_upper(s):
s_chars = s.chars
s_len = len(s_chars)
diff --git a/rpython/rtyper/rstr.py b/rpython/rtyper/rstr.py
--- a/rpython/rtyper/rstr.py
+++ b/rpython/rtyper/rstr.py
@@ -231,11 +231,22 @@
def rtype_method_strip(self, hop, left=True, right=True):
rstr = hop.args_r[0].repr
v_str = hop.inputarg(rstr.repr, arg=0)
- v_char = hop.inputarg(rstr.char_repr, arg=1)
- v_left = hop.inputconst(Bool, left)
- v_right = hop.inputconst(Bool, right)
+ args_v = [v_str]
+ if len(hop.args_s) == 2:
+ if isinstance(hop.args_s[1], annmodel.SomeString):
+ v_stripstr = hop.inputarg(rstr.repr, arg=1)
+ args_v.append(v_stripstr)
+ func = self.ll.ll_strip_multiple
+ else:
+ v_char = hop.inputarg(rstr.char_repr, arg=1)
+ args_v.append(v_char)
+ func = self.ll.ll_strip
+ else:
+ func = self.ll.ll_strip_default
+ args_v.append(hop.inputconst(Bool, left))
+ args_v.append(hop.inputconst(Bool, right))
hop.exception_is_here()
- return hop.gendirectcall(self.ll.ll_strip, v_str, v_char, v_left,
v_right)
+ return hop.gendirectcall(func, *args_v)
def rtype_method_lstrip(self, hop):
return self.rtype_method_strip(hop, left=True, right=False)
diff --git a/rpython/rtyper/test/test_rstr.py b/rpython/rtyper/test/test_rstr.py
--- a/rpython/rtyper/test/test_rstr.py
+++ b/rpython/rtyper/test/test_rstr.py
@@ -9,6 +9,7 @@
from rpython.rtyper.rstr import AbstractLLHelpers
from rpython.rtyper.rtyper import TyperError
from rpython.rtyper.test.tool import BaseRtypingTest
+from rpython.rtyper.annlowlevel import llstr, hlstr
def test_parse_fmt():
@@ -457,6 +458,29 @@
res = self.interpret(left2, [])
assert self.ll_to_string(res) == const('a')
+ def test_strip_multiple_chars(self):
+ const = self.const
+ def both():
+ return const('!ab!').strip(const('!a'))
+ def left():
+ return const('!+ab!').lstrip(const('!+'))
+ def right():
+ return const('!ab!+').rstrip(const('!+'))
+ def empty():
+ return const(' \t\t ').strip('\t ')
+ def left2():
+ return const('a ').strip(' \t')
+ res = self.interpret(both, [])
+ assert self.ll_to_string(res) == const('b')
+ res = self.interpret(left, [])
+ assert self.ll_to_string(res) == const('ab!')
+ res = self.interpret(right, [])
+ assert self.ll_to_string(res) == const('!ab')
+ res = self.interpret(empty, [])
+ assert self.ll_to_string(res) == const('')
+ res = self.interpret(left2, [])
+ assert self.ll_to_string(res) == const('a')
+
def test_upper(self):
const = self.const
constchar = self.constchar
@@ -1143,3 +1167,16 @@
self.interpret(f, [array, 4])
assert list(array) == list('abc'*4)
lltype.free(array, flavor='raw')
+
+ def test_strip_no_arg(self):
+ strings = [" xyz ", "", "\t\vx"]
+
+ def f(i):
+ return strings[i].strip()
+
+ res = self.interpret(f, [0])
+ assert hlstr(res) == "xyz"
+ res = self.interpret(f, [1])
+ assert hlstr(res) == ""
+ res = self.interpret(f, [2])
+ assert hlstr(res) == "x"
diff --git a/rpython/rtyper/test/test_runicode.py
b/rpython/rtyper/test/test_runicode.py
--- a/rpython/rtyper/test/test_runicode.py
+++ b/rpython/rtyper/test/test_runicode.py
@@ -282,6 +282,7 @@
test_int_valueerror = unsupported
test_float = unsupported
test_hlstr = unsupported
+ test_strip_multiple_chars = unsupported
def test_hash_via_type(self):
from rpython.rlib.objectmodel import compute_hash
diff --git a/rpython/tool/runsubprocess.py b/rpython/tool/runsubprocess.py
--- a/rpython/tool/runsubprocess.py
+++ b/rpython/tool/runsubprocess.py
@@ -49,7 +49,7 @@
sys.stdout.flush()
-if sys.platform != 'win32' and hasattr(os, 'fork'):
+if sys.platform != 'win32' and hasattr(os, 'fork') and not
os.getenv("PYPY_DONT_RUN_SUBPROCESS", None):
# do this at import-time, when the process is still tiny
_source = os.path.dirname(os.path.abspath(__file__))
_source = os.path.join(_source, 'runsubprocess.py') # and not e.g. '.pyc'
diff --git a/rpython/translator/c/src/dtoa.c b/rpython/translator/c/src/dtoa.c
--- a/rpython/translator/c/src/dtoa.c
+++ b/rpython/translator/c/src/dtoa.c
@@ -2329,7 +2329,7 @@
static char *
__Py_dg_dtoa(double dd, int mode, int ndigits,
- Signed *decpt, Signed *sign, char **rve)
+ int *decpt, int *sign, char **rve)
{
/* Arguments ndigits, decpt, sign are similar to those
of ecvt and fcvt; trailing zeros are suppressed from
@@ -2952,7 +2952,7 @@
}
char * _PyPy_dg_dtoa(double dd, int mode, int ndigits,
- Signed *decpt, Signed *sign, char **rve)
+ int *decpt, int *sign, char **rve)
{
char* result;
_PyPy_SET_53BIT_PRECISION_HEADER;
diff --git a/rpython/translator/c/src/dtoa.h b/rpython/translator/c/src/dtoa.h
--- a/rpython/translator/c/src/dtoa.h
+++ b/rpython/translator/c/src/dtoa.h
@@ -2,6 +2,6 @@
double _PyPy_dg_strtod(const char *str, char **ptr);
char * _PyPy_dg_dtoa(double d, int mode, int ndigits,
- Signed *decpt, Signed *sign, char **rve);
+ int *decpt, int *sign, char **rve);
void _PyPy_dg_freedtoa(char *s);
diff --git a/rpython/translator/c/test/test_exception.py
b/rpython/translator/c/test/test_exception.py
--- a/rpython/translator/c/test/test_exception.py
+++ b/rpython/translator/c/test/test_exception.py
@@ -156,3 +156,20 @@
assert res == 42
res = f1(0)
assert res == 100
+
+def test_dict_keyerror_inside_try_finally():
+ class CtxMgr:
+ def __enter__(self):
+ return 42
+ def __exit__(self, *args):
+ pass
+ def fn(x):
+ d = {5: x}
+ with CtxMgr() as forty_two:
+ try:
+ return d[x]
+ except KeyError:
+ return forty_two
+ f1 = getcompiledopt(fn, [int])
+ res = f1(100)
+ assert res == 42
diff --git a/rpython/translator/c/test/test_genc.py
b/rpython/translator/c/test/test_genc.py
--- a/rpython/translator/c/test/test_genc.py
+++ b/rpython/translator/c/test/test_genc.py
@@ -574,6 +574,22 @@
fn = compile(chooser, [bool])
assert fn(True)
+def test_ordered_dict():
+ try:
+ from collections import OrderedDict
+ except ImportError:
+ py.test.skip("Please update to Python 2.7")
+
+ expected = [('ea', 1), ('bb', 2), ('c', 3), ('d', 4), ('e', 5),
+ ('ef', 6)]
+ d = OrderedDict(expected)
+
+ def f():
+ assert d.items() == expected
+
+ fn = compile(f, [])
+ fn()
+
def test_inhibit_tail_call():
def foobar_fn(n):
return 42
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit