[pypy-commit] pypy reflex-support: merge default into branch
wlav
noreply at buildbot.pypy.org
Wed Mar 14 14:27:07 CET 2012
Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r53556:3a12457d80db
Date: 2012-03-14 06:25 -0700
http://bitbucket.org/pypy/pypy/changeset/3a12457d80db/
Log: merge default into branch
diff --git a/lib-python/conftest.py b/lib-python/conftest.py
--- a/lib-python/conftest.py
+++ b/lib-python/conftest.py
@@ -311,7 +311,7 @@
RegrTest('test_mimetypes.py'),
RegrTest('test_MimeWriter.py', core=False),
RegrTest('test_minidom.py'),
- RegrTest('test_mmap.py'),
+ RegrTest('test_mmap.py', usemodules="mmap"),
RegrTest('test_module.py', core=True),
RegrTest('test_modulefinder.py'),
RegrTest('test_msilib.py', skip=only_win32),
diff --git a/lib-python/modified-2.7/distutils/command/bdist_wininst.py b/lib-python/modified-2.7/distutils/command/bdist_wininst.py
--- a/lib-python/modified-2.7/distutils/command/bdist_wininst.py
+++ b/lib-python/modified-2.7/distutils/command/bdist_wininst.py
@@ -298,7 +298,8 @@
bitmaplen, # number of bytes in bitmap
)
file.write(header)
- file.write(open(arcname, "rb").read())
+ with open(arcname, "rb") as arcfile:
+ file.write(arcfile.read())
# create_exe()
diff --git a/lib-python/modified-2.7/opcode.py b/lib-python/modified-2.7/opcode.py
--- a/lib-python/modified-2.7/opcode.py
+++ b/lib-python/modified-2.7/opcode.py
@@ -192,5 +192,6 @@
def_op('LOOKUP_METHOD', 201) # Index in name list
hasname.append(201)
def_op('CALL_METHOD', 202) # #args not including 'self'
+def_op('BUILD_LIST_FROM_ARG', 203)
del def_op, name_op, jrel_op, jabs_op
diff --git a/lib-python/modified-2.7/test/test_dis.py b/lib-python/modified-2.7/test/test_dis.py
new file mode 100644
--- /dev/null
+++ b/lib-python/modified-2.7/test/test_dis.py
@@ -0,0 +1,150 @@
+# Minimal tests for dis module
+
+from test.test_support import run_unittest
+import unittest
+import sys
+import dis
+import StringIO
+
+
+def _f(a):
+ print a
+ return 1
+
+dis_f = """\
+ %-4d 0 LOAD_FAST 0 (a)
+ 3 PRINT_ITEM
+ 4 PRINT_NEWLINE
+
+ %-4d 5 LOAD_CONST 1 (1)
+ 8 RETURN_VALUE
+"""%(_f.func_code.co_firstlineno + 1,
+ _f.func_code.co_firstlineno + 2)
+
+
+def bug708901():
+ for res in range(1,
+ 10):
+ pass
+
+dis_bug708901 = """\
+ %-4d 0 SETUP_LOOP 23 (to 26)
+ 3 LOAD_GLOBAL 0 (range)
+ 6 LOAD_CONST 1 (1)
+
+ %-4d 9 LOAD_CONST 2 (10)
+ 12 CALL_FUNCTION 2
+ 15 GET_ITER
+ >> 16 FOR_ITER 6 (to 25)
+ 19 STORE_FAST 0 (res)
+
+ %-4d 22 JUMP_ABSOLUTE 16
+ >> 25 POP_BLOCK
+ >> 26 LOAD_CONST 0 (None)
+ 29 RETURN_VALUE
+"""%(bug708901.func_code.co_firstlineno + 1,
+ bug708901.func_code.co_firstlineno + 2,
+ bug708901.func_code.co_firstlineno + 3)
+
+
+def bug1333982(x=[]):
+ assert 0, ([s for s in x] +
+ 1)
+ pass
+
+dis_bug1333982 = """\
+ %-4d 0 LOAD_CONST 1 (0)
+ 3 POP_JUMP_IF_TRUE 38
+ 6 LOAD_GLOBAL 0 (AssertionError)
+ 9 LOAD_FAST 0 (x)
+ 12 BUILD_LIST_FROM_ARG 0
+ 15 GET_ITER
+ >> 16 FOR_ITER 12 (to 31)
+ 19 STORE_FAST 1 (s)
+ 22 LOAD_FAST 1 (s)
+ 25 LIST_APPEND 2
+ 28 JUMP_ABSOLUTE 16
+
+ %-4d >> 31 LOAD_CONST 2 (1)
+ 34 BINARY_ADD
+ 35 RAISE_VARARGS 2
+
+ %-4d >> 38 LOAD_CONST 0 (None)
+ 41 RETURN_VALUE
+"""%(bug1333982.func_code.co_firstlineno + 1,
+ bug1333982.func_code.co_firstlineno + 2,
+ bug1333982.func_code.co_firstlineno + 3)
+
+_BIG_LINENO_FORMAT = """\
+%3d 0 LOAD_GLOBAL 0 (spam)
+ 3 POP_TOP
+ 4 LOAD_CONST 0 (None)
+ 7 RETURN_VALUE
+"""
+
+class DisTests(unittest.TestCase):
+ def do_disassembly_test(self, func, expected):
+ s = StringIO.StringIO()
+ save_stdout = sys.stdout
+ sys.stdout = s
+ dis.dis(func)
+ sys.stdout = save_stdout
+ got = s.getvalue()
+ # Trim trailing blanks (if any).
+ lines = got.split('\n')
+ lines = [line.rstrip() for line in lines]
+ expected = expected.split("\n")
+ import difflib
+ if expected != lines:
+ self.fail(
+ "events did not match expectation:\n" +
+ "\n".join(difflib.ndiff(expected,
+ lines)))
+
+ def test_opmap(self):
+ self.assertEqual(dis.opmap["STOP_CODE"], 0)
+ self.assertIn(dis.opmap["LOAD_CONST"], dis.hasconst)
+ self.assertIn(dis.opmap["STORE_NAME"], dis.hasname)
+
+ def test_opname(self):
+ self.assertEqual(dis.opname[dis.opmap["LOAD_FAST"]], "LOAD_FAST")
+
+ def test_boundaries(self):
+ self.assertEqual(dis.opmap["EXTENDED_ARG"], dis.EXTENDED_ARG)
+ self.assertEqual(dis.opmap["STORE_NAME"], dis.HAVE_ARGUMENT)
+
+ def test_dis(self):
+ self.do_disassembly_test(_f, dis_f)
+
+ def test_bug_708901(self):
+ self.do_disassembly_test(bug708901, dis_bug708901)
+
+ def test_bug_1333982(self):
+ # This one is checking bytecodes generated for an `assert` statement,
+ # so fails if the tests are run with -O. Skip this test then.
+ if __debug__:
+ self.do_disassembly_test(bug1333982, dis_bug1333982)
+
+ def test_big_linenos(self):
+ def func(count):
+ namespace = {}
+ func = "def foo():\n " + "".join(["\n "] * count + ["spam\n"])
+ exec func in namespace
+ return namespace['foo']
+
+ # Test all small ranges
+ for i in xrange(1, 300):
+ expected = _BIG_LINENO_FORMAT % (i + 2)
+ self.do_disassembly_test(func(i), expected)
+
+ # Test some larger ranges too
+ for i in xrange(300, 5000, 10):
+ expected = _BIG_LINENO_FORMAT % (i + 2)
+ self.do_disassembly_test(func(i), expected)
+
+def test_main():
+ run_unittest(DisTests)
+
+
+if __name__ == "__main__":
+ test_main()
diff --git a/lib_pypy/_csv.py b/lib_pypy/_csv.py
--- a/lib_pypy/_csv.py
+++ b/lib_pypy/_csv.py
@@ -414,7 +414,7 @@
def _parse_add_char(self, c):
if len(self.field) + len(c) > _field_limit:
- raise Error("field larget than field limit (%d)" % (_field_limit))
+ raise Error("field larger than field limit (%d)" % (_field_limit))
self.field += c
diff --git a/lib_pypy/_ctypes/builtin.py b/lib_pypy/_ctypes/builtin.py
--- a/lib_pypy/_ctypes/builtin.py
+++ b/lib_pypy/_ctypes/builtin.py
@@ -31,24 +31,20 @@
arg = cobj._get_buffer_value()
return _rawffi.wcharp2rawunicode(arg, lgt)
-class ErrorObject(local):
- def __init__(self):
- self.errno = 0
- self.winerror = 0
-_error_object = ErrorObject()
+_err = local()
def get_errno():
- return _error_object.errno
+ return getattr(_err, "errno", 0)
def set_errno(errno):
- old_errno = _error_object.errno
- _error_object.errno = errno
+ old_errno = get_errno()
+ _err.errno = errno
return old_errno
def get_last_error():
- return _error_object.winerror
+ return getattr(_err, "winerror", 0)
def set_last_error(winerror):
- old_winerror = _error_object.winerror
- _error_object.winerror = winerror
+ old_winerror = get_last_error()
+ _err.winerror = winerror
return old_winerror
diff --git a/lib_pypy/_ctypes/function.py b/lib_pypy/_ctypes/function.py
--- a/lib_pypy/_ctypes/function.py
+++ b/lib_pypy/_ctypes/function.py
@@ -3,7 +3,7 @@
from _ctypes.primitive import SimpleType, _SimpleCData
from _ctypes.basics import ArgumentError, keepalive_key
from _ctypes.basics import is_struct_shape
-from _ctypes.builtin import set_errno, set_last_error
+from _ctypes.builtin import get_errno, set_errno, get_last_error, set_last_error
import _rawffi
import _ffi
import sys
@@ -350,16 +350,24 @@
def _call_funcptr(self, funcptr, *newargs):
if self._flags_ & _rawffi.FUNCFLAG_USE_ERRNO:
- set_errno(_rawffi.get_errno())
+ tmp = _rawffi.get_errno()
+ _rawffi.set_errno(get_errno())
+ set_errno(tmp)
if self._flags_ & _rawffi.FUNCFLAG_USE_LASTERROR:
- set_last_error(_rawffi.get_last_error())
+ tmp = _rawffi.get_last_error()
+ _rawffi.set_last_error(get_last_error())
+ set_last_error(tmp)
try:
result = funcptr(*newargs)
finally:
if self._flags_ & _rawffi.FUNCFLAG_USE_ERRNO:
- set_errno(_rawffi.get_errno())
+ tmp = _rawffi.get_errno()
+ _rawffi.set_errno(get_errno())
+ set_errno(tmp)
if self._flags_ & _rawffi.FUNCFLAG_USE_LASTERROR:
- set_last_error(_rawffi.get_last_error())
+ tmp = _rawffi.get_last_error()
+ _rawffi.set_last_error(get_last_error())
+ set_last_error(tmp)
#
try:
return self._build_result(self._restype_, result, newargs)
diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py
--- a/pypy/annotation/builtin.py
+++ b/pypy/annotation/builtin.py
@@ -37,7 +37,11 @@
try:
realresult = func(*args)
except (ValueError, OverflowError):
- return s_ImpossibleValue # no possible answer for this precise input
+ # no possible answer for this precise input. Be conservative
+ # and keep the computation non-constant. Example:
+ # unichr(constant-that-doesn't-fit-16-bits) on platforms where
+ # the underlying Python has sys.maxunicode == 0xffff.
+ return s_result
s_realresult = immutablevalue(realresult)
if not s_result.contains(s_realresult):
raise Exception("%s%r returned %r, which is not contained in %s" % (
diff --git a/pypy/annotation/classdef.py b/pypy/annotation/classdef.py
--- a/pypy/annotation/classdef.py
+++ b/pypy/annotation/classdef.py
@@ -134,12 +134,19 @@
if self.name not in homedef.classdesc.all_enforced_attrs:
self.attr_allowed = False
if not self.readonly:
- raise NoSuchAttrError(homedef, self.name)
+ raise NoSuchAttrError(
+ "setting forbidden attribute %r on %r" % (
+ self.name, homedef))
def modified(self, classdef='?'):
self.readonly = False
if not self.attr_allowed:
- raise NoSuchAttrError(classdef, self.name)
+ raise NoSuchAttrError(
+ "Attribute %r on %r should be read-only.\n" % (self.name,
+ classdef) +
+ "This error can be caused by another 'getattr' that promoted\n"
+ "the attribute here; the list of read locations is:\n" +
+ '\n'.join([str(loc[0]) for loc in self.read_locations]))
class ClassDef(object):
diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py
--- a/pypy/annotation/test/test_annrpython.py
+++ b/pypy/annotation/test/test_annrpython.py
@@ -1,15 +1,12 @@
from __future__ import with_statement
-import autopath
import py.test
import sys
from pypy import conftest
-from pypy.tool.udir import udir
from pypy.annotation import model as annmodel
from pypy.annotation.annrpython import RPythonAnnotator as _RPythonAnnotator
from pypy.translator.translator import graphof as tgraphof
from pypy.annotation import policy
-from pypy.annotation import specialize
from pypy.annotation.listdef import ListDef, ListChangeUnallowed
from pypy.annotation.dictdef import DictDef
from pypy.objspace.flow.model import *
@@ -2556,6 +2553,26 @@
s = a.build_types(f, [int])
assert s.knowntype == int
+ def test_slots_reads(self):
+ class A(object):
+ __slots__ = ()
+ class B(A):
+ def __init__(self, x):
+ self.x = x
+ def f(x):
+ if x:
+ a = A()
+ else:
+ a = B(x)
+ return a.x # should explode here
+
+ a = self.RPythonAnnotator()
+ e = py.test.raises(Exception, a.build_types, f, [int])
+ # this should explode on reading the attribute 'a.x', but it can
+ # sometimes explode on 'self.x = x', which does not make much sense.
+ # But it looks hard to fix in general: we don't know yet during 'a.x'
+ # if the attribute x will be read-only or read-write.
+
def test_unboxed_value(self):
class A(object):
__slots__ = ()
diff --git a/pypy/interpreter/astcompiler/assemble.py b/pypy/interpreter/astcompiler/assemble.py
--- a/pypy/interpreter/astcompiler/assemble.py
+++ b/pypy/interpreter/astcompiler/assemble.py
@@ -610,6 +610,8 @@
ops.JUMP_IF_FALSE_OR_POP : 0,
ops.POP_JUMP_IF_TRUE : -1,
ops.POP_JUMP_IF_FALSE : -1,
+
+ ops.BUILD_LIST_FROM_ARG: 1,
}
diff --git a/pypy/interpreter/astcompiler/codegen.py b/pypy/interpreter/astcompiler/codegen.py
--- a/pypy/interpreter/astcompiler/codegen.py
+++ b/pypy/interpreter/astcompiler/codegen.py
@@ -965,7 +965,7 @@
self.emit_op_arg(ops.CALL_METHOD, (kwarg_count << 8) | arg_count)
return True
- def _listcomp_generator(self, gens, gen_index, elt):
+ def _listcomp_generator(self, gens, gen_index, elt, single=False):
start = self.new_block()
skip = self.new_block()
if_cleanup = self.new_block()
@@ -973,6 +973,8 @@
gen = gens[gen_index]
assert isinstance(gen, ast.comprehension)
gen.iter.walkabout(self)
+ if single:
+ self.emit_op_arg(ops.BUILD_LIST_FROM_ARG, 0)
self.emit_op(ops.GET_ITER)
self.use_next_block(start)
self.emit_jump(ops.FOR_ITER, anchor)
@@ -998,8 +1000,12 @@
def visit_ListComp(self, lc):
self.update_position(lc.lineno)
- self.emit_op_arg(ops.BUILD_LIST, 0)
- self._listcomp_generator(lc.generators, 0, lc.elt)
+ if len(lc.generators) != 1 or lc.generators[0].ifs:
+ single = False
+ self.emit_op_arg(ops.BUILD_LIST, 0)
+ else:
+ single = True
+ self._listcomp_generator(lc.generators, 0, lc.elt, single=single)
def _comp_generator(self, node, generators, gen_index):
start = self.new_block()
diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py
--- a/pypy/interpreter/astcompiler/test/test_compiler.py
+++ b/pypy/interpreter/astcompiler/test/test_compiler.py
@@ -908,3 +908,17 @@
return d['f'](5)
""")
assert 'generator' in space.str_w(space.repr(w_generator))
+
+ def test_list_comprehension(self):
+ source = "def f(): [i for i in l]"
+ source2 = "def f(): [i for i in l for j in l]"
+ source3 = "def f(): [i for i in l if i]"
+ counts = self.count_instructions(source)
+ assert ops.BUILD_LIST not in counts
+ assert counts[ops.BUILD_LIST_FROM_ARG] == 1
+ counts = self.count_instructions(source2)
+ assert counts[ops.BUILD_LIST] == 1
+ assert ops.BUILD_LIST_FROM_ARG not in counts
+ counts = self.count_instructions(source3)
+ assert counts[ops.BUILD_LIST] == 1
+ assert ops.BUILD_LIST_FROM_ARG not in counts
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -7,7 +7,8 @@
from pypy.interpreter.miscutils import ThreadLocals
from pypy.tool.cache import Cache
from pypy.tool.uid import HUGEVAL_BYTES
-from pypy.rlib.objectmodel import we_are_translated, newlist, compute_unique_id
+from pypy.rlib.objectmodel import we_are_translated, newlist_hint,\
+ compute_unique_id
from pypy.rlib.debug import make_sure_not_resized
from pypy.rlib.timer import DummyTimer, Timer
from pypy.rlib.rarithmetic import r_uint
@@ -833,7 +834,7 @@
items = []
else:
try:
- items = newlist(lgt_estimate)
+ items = newlist_hint(lgt_estimate)
except MemoryError:
items = [] # it might have lied
#
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -15,9 +15,8 @@
from pypy.rlib.rarithmetic import r_uint, intmask
from pypy.rlib.unroll import unrolling_iterable
from pypy.rlib.debug import check_nonneg
-from pypy.tool.stdlib_opcode import (bytecode_spec, host_bytecode_spec,
- unrolling_all_opcode_descs, opmap,
- host_opmap)
+from pypy.tool.stdlib_opcode import (bytecode_spec,
+ unrolling_all_opcode_descs)
def unaryoperation(operationname):
"""NOT_RPYTHON"""
@@ -713,6 +712,19 @@
w_list = self.space.newlist(items)
self.pushvalue(w_list)
+ def BUILD_LIST_FROM_ARG(self, _, next_instr):
+ # this is a little dance, because list has to be before the
+ # value
+ last_val = self.popvalue()
+ try:
+ lgt = self.space.len_w(last_val)
+ except OperationError, e:
+ if e.async(self.space):
+ raise
+ lgt = 0 # oh well
+ self.pushvalue(self.space.newlist([], sizehint=lgt))
+ self.pushvalue(last_val)
+
def LOAD_ATTR(self, nameindex, next_instr):
"obj.attributename"
w_obj = self.popvalue()
diff --git a/pypy/jit/codewriter/jtransform.py b/pypy/jit/codewriter/jtransform.py
--- a/pypy/jit/codewriter/jtransform.py
+++ b/pypy/jit/codewriter/jtransform.py
@@ -365,7 +365,7 @@
def handle_builtin_call(self, op):
oopspec_name, args = support.decode_builtin_call(op)
# dispatch to various implementations depending on the oopspec_name
- if oopspec_name.startswith('list.') or oopspec_name == 'newlist':
+ if oopspec_name.startswith('list.') or oopspec_name.startswith('newlist'):
prepare = self._handle_list_call
elif oopspec_name.startswith('stroruni.'):
prepare = self._handle_stroruni_call
@@ -1494,6 +1494,14 @@
arraydescr, v_length],
op.result)
+ def do_resizable_newlist_hint(self, op, args, arraydescr, lengthdescr,
+ itemsdescr, structdescr):
+ v_hint = self._get_initial_newlist_length(op, args)
+ return SpaceOperation('newlist_hint',
+ [structdescr, lengthdescr, itemsdescr,
+ arraydescr, v_hint],
+ op.result)
+
def do_resizable_list_getitem(self, op, args, arraydescr, lengthdescr,
itemsdescr, structdescr):
v_index, extraop = self._prepare_list_getset(op, lengthdescr, args,
diff --git a/pypy/jit/codewriter/support.py b/pypy/jit/codewriter/support.py
--- a/pypy/jit/codewriter/support.py
+++ b/pypy/jit/codewriter/support.py
@@ -144,6 +144,10 @@
_ll_1_newlist.need_result_type = True
_ll_2_newlist.need_result_type = True
+def _ll_1_newlist_hint(LIST, hint):
+ return LIST.ll_newlist_hint(hint)
+_ll_1_newlist_hint.need_result_type = True
+
def _ll_1_list_len(l):
return l.ll_length()
def _ll_2_list_getitem(l, index):
diff --git a/pypy/jit/metainterp/blackhole.py b/pypy/jit/metainterp/blackhole.py
--- a/pypy/jit/metainterp/blackhole.py
+++ b/pypy/jit/metainterp/blackhole.py
@@ -982,6 +982,15 @@
cpu.bh_setfield_gc_r(result, itemsdescr, items)
return result
+ @arguments("cpu", "d", "d", "d", "d", "i", returns="r")
+ def bhimpl_newlist_hint(cpu, structdescr, lengthdescr, itemsdescr,
+ arraydescr, lengthhint):
+ result = cpu.bh_new(structdescr)
+ cpu.bh_setfield_gc_i(result, lengthdescr, 0)
+ items = cpu.bh_new_array(arraydescr, lengthhint)
+ cpu.bh_setfield_gc_r(result, itemsdescr, items)
+ return result
+
@arguments("cpu", "r", "d", "d", "i", returns="i")
def bhimpl_getlistitem_gc_i(cpu, lst, itemsdescr, arraydescr, index):
items = cpu.bh_getfield_gc_r(lst, itemsdescr)
diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -509,6 +509,15 @@
self._opimpl_setfield_gc_any(sbox, itemsdescr, abox)
return sbox
+ @arguments("descr", "descr", "descr", "descr", "box")
+ def opimpl_newlist_hint(self, structdescr, lengthdescr, itemsdescr,
+ arraydescr, sizehintbox):
+ sbox = self.opimpl_new(structdescr)
+ self._opimpl_setfield_gc_any(sbox, lengthdescr, history.CONST_FALSE)
+ abox = self.opimpl_new_array(arraydescr, sizehintbox)
+ self._opimpl_setfield_gc_any(sbox, itemsdescr, abox)
+ return sbox
+
@arguments("box", "descr", "descr", "box")
def _opimpl_getlistitem_gc_any(self, listbox, itemsdescr, arraydescr,
indexbox):
diff --git a/pypy/jit/metainterp/test/test_list.py b/pypy/jit/metainterp/test/test_list.py
--- a/pypy/jit/metainterp/test/test_list.py
+++ b/pypy/jit/metainterp/test/test_list.py
@@ -1,4 +1,5 @@
import py
+from pypy.rlib.objectmodel import newlist_hint
from pypy.rlib.jit import JitDriver
from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
@@ -228,6 +229,27 @@
self.check_resops({'jump': 1, 'int_gt': 2, 'int_add': 2,
'guard_true': 2, 'int_sub': 2})
+ def test_newlist_hint(self):
+ def f(i):
+ l = newlist_hint(i)
+ return len(l)
+
+ r = self.interp_operations(f, [3])
+ assert r == 0
+
+ def test_newlist_hint_optimized(self):
+ driver = JitDriver(greens = [], reds = ['i'])
+
+ def f(i):
+ while i > 0:
+ driver.jit_merge_point(i=i)
+ l = newlist_hint(5)
+ l.append(1)
+ i -= l[0]
+
+ self.meta_interp(f, [10], listops=True)
+ self.check_resops(new_array=0, call=0)
+
class TestOOtype(ListTests, OOJitMixin):
pass
diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py
--- a/pypy/module/__pypy__/__init__.py
+++ b/pypy/module/__pypy__/__init__.py
@@ -1,5 +1,5 @@
+import sys
-# Package initialisation
from pypy.interpreter.mixedmodule import MixedModule
from pypy.module.imp.importing import get_pyc_magic
@@ -12,6 +12,19 @@
"UnicodeBuilder": "interp_builders.W_UnicodeBuilder",
}
+class TimeModule(MixedModule):
+ appleveldefs = {}
+ interpleveldefs = {}
+ if sys.platform.startswith("linux"):
+ interpleveldefs["clock_gettime"] = "interp_time.clock_gettime"
+ interpleveldefs["clock_getres"] = "interp_time.clock_getres"
+ for name in [
+ "CLOCK_REALTIME", "CLOCK_MONOTONIC", "CLOCK_MONOTONIC_RAW",
+ "CLOCK_PROCESS_CPUTIME_ID", "CLOCK_THREAD_CPUTIME_ID"
+ ]:
+ interpleveldefs[name] = "space.wrap(interp_time.%s)" % name
+
+
class Module(MixedModule):
appleveldefs = {
}
@@ -32,6 +45,7 @@
submodules = {
"builders": BuildersModule,
+ "time": TimeModule,
}
def setup_after_space_initialization(self):
diff --git a/pypy/module/__pypy__/interp_time.py b/pypy/module/__pypy__/interp_time.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/__pypy__/interp_time.py
@@ -0,0 +1,64 @@
+import sys
+
+from pypy.interpreter.error import exception_from_errno
+from pypy.interpreter.gateway import unwrap_spec
+from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.rpython.tool import rffi_platform
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
+
+
+class CConfig:
+ _compilation_info_ = ExternalCompilationInfo(
+ includes=["time.h"],
+ libraries=["rt"],
+ )
+
+ HAS_CLOCK_GETTIME = rffi_platform.Has('clock_gettime')
+
+ CLOCK_REALTIME = rffi_platform.DefinedConstantInteger("CLOCK_REALTIME")
+ CLOCK_MONOTONIC = rffi_platform.DefinedConstantInteger("CLOCK_MONOTONIC")
+ CLOCK_MONOTONIC_RAW = rffi_platform.DefinedConstantInteger("CLOCK_MONOTONIC_RAW")
+ CLOCK_PROCESS_CPUTIME_ID = rffi_platform.DefinedConstantInteger("CLOCK_PROCESS_CPUTIME_ID")
+ CLOCK_THREAD_CPUTIME_ID = rffi_platform.DefinedConstantInteger("CLOCK_THREAD_CPUTIME_ID")
+
+ TIMESPEC = rffi_platform.Struct("struct timespec", [
+ ("tv_sec", rffi.TIME_T),
+ ("tv_nsec", rffi.LONG),
+ ])
+
+cconfig = rffi_platform.configure(CConfig)
+
+HAS_CLOCK_GETTIME = cconfig["HAS_CLOCK_GETTIME"]
+
+CLOCK_REALTIME = cconfig["CLOCK_REALTIME"]
+CLOCK_MONOTONIC = cconfig["CLOCK_MONOTONIC"]
+CLOCK_MONOTONIC_RAW = cconfig["CLOCK_MONOTONIC_RAW"]
+CLOCK_PROCESS_CPUTIME_ID = cconfig["CLOCK_PROCESS_CPUTIME_ID"]
+CLOCK_THREAD_CPUTIME_ID = cconfig["CLOCK_THREAD_CPUTIME_ID"]
+
+TIMESPEC = cconfig["TIMESPEC"]
+
+c_clock_gettime = rffi.llexternal("clock_gettime",
+ [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT,
+ compilation_info=CConfig._compilation_info_, threadsafe=False
+)
+c_clock_getres = rffi.llexternal("clock_getres",
+ [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT,
+ compilation_info=CConfig._compilation_info_, threadsafe=False
+)
+
+ at unwrap_spec(clk_id="c_int")
+def clock_gettime(space, clk_id):
+ with lltype.scoped_alloc(TIMESPEC) as tp:
+ ret = c_clock_gettime(clk_id, tp)
+ if ret != 0:
+ raise exception_from_errno(space, space.w_IOError)
+ return space.wrap(tp.c_tv_sec + tp.c_tv_nsec * 1e-9)
+
+ at unwrap_spec(clk_id="c_int")
+def clock_getres(space, clk_id):
+ with lltype.scoped_alloc(TIMESPEC) as tp:
+ ret = c_clock_getres(clk_id, tp)
+ if ret != 0:
+ raise exception_from_errno(space, space.w_IOError)
+ return space.wrap(tp.c_tv_sec + tp.c_tv_nsec * 1e-9)
diff --git a/pypy/module/__pypy__/test/test_time.py b/pypy/module/__pypy__/test/test_time.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/__pypy__/test/test_time.py
@@ -0,0 +1,26 @@
+import py
+
+from pypy.module.__pypy__.interp_time import HAS_CLOCK_GETTIME
+
+
+class AppTestTime(object):
+ def setup_class(cls):
+ if not HAS_CLOCK_GETTIME:
+ py.test.skip("need time.clock_gettime")
+
+ def test_clock_realtime(self):
+ from __pypy__ import time
+ res = time.clock_gettime(time.CLOCK_REALTIME)
+ assert isinstance(res, float)
+
+ def test_clock_monotonic(self):
+ from __pypy__ import time
+ a = time.clock_gettime(time.CLOCK_MONOTONIC)
+ b = time.clock_gettime(time.CLOCK_MONOTONIC)
+ assert a <= b
+
+ def test_clock_getres(self):
+ from __pypy__ import time
+ res = time.clock_getres(time.CLOCK_REALTIME)
+ assert res > 0.0
+ assert res <= 1.0
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
@@ -107,6 +107,10 @@
('logical_xor', 'logical_xor'),
('logical_not', 'logical_not'),
('logical_or', 'logical_or'),
+ ('log', 'log'),
+ ('log2', 'log2'),
+ ('log10', 'log10'),
+ ('log1p', 'log1p'),
]:
interpleveldefs[exposed] = "interp_ufuncs.get(space).%s" % impl
diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py
--- a/pypy/module/micronumpy/interp_boxes.py
+++ b/pypy/module/micronumpy/interp_boxes.py
@@ -80,6 +80,7 @@
descr_mul = _binop_impl("multiply")
descr_div = _binop_impl("divide")
descr_truediv = _binop_impl("true_divide")
+ descr_floordiv = _binop_impl("floor_divide")
descr_mod = _binop_impl("mod")
descr_pow = _binop_impl("power")
descr_lshift = _binop_impl("left_shift")
@@ -100,6 +101,7 @@
descr_rmul = _binop_right_impl("multiply")
descr_rdiv = _binop_right_impl("divide")
descr_rtruediv = _binop_right_impl("true_divide")
+ descr_rfloordiv = _binop_right_impl("floor_divide")
descr_rmod = _binop_right_impl("mod")
descr_rpow = _binop_right_impl("power")
descr_rlshift = _binop_right_impl("left_shift")
@@ -208,6 +210,7 @@
__mul__ = interp2app(W_GenericBox.descr_mul),
__div__ = interp2app(W_GenericBox.descr_div),
__truediv__ = interp2app(W_GenericBox.descr_truediv),
+ __floordiv__ = interp2app(W_GenericBox.descr_floordiv),
__mod__ = interp2app(W_GenericBox.descr_mod),
__divmod__ = interp2app(W_GenericBox.descr_divmod),
__pow__ = interp2app(W_GenericBox.descr_pow),
@@ -222,6 +225,7 @@
__rmul__ = interp2app(W_GenericBox.descr_rmul),
__rdiv__ = interp2app(W_GenericBox.descr_rdiv),
__rtruediv__ = interp2app(W_GenericBox.descr_rtruediv),
+ __rfloordiv__ = interp2app(W_GenericBox.descr_rfloordiv),
__rmod__ = interp2app(W_GenericBox.descr_rmod),
__rdivmod__ = interp2app(W_GenericBox.descr_rdivmod),
__rpow__ = interp2app(W_GenericBox.descr_rpow),
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
@@ -102,6 +102,7 @@
descr_mul = _binop_impl("multiply")
descr_div = _binop_impl("divide")
descr_truediv = _binop_impl("true_divide")
+ descr_floordiv = _binop_impl("floor_divide")
descr_mod = _binop_impl("mod")
descr_pow = _binop_impl("power")
descr_lshift = _binop_impl("left_shift")
@@ -136,6 +137,7 @@
descr_rmul = _binop_right_impl("multiply")
descr_rdiv = _binop_right_impl("divide")
descr_rtruediv = _binop_right_impl("true_divide")
+ descr_rfloordiv = _binop_right_impl("floor_divide")
descr_rmod = _binop_right_impl("mod")
descr_rpow = _binop_right_impl("power")
descr_rlshift = _binop_right_impl("left_shift")
@@ -1250,6 +1252,7 @@
__mul__ = interp2app(BaseArray.descr_mul),
__div__ = interp2app(BaseArray.descr_div),
__truediv__ = interp2app(BaseArray.descr_truediv),
+ __floordiv__ = interp2app(BaseArray.descr_floordiv),
__mod__ = interp2app(BaseArray.descr_mod),
__divmod__ = interp2app(BaseArray.descr_divmod),
__pow__ = interp2app(BaseArray.descr_pow),
@@ -1264,6 +1267,7 @@
__rmul__ = interp2app(BaseArray.descr_rmul),
__rdiv__ = interp2app(BaseArray.descr_rdiv),
__rtruediv__ = interp2app(BaseArray.descr_rtruediv),
+ __rfloordiv__ = interp2app(BaseArray.descr_rfloordiv),
__rmod__ = interp2app(BaseArray.descr_rmod),
__rdivmod__ = interp2app(BaseArray.descr_rdivmod),
__rpow__ = interp2app(BaseArray.descr_rpow),
diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py
--- a/pypy/module/micronumpy/interp_ufuncs.py
+++ b/pypy/module/micronumpy/interp_ufuncs.py
@@ -388,6 +388,7 @@
"int_only": True}),
("bitwise_xor", "bitwise_xor", 2, {"int_only": True}),
("invert", "invert", 1, {"int_only": True}),
+ ("floor_divide", "floordiv", 2, {"promote_bools": True}),
("divide", "div", 2, {"promote_bools": True}),
("true_divide", "div", 2, {"promote_to_float": True}),
("mod", "mod", 2, {"promote_bools": True}),
@@ -441,6 +442,11 @@
("arcsinh", "arcsinh", 1, {"promote_to_float": True}),
("arccosh", "arccosh", 1, {"promote_to_float": True}),
("arctanh", "arctanh", 1, {"promote_to_float": True}),
+
+ ("log", "log", 1, {"promote_to_float": True}),
+ ("log2", "log2", 1, {"promote_to_float": True}),
+ ("log10", "log10", 1, {"promote_to_float": True}),
+ ("log1p", "log1p", 1, {"promote_to_float": True}),
]:
self.add_ufunc(space, *ufunc_def)
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
@@ -625,6 +625,56 @@
for i in range(5):
assert b[i] == i / 5.0
+ def test_floordiv(self):
+ from math import isnan
+ from _numpypy import array, dtype
+
+ a = array(range(1, 6))
+ b = a // a
+ assert (b == [1, 1, 1, 1, 1]).all()
+
+ a = array(range(1, 6), dtype=bool)
+ b = a // a
+ assert b.dtype is dtype("int8")
+ assert (b == [1, 1, 1, 1, 1]).all()
+
+ a = array([-1, 0, 1])
+ b = array([0, 0, 0])
+ c = a // b
+ assert (c == [0, 0, 0]).all()
+
+ a = array([-1.0, 0.0, 1.0])
+ b = array([0.0, 0.0, 0.0])
+ c = a // b
+ assert c[0] == float('-inf')
+ assert isnan(c[1])
+ assert c[2] == float('inf')
+
+ b = array([-0.0, -0.0, -0.0])
+ c = a // b
+ assert c[0] == float('inf')
+ assert isnan(c[1])
+ assert c[2] == float('-inf')
+
+ def test_floordiv_other(self):
+ from _numpypy import array
+ a = array(range(5))
+ b = array([2, 2, 2, 2, 2], float)
+ c = a // b
+ assert (c == [0, 0, 1, 1, 2]).all()
+
+ def test_rfloordiv(self):
+ from _numpypy import array
+ a = array(range(1, 6))
+ b = 3 // a
+ assert (b == [3, 1, 1, 0, 0]).all()
+
+ def test_floordiv_constant(self):
+ from _numpypy import array
+ a = array(range(5))
+ b = a // 2
+ assert (b == [0, 0, 1, 1, 2]).all()
+
def test_truediv(self):
from operator import truediv
from _numpypy import arange
diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py
--- a/pypy/module/micronumpy/test/test_ufuncs.py
+++ b/pypy/module/micronumpy/test/test_ufuncs.py
@@ -481,3 +481,26 @@
assert (logical_xor([True, False, True, False], [1, 2, 0, 0])
== [False, True, True, False]).all()
assert (logical_not([True, False]) == [False, True]).all()
+
+ def test_logn(self):
+ import math
+ from _numpypy import log, log2, log10
+
+ for log_func, base in [(log, math.e), (log2, 2), (log10, 10)]:
+ for v in [float('-nan'), float('-inf'), -1, float('nan')]:
+ assert math.isnan(log_func(v))
+ for v in [-0.0, 0.0]:
+ assert log_func(v) == float("-inf")
+ assert log_func(float('inf')) == float('inf')
+ assert (log_func([1, base]) == [0, 1]).all()
+
+ def test_log1p(self):
+ import math
+ from _numpypy import log1p
+
+ for v in [float('-nan'), float('-inf'), -2, float('nan')]:
+ assert math.isnan(log1p(v))
+ for v in [-1]:
+ assert log1p(v) == float("-inf")
+ assert log1p(float('inf')) == float('inf')
+ assert (log1p([0, 1e-50, math.e - 1]) == [0, 1e-50, 1]).all()
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
@@ -280,6 +280,12 @@
return v1 / v2
@simple_binary_op
+ def floordiv(self, v1, v2):
+ if v2 == 0:
+ return 0
+ return v1 // v2
+
+ @simple_binary_op
def mod(self, v1, v2):
return v1 % v2
@@ -418,6 +424,15 @@
return rfloat.copysign(rfloat.INFINITY, v1 * v2)
@simple_binary_op
+ def floordiv(self, v1, v2):
+ try:
+ return v1 // v2
+ except ZeroDivisionError:
+ if v1 == v2 == 0.0:
+ return rfloat.NAN
+ return rfloat.copysign(rfloat.INFINITY, v1 * v2)
+
+ @simple_binary_op
def mod(self, v1, v2):
return math.fmod(v1, v2)
@@ -533,6 +548,48 @@
def isinf(self, v):
return rfloat.isinf(v)
+ @simple_unary_op
+ def log(self, v):
+ try:
+ return math.log(v)
+ except ValueError:
+ if v == 0.0:
+ # CPython raises ValueError here, so we have to check
+ # the value to find the correct numpy return value
+ return -rfloat.INFINITY
+ return rfloat.NAN
+
+ @simple_unary_op
+ def log2(self, v):
+ try:
+ return math.log(v, 2)
+ except ValueError:
+ if v == 0.0:
+ # CPython raises ValueError here, so we have to check
+ # the value to find the correct numpy return value
+ return -rfloat.INFINITY
+ return rfloat.NAN
+
+ @simple_unary_op
+ def log10(self, v):
+ try:
+ return math.log10(v)
+ except ValueError:
+ if v == 0.0:
+ # CPython raises ValueError here, so we have to check
+ # the value to find the correct numpy return value
+ return -rfloat.INFINITY
+ return rfloat.NAN
+
+ @simple_unary_op
+ def log1p(self, v):
+ try:
+ return rfloat.log1p(v)
+ except OverflowError:
+ return -rfloat.INFINITY
+ except ValueError:
+ return rfloat.NAN
+
class Float32(BaseType, Float):
T = rffi.FLOAT
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_errno.py b/pypy/module/test_lib_pypy/ctypes_tests/test_errno.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/test_lib_pypy/ctypes_tests/test_errno.py
@@ -0,0 +1,21 @@
+import py
+
+import ctypes
+from _ctypes import function
+
+_rawffi = py.test.importorskip("_rawffi")
+
+class TestErrno:
+
+ def test_errno_saved_and_restored(self):
+ def check():
+ assert _rawffi.get_errno() == 42
+ assert ctypes.get_errno() == old
+ check.free_temp_buffers = lambda *args: None
+ f = function.CFuncPtr()
+ old = _rawffi.get_errno()
+ f._flags_ = _rawffi.FUNCFLAG_USE_ERRNO
+ ctypes.set_errno(42)
+ f._call_funcptr(check)
+ assert _rawffi.get_errno() == old
+ ctypes.set_errno(0)
diff --git a/pypy/objspace/flow/operation.py b/pypy/objspace/flow/operation.py
--- a/pypy/objspace/flow/operation.py
+++ b/pypy/objspace/flow/operation.py
@@ -30,10 +30,7 @@
def new_style_type(x):
"""Simulate a situation where every class is new-style"""
- t = getattr(x, '__class__', type(x))
- if t is types.ClassType: # guess who's here? exception classes...
- t = type
- return t
+ return getattr(x, '__class__', type(x))
def do_int(x):
return x.__int__()
diff --git a/pypy/objspace/std/abstractstring.py b/pypy/objspace/std/abstractstring.py
new file mode 100644
--- /dev/null
+++ b/pypy/objspace/std/abstractstring.py
@@ -0,0 +1,176 @@
+from pypy.objspace.std.model import W_Object
+from pypy.rlib.objectmodel import specialize
+
+
+class Mixin_BaseStringMethods(object):
+ __slots__ = ()
+
+ def isalnum(w_self, space):
+ return w_self._all_true(space, w_self._isalnum)
+
+ def isalpha(w_self, space):
+ return w_self._all_true(space, w_self._isalpha)
+
+ def isdigit(w_self, space):
+ return w_self._all_true(space, w_self._isdigit)
+
+ def islower(w_self, space):
+ return w_self._none_false_one_true(space,
+ w_self._islower, w_self._isupper)
+
+ def isspace(w_self, space):
+ return w_self._all_true(space, w_self._isspace)
+
+ def isupper(w_self, space):
+ return w_self._none_false_one_true(space,
+ w_self._isupper, w_self._islower)
+
+ def istitle(w_self, space):
+ return w_self._title(space)
+
+ def lower(w_self, space):
+ return w_self._transform(space, w_self._lower)
+
+ def swapcase(w_self, space):
+ return w_self._transform(space, w_self._swapcase)
+
+ def upper(w_self, space):
+ return w_self._transform(space, w_self._upper)
+
+
+class AbstractCharIterator(object):
+
+ def __init__(self, sequence):
+ self.sequence = sequence
+ self.pos = 0
+
+ def __len__(self):
+ return len(self.sequence)
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ ch = self.nextchar()
+ if ch is None:
+ raise StopIteration
+ return ch
+
+ # XXX deprecate nextchar() method
+ def nextchar(self):
+ if self.pos >= len(self):
+ return None
+ idx = self.pos
+ self.pos += 1
+ return self.sequence[idx]
+
+
+class W_AbstractBaseStringObject(W_Object):
+ __slots__ = ()
+
+ def __repr__(w_self):
+ """ representation for debugging purposes """
+ return "%s(%r)" % (w_self.__class__.__name__, w_self.raw_value())
+
+ def builder(w_self, space, size=0):
+ raise NotImplemented, "method not implemented"
+
+ def construct(w_self, space, data):
+ raise NotImplemented, "method not implemented"
+
+ def immutable_unique_id(w_self, space):
+ if w_self.user_overridden_class:
+ return None
+ return space.wrap(compute_unique_id(w_self.unwrap(space)))
+
+ def is_w(self, space, w_other):
+ if not isinstance(w_other, W_AbstractBaseStringObject):
+ return False
+ if self is w_other:
+ return True
+ if self.user_overridden_class or w_other.user_overridden_class:
+ return False
+ return self.unwrap(space) is w_other.unwrap(space)
+
+ def iterator(w_self, space):
+ return AbstractCharIterator(w_self.unwrap(space))
+
+ def length(w_self, space):
+ return len(w_self.unwrap(space))
+
+ def raw_value(w_self):
+ raise NotImplemented, "method not implemented"
+
+ def str_w(w_self, space):
+ raise NotImplemented, "method not implemented"
+
+ def unicode_w(w_self, space):
+ raise NotImplemented, "method not implemented"
+
+ def unwrap(w_self, space):
+ raise NotImplemented, "method not implemented"
+
+ @specialize.arg(2)
+ def _all_true(w_self, space, func):
+ """Test all elements of a list with func for True.
+ Returns True only if all elements test True."""
+ size = w_self.length(space)
+ it = w_self.iterator(space)
+ if size == 0:
+ return space.w_False
+ if size == 1:
+ return space.newbool(func(it.nextchar()))
+ # not all it objects will support iterator protocol, eg rope
+ for pos in range(size):
+ ch = it.nextchar()
+ if not func(ch):
+ return space.w_False
+ return space.w_True
+
+ @specialize.arg(2, 3)
+ def _none_false_one_true(w_self, space, pred, inverse):
+ """Test all elements against predicate and inverse.
+ Returns True only if all elements fail inverse and at least one
+ element passes predicate."""
+ v = w_self.unwrap(space)
+ if len(v) == 1:
+ c = v[0]
+ return space.newbool(pred(c))
+ status = False
+ for idx in range(len(v)):
+ if inverse(v[idx]):
+ return space.w_False
+ elif not status and pred(v[idx]):
+ status = True
+ return space.newbool(status)
+
+ def _title(w_self, space):
+ input = w_self.unwrap(space)
+ cased = False
+ previous_is_cased = False
+
+ for pos in range(0, len(input)):
+ ch = input[pos]
+ if w_self._isupper(ch):
+ if previous_is_cased:
+ return space.w_False
+ previous_is_cased = True
+ cased = True
+ elif w_self._islower(ch):
+ if not previous_is_cased:
+ return space.w_False
+ cased = True
+ else:
+ previous_is_cased = False
+
+ return space.newbool(cased)
+
+ @specialize.arg(2)
+ def _transform(w_self, space, func):
+ sz = w_self.length(space)
+ it = w_self.iterator(space)
+ bd = w_self.builder(space, sz)
+ for pos in range(sz):
+ ch = it.nextchar()
+ bd.append(func(ch))
+ return w_self.construct(space, bd.build())
diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py
--- a/pypy/objspace/std/bytearrayobject.py
+++ b/pypy/objspace/std/bytearrayobject.py
@@ -19,22 +19,45 @@
from pypy.interpreter import gateway
from pypy.interpreter.argument import Signature
from pypy.interpreter.buffer import RWBuffer
+from pypy.objspace.std.abstractstring import \
+ W_AbstractBaseStringObject, Mixin_BaseStringMethods
from pypy.objspace.std.bytearraytype import (
makebytearraydata_w, getbytevalue,
new_bytearray
)
-from pypy.tool.sourcetools import func_with_new_name
-class W_BytearrayObject(W_Object):
+class Mixin_BytearrayMethods(Mixin_BaseStringMethods):
+ __slots__ = ()
+
+
+class W_AbstractBytearrayObject(stringobject.W_AbstractStringObject):
+ __slots__ = ()
+
+
+class W_BytearrayObject(W_AbstractBytearrayObject, Mixin_BytearrayMethods):
from pypy.objspace.std.bytearraytype import bytearray_typedef as typedef
def __init__(w_self, data):
w_self.data = data
- def __repr__(w_self):
- """ representation for debugging purposes """
- return "%s(%s)" % (w_self.__class__.__name__, ''.join(w_self.data))
+ def builder(w_self, space, size=0):
+ return StringBuilder(size)
+
+ def construct(w_self, space, data):
+ return W_BytearrayObject(data)
+
+ def raw_value(w_self):
+ return w_self.data
+
+ def str_w(w_self, space):
+ return w_self.data
+
+ def unicode_w(w_self, space):
+ # XXX should this use the default encoding?
+ from pypy.objspace.std.unicodetype import plain_str2unicode
+ return plain_str2unicode(space, w_self.data)
+
registerimplementation(W_BytearrayObject)
@@ -279,6 +302,36 @@
def str__Bytearray(space, w_bytearray):
return space.wrap(''.join(w_bytearray.data))
+def str_isalnum__Bytearray(space, w_self):
+ return w_self.isalnum(space)
+
+def str_isalpha__Bytearray(space, w_self):
+ return w_self.isalpha(space)
+
+def str_isdigit__Bytearray(space, w_self):
+ return w_self.isdigit(space)
+
+def str_islower__Bytearray(space, w_self):
+ return w_self.islower(space)
+
+def str_isspace__Bytearray(space, w_self):
+ return w_self.isspace(space)
+
+def str_istitle__Bytearray(space, w_self):
+ return w_self.istitle(space)
+
+def str_isupper__Bytearray(space, w_self):
+ return w_self.isupper(space)
+
+def str_lower__Bytearray(space, w_self):
+ return w_self.lower(space)
+
+def str_upper__Bytearray(space, w_self):
+ return w_self.upper(space)
+
+def str_swapcase__Bytearray(space, w_self):
+ return w_self.swapcase(space)
+
def str_count__Bytearray_Int_ANY_ANY(space, w_bytearray, w_char, w_start, w_stop):
char = w_char.intval
bytearray = w_bytearray.data
@@ -372,34 +425,6 @@
w_str = str__Bytearray(space, w_bytearray)
return stringobject.str_decode__String_ANY_ANY(space, w_str, w_encoding, w_errors)
-def str_islower__Bytearray(space, w_bytearray):
- w_str = str__Bytearray(space, w_bytearray)
- return stringobject.str_islower__String(space, w_str)
-
-def str_isupper__Bytearray(space, w_bytearray):
- w_str = str__Bytearray(space, w_bytearray)
- return stringobject.str_isupper__String(space, w_str)
-
-def str_isalpha__Bytearray(space, w_bytearray):
- w_str = str__Bytearray(space, w_bytearray)
- return stringobject.str_isalpha__String(space, w_str)
-
-def str_isalnum__Bytearray(space, w_bytearray):
- w_str = str__Bytearray(space, w_bytearray)
- return stringobject.str_isalnum__String(space, w_str)
-
-def str_isdigit__Bytearray(space, w_bytearray):
- w_str = str__Bytearray(space, w_bytearray)
- return stringobject.str_isdigit__String(space, w_str)
-
-def str_istitle__Bytearray(space, w_bytearray):
- w_str = str__Bytearray(space, w_bytearray)
- return stringobject.str_istitle__String(space, w_str)
-
-def str_isspace__Bytearray(space, w_bytearray):
- w_str = str__Bytearray(space, w_bytearray)
- return stringobject.str_isspace__String(space, w_str)
-
def bytearray_insert__Bytearray_Int_ANY(space, w_bytearray, w_idx, w_other):
where = space.int_w(w_idx)
length = len(w_bytearray.data)
@@ -460,26 +485,11 @@
w_str2, w_max)
return String2Bytearray(space, w_res)
-def str_upper__Bytearray(space, w_bytearray):
- w_str = str__Bytearray(space, w_bytearray)
- w_res = stringobject.str_upper__String(space, w_str)
- return String2Bytearray(space, w_res)
-
-def str_lower__Bytearray(space, w_bytearray):
- w_str = str__Bytearray(space, w_bytearray)
- w_res = stringobject.str_lower__String(space, w_str)
- return String2Bytearray(space, w_res)
-
def str_title__Bytearray(space, w_bytearray):
w_str = str__Bytearray(space, w_bytearray)
w_res = stringobject.str_title__String(space, w_str)
return String2Bytearray(space, w_res)
-def str_swapcase__Bytearray(space, w_bytearray):
- w_str = str__Bytearray(space, w_bytearray)
- w_res = stringobject.str_swapcase__String(space, w_str)
- return String2Bytearray(space, w_res)
-
def str_capitalize__Bytearray(space, w_bytearray):
w_str = str__Bytearray(space, w_bytearray)
w_res = stringobject.str_capitalize__String(space, w_str)
diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py
--- a/pypy/objspace/std/dictmultiobject.py
+++ b/pypy/objspace/std/dictmultiobject.py
@@ -2,6 +2,7 @@
from pypy.objspace.std.model import registerimplementation, W_Object
from pypy.objspace.std.register_all import register_all
from pypy.objspace.std.settype import set_typedef as settypedef
+from pypy.objspace.std.frozensettype import frozenset_typedef as frozensettypedef
from pypy.interpreter import gateway
from pypy.interpreter.argument import Signature
from pypy.interpreter.error import OperationError, operationerrfmt
@@ -488,7 +489,7 @@
class _UnwrappedIteratorMixin:
_mixin_ = True
-
+
def __init__(self, space, strategy, dictimplementation):
IteratorImplementation.__init__(self, space, dictimplementation)
self.iterator = strategy.unerase(dictimplementation.dstorage).iteritems()
@@ -837,10 +838,12 @@
return all_contained_in(space, w_dictview, w_otherview)
return space.w_False
eq__DictViewKeys_settypedef = eq__DictViewKeys_DictViewKeys
+eq__DictViewKeys_frozensettypedef = eq__DictViewKeys_DictViewKeys
eq__DictViewKeys_DictViewItems = eq__DictViewKeys_DictViewKeys
eq__DictViewItems_DictViewItems = eq__DictViewKeys_DictViewKeys
eq__DictViewItems_settypedef = eq__DictViewItems_DictViewItems
+eq__DictViewItems_frozensettypedef = eq__DictViewItems_DictViewItems
def repr__DictViewKeys(space, w_dictview):
w_seq = space.call_function(space.w_list, w_dictview)
diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -7,7 +7,7 @@
from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
from pypy.objspace.std import slicetype
from pypy.interpreter import gateway, baseobjspace
-from pypy.rlib.objectmodel import instantiate, specialize
+from pypy.rlib.objectmodel import instantiate, specialize, newlist_hint
from pypy.rlib.listsort import make_timsort_class
from pypy.rlib import rerased, jit, debug
from pypy.interpreter.argument import Signature
@@ -32,9 +32,11 @@
storage = strategy.erase(None)
return W_ListObject.from_storage_and_strategy(space, storage, strategy)
- at jit.look_inside_iff(lambda space, list_w: jit.isconstant(len(list_w)) and len(list_w) < UNROLL_CUTOFF)
-def get_strategy_from_list_objects(space, list_w):
+ at jit.look_inside_iff(lambda space, list_w, sizehint: jit.isconstant(len(list_w)) and len(list_w) < UNROLL_CUTOFF)
+def get_strategy_from_list_objects(space, list_w, sizehint):
if not list_w:
+ if sizehint != -1:
+ return SizeListStrategy(space, sizehint)
return space.fromcache(EmptyListStrategy)
# check for ints
@@ -75,11 +77,13 @@
class W_ListObject(W_AbstractListObject):
from pypy.objspace.std.listtype import list_typedef as typedef
- def __init__(w_self, space, wrappeditems):
+ def __init__(w_self, space, wrappeditems, sizehint=-1):
assert isinstance(wrappeditems, list)
w_self.space = space
if space.config.objspace.std.withliststrategies:
- w_self.strategy = get_strategy_from_list_objects(space, wrappeditems)
+ w_self.strategy = get_strategy_from_list_objects(space,
+ wrappeditems,
+ sizehint)
else:
w_self.strategy = space.fromcache(ObjectListStrategy)
w_self.init_from_list_w(wrappeditems)
@@ -255,6 +259,7 @@
class ListStrategy(object):
+ sizehint = -1
def __init__(self, space):
self.space = space
@@ -336,6 +341,7 @@
def sort(self, w_list, reverse):
raise NotImplementedError
+
class EmptyListStrategy(ListStrategy):
"""EmptyListStrategy is used when a W_List withouth elements is created.
The storage is None. When items are added to the W_List a new RPython list
@@ -397,7 +403,7 @@
else:
strategy = self.space.fromcache(ObjectListStrategy)
- storage = strategy.get_empty_storage()
+ storage = strategy.get_empty_storage(self.sizehint)
w_list.strategy = strategy
w_list.lstorage = storage
@@ -438,6 +444,13 @@
def reverse(self, w_list):
pass
+class SizeListStrategy(EmptyListStrategy):
+ """ Like empty, but when modified it'll preallocate the size to sizehint
+ """
+ def __init__(self, space, sizehint):
+ self.sizehint = sizehint
+ ListStrategy.__init__(self, space)
+
class RangeListStrategy(ListStrategy):
"""RangeListStrategy is used when a list is created using the range method.
The storage is a tuple containing only three integers start, step and length
@@ -660,8 +673,10 @@
l = [self.unwrap(w_item) for w_item in list_w]
w_list.lstorage = self.erase(l)
- def get_empty_storage(self):
- return self.erase([])
+ def get_empty_storage(self, sizehint):
+ if sizehint == -1:
+ return self.erase([])
+ return self.erase(newlist_hint(sizehint))
def clone(self, w_list):
l = self.unerase(w_list.lstorage)
diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py
--- a/pypy/objspace/std/newformat.py
+++ b/pypy/objspace/std/newformat.py
@@ -10,6 +10,10 @@
@specialize.argtype(1)
+ at jit.look_inside_iff(lambda space, s, start, end:
+ jit.isconstant(s) and
+ jit.isconstant(start) and
+ jit.isconstant(end))
def _parse_int(space, s, start, end):
"""Parse a number and check for overflows"""
result = 0
@@ -91,9 +95,18 @@
if s[i] == "{":
i += 1
markup_follows = False
- # Attach literal data
+ # Attach literal data, ending with { or }
out.append_slice(s, last_literal, i - 1)
if not markup_follows:
+ if self.parser_list_w is not None:
+ end_literal = i - 1
+ assert end_literal > last_literal
+ literal = self.template[last_literal:end_literal]
+ w_entry = space.newtuple([
+ space.wrap(literal),
+ space.w_None, space.w_None, space.w_None])
+ self.parser_list_w.append(w_entry)
+ self.last_end = i
last_literal = i
continue
nested = 1
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
@@ -300,8 +300,9 @@
make_sure_not_resized(list_w)
return wraptuple(self, list_w)
- def newlist(self, list_w):
- return W_ListObject(self, list_w)
+ def newlist(self, list_w, sizehint=-1):
+ assert not list_w or sizehint == -1
+ return W_ListObject(self, list_w, sizehint)
def newlist_str(self, list_s):
return W_ListObject.newlist_str(self, list_s)
diff --git a/pypy/objspace/std/ropeobject.py b/pypy/objspace/std/ropeobject.py
--- a/pypy/objspace/std/ropeobject.py
+++ b/pypy/objspace/std/ropeobject.py
@@ -17,9 +17,26 @@
from pypy.objspace.std.stringobject import (
mod__String_ANY as mod__Rope_ANY,
str_format__String as str_format__Rope,
- _upper, _lower, DEFAULT_NOOP_TABLE)
+ DEFAULT_NOOP_TABLE)
-class W_RopeObject(stringobject.W_AbstractStringObject):
+
+class RopeBuilder(object):
+ """Mimic sufficent StringBuilder API for over simple character arrays"""
+
+ def __init__(self, size=0):
+ self.data = [' '] * size
+ self.pos = 0
+
+ def append(self, ch):
+ self.data[self.pos] = ch
+ self.pos += 1
+
+ def build(self):
+ return rope.rope_from_charlist(self.data)
+
+
+class W_RopeObject(stringobject.W_AbstractStringObject,
+ stringobject.Mixin_StringMethods):
from pypy.objspace.std.stringtype import str_typedef as typedef
_immutable_fields_ = ['_node']
@@ -28,24 +45,34 @@
assert node.is_bytestring()
w_self._node = node
- def __repr__(w_self):
- """ representation for debugging purposes """
- return "%s(%r)" % (w_self.__class__.__name__, w_self._node)
+ def builder(w_self, space, size=0):
+ return RopeBuilder(size)
- def unwrap(w_self, space):
+ def construct(w_self, space, data):
+ return W_RopeObject(data)
+
+ def iterator(w_self, space):
+ return rope.ItemIterator(w_self._node)
+
+ def length(w_self, space):
+ return w_self._node.length()
+
+ def raw_value(w_self):
+ return w_self._node
+
+ def str_w(w_self, space):
return w_self._node.flatten_string()
- str_w = unwrap
+
+ def unicode_w(w_self, space):
+ # XXX should this use the default encoding?
+ from pypy.objspace.std.unicodetype import plain_str2unicode
+ return plain_str2unicode(space, w_self._node.flatten_string())
def create_if_subclassed(w_self):
if type(w_self) is W_RopeObject:
return w_self
return W_RopeObject(w_self._node)
- def unicode_w(w_self, space):
- # XXX should this use the default encoding?
- from pypy.objspace.std.unicodetype import plain_str2unicode
- return plain_str2unicode(space, w_self._node.flatten_string())
-
W_RopeObject.EMPTY = W_RopeObject(rope.LiteralStringNode.EMPTY)
W_RopeObject.PREBUILT = [W_RopeObject(rope.LiteralStringNode.PREBUILT[i])
for i in range(256)]
@@ -69,123 +96,43 @@
registerimplementation(W_RopeIterObject)
-def _is_generic(space, w_self, fun):
- l = w_self._node.length()
- if l == 0:
- return space.w_False
- iter = rope.ItemIterator(w_self._node)
- for i in range(l):
- if not fun(iter.nextchar()):
- return space.w_False
- return space.w_True
-_is_generic._annspecialcase_ = "specialize:arg(2)"
-
-_isspace = lambda c: c.isspace()
-_isdigit = lambda c: c.isdigit()
-_isalpha = lambda c: c.isalpha()
-_isalnum = lambda c: c.isalnum()
-
def str_isspace__Rope(space, w_self):
- return _is_generic(space, w_self, _isspace)
+ return w_self.isspace(space)
def str_isdigit__Rope(space, w_self):
- return _is_generic(space, w_self, _isdigit)
+ return w_self.isdigit(space)
def str_isalpha__Rope(space, w_self):
- return _is_generic(space, w_self, _isalpha)
+ return w_self.isalpha(space)
def str_isalnum__Rope(space, w_self):
- return _is_generic(space, w_self, _isalnum)
+ return w_self.isalnum(space)
def str_isupper__Rope(space, w_self):
"""Return True if all cased characters in S are uppercase and there is
at least one cased character in S, False otherwise."""
- l = w_self._node.length()
-
- if l == 0:
- return space.w_False
- cased = False
- iter = rope.ItemIterator(w_self._node)
- for idx in range(l):
- c = iter.nextchar()
- if c.islower():
- return space.w_False
- elif not cased and c.isupper():
- cased = True
- return space.newbool(cased)
+ return w_self.isupper(space)
def str_islower__Rope(space, w_self):
"""Return True if all cased characters in S are lowercase and there is
at least one cased character in S, False otherwise."""
- l = w_self._node.length()
-
- if l == 0:
- return space.w_False
- cased = False
- iter = rope.ItemIterator(w_self._node)
- for idx in range(l):
- c = iter.nextchar()
- if c.isupper():
- return space.w_False
- elif not cased and c.islower():
- cased = True
- return space.newbool(cased)
+ return w_self.islower(space)
def str_istitle__Rope(space, w_self):
"""Return True if S is a titlecased string and there is at least one
character in S, i.e. uppercase characters may only follow uncased
characters and lowercase characters only cased ones. Return False
otherwise."""
- cased = False
- previous_is_cased = False
+ return w_self.istitle(space)
- iter = rope.ItemIterator(w_self._node)
- for pos in range(0, w_self._node.length()):
- ch = iter.nextchar()
- if ch.isupper():
- if previous_is_cased:
- return space.w_False
- previous_is_cased = True
- cased = True
- elif ch.islower():
- if not previous_is_cased:
- return space.w_False
- cased = True
- else:
- previous_is_cased = False
+def str_lower__Rope(space, w_self):
+ return w_self.lower(space)
- return space.newbool(cased)
-
-def _local_transform(node, transform):
- l = node.length()
- res = [' '] * l
- iter = rope.ItemIterator(node)
- for i in range(l):
- ch = iter.nextchar()
- res[i] = transform(ch)
-
- return W_RopeObject(rope.rope_from_charlist(res))
-_local_transform._annspecialcase_ = "specialize:arg(1)"
+def str_swapcase__Rope(space, w_self):
+ return w_self.swapcase(space)
def str_upper__Rope(space, w_self):
- return _local_transform(w_self._node, _upper)
-
-def str_lower__Rope(space, w_self):
- return _local_transform(w_self._node, _lower)
-
-def _swapcase(ch):
- if ch.isupper():
- o = ord(ch) + 32
- return chr(o)
- elif ch.islower():
- o = ord(ch) - 32
- return chr(o)
- else:
- return ch
-
-def str_swapcase__Rope(space, w_self):
- return _local_transform(w_self._node, _swapcase)
-
+ return w_self.upper(space)
def str_capitalize__Rope(space, w_self):
node = w_self._node
@@ -223,9 +170,9 @@
for pos in range(0, length):
ch = iter.nextchar()
if not prev_letter.isalpha():
- buffer[pos] = _upper(ch)
+ buffer[pos] = w_self._upper(ch)
else:
- buffer[pos] = _lower(ch)
+ buffer[pos] = w_self._lower(ch)
prev_letter = buffer[pos]
diff --git a/pypy/objspace/std/ropeunicodeobject.py b/pypy/objspace/std/ropeunicodeobject.py
--- a/pypy/objspace/std/ropeunicodeobject.py
+++ b/pypy/objspace/std/ropeunicodeobject.py
@@ -4,7 +4,6 @@
from pypy.interpreter.error import OperationError, operationerrfmt
from pypy.interpreter import gateway
from pypy.objspace.std.stringobject import W_StringObject
-from pypy.objspace.std.unicodeobject import _normalize_index
from pypy.objspace.std.ropeobject import W_RopeObject
from pypy.objspace.std.noneobject import W_NoneObject
from pypy.rlib import rope
@@ -14,7 +13,6 @@
from pypy.objspace.std.tupleobject import W_TupleObject
from pypy.rlib.rarithmetic import intmask, ovfcheck
from pypy.module.unicodedata import unicodedb
-from pypy.tool.sourcetools import func_with_new_name
from pypy.objspace.std.formatting import mod_format
@@ -77,6 +75,22 @@
return encode_object(space, w_unistr, encoding, errors)
+# XXX create shared base class with RopeBuilder
+class RopeUnicodeBuilder(object):
+ """Mimic sufficent StringBuilder API for over simple character arrays"""
+
+ def __init__(self, size=0):
+ self.data = [u' '] * size
+ self.pos = 0
+
+ def append(self, ch):
+ self.data[self.pos] = ch
+ self.pos += 1
+
+ def build(self):
+ return rope.rope_from_unicharlist(self.data)
+
+
class W_RopeUnicodeObject(unicodeobject.W_AbstractUnicodeObject):
from pypy.objspace.std.unicodetype import unicode_typedef as typedef
_immutable_fields_ = ['_node']
@@ -84,32 +98,36 @@
def __init__(w_self, node):
w_self._node = node
- def __repr__(w_self):
- """ representation for debugging purposes """
- return "%s(%r)" % (w_self.__class__.__name__, w_self._node)
+ def builder(w_self, space, size=0):
+ return RopeUnicodeBuilder(size)
- def unwrap(w_self, space):
- # for testing
- return w_self._node.flatten_unicode()
+ def construct(w_self, space, data):
+ return W_RopeUnicodeObject(data)
+
+ def iterator(w_self, space):
+ return rope.ItemIterator(w_self._node)
+
+ def length(w_self, space):
+ return w_self._node.length()
+
+ def raw_value(w_self):
+ return w_self._node
def str_w(w_self, space):
return space.str_w(space.str(w_self))
+ def unicode_w(self, space):
+ return self._node.flatten_unicode()
+
def create_if_subclassed(w_self):
if type(w_self) is W_RopeUnicodeObject:
return w_self
return W_RopeUnicodeObject(w_self._node)
- def unicode_w(self, space):
- return self._node.flatten_unicode()
-
W_RopeUnicodeObject.EMPTY = W_RopeUnicodeObject(rope.LiteralStringNode.EMPTY)
registerimplementation(W_RopeUnicodeObject)
-def _isspace(uchar_ord):
- return unicodedb.isspace(uchar_ord)
-
def ropeunicode_w(space, w_str):
if isinstance(w_str, W_RopeUnicodeObject):
return w_str._node
@@ -319,81 +337,38 @@
def mul__ANY_RopeUnicode(space, w_times, w_uni):
return mul__RopeUnicode_ANY(space, w_uni, w_times)
+def unicode_isspace__RopeUnicode(space, w_self):
+ return w_self.isspace(space)
-def make_generic(funcname):
- def func(space, w_self):
- node = w_self._node
- if node.length() == 0:
- return space.w_False
- iter = rope.ItemIterator(node)
- for idx in range(node.length()):
- if not getattr(unicodedb, funcname)(iter.nextint()):
- return space.w_False
- return space.w_True
- return func_with_new_name(func, "unicode_%s__RopeUnicode" % (funcname, ))
+def unicode_isalpha__RopeUnicode(space, w_self):
+ return w_self.isalpha(space)
-unicode_isspace__RopeUnicode = make_generic("isspace")
-unicode_isalpha__RopeUnicode = make_generic("isalpha")
-unicode_isalnum__RopeUnicode = make_generic("isalnum")
-unicode_isdecimal__RopeUnicode = make_generic("isdecimal")
-unicode_isdigit__RopeUnicode = make_generic("isdigit")
-unicode_isnumeric__RopeUnicode = make_generic("isnumeric")
+def unicode_isalnum__RopeUnicode(space, w_self):
+ return w_self.isalnum(space)
-def unicode_islower__RopeUnicode(space, w_unicode):
- cased = False
- iter = rope.ItemIterator(w_unicode._node)
- while 1:
- try:
- ch = iter.nextint()
- except StopIteration:
- return space.newbool(cased)
- if (unicodedb.isupper(ch) or
- unicodedb.istitle(ch)):
- return space.w_False
- if not cased and unicodedb.islower(ch):
- cased = True
+def unicode_isdecimal__RopeUnicode(space, w_self):
+ return w_self.isdecimal(space)
-def unicode_isupper__RopeUnicode(space, w_unicode):
- cased = False
- iter = rope.ItemIterator(w_unicode._node)
- while 1:
- try:
- ch = iter.nextint()
- except StopIteration:
- return space.newbool(cased)
- if (unicodedb.islower(ch) or
- unicodedb.istitle(ch)):
- return space.w_False
- if not cased and unicodedb.isupper(ch):
- cased = True
+def unicode_isdigit__RopeUnicode(space, w_self):
+ return w_self.isdigit(space)
-def unicode_istitle__RopeUnicode(space, w_unicode):
- cased = False
- previous_is_cased = False
- iter = rope.ItemIterator(w_unicode._node)
- while 1:
- try:
- ch = iter.nextint()
- except StopIteration:
- return space.newbool(cased)
- if (unicodedb.isupper(ch) or
- unicodedb.istitle(ch)):
- if previous_is_cased:
- return space.w_False
- previous_is_cased = cased = True
- elif unicodedb.islower(ch):
- if not previous_is_cased:
- return space.w_False
- previous_is_cased = cased = True
- else:
- previous_is_cased = False
+def unicode_isnumeric__RopeUnicode(space, w_self):
+ return w_self.isnumeric(space)
+def unicode_islower__RopeUnicode(space, w_self):
+ return w_self.islower(space)
+
+def unicode_isupper__RopeUnicode(space, w_self):
+ return w_self.isupper(space)
+
+def unicode_istitle__RopeUnicode(space, w_self):
+ return w_self.istitle(space)
def _contains(i, uni):
return unichr(i) in uni
def unicode_strip__RopeUnicode_None(space, w_self, w_chars):
- return W_RopeUnicodeObject(rope.strip(w_self._node, True, True, _isspace))
+ return W_RopeUnicodeObject(rope.strip(w_self._node, True, True, unicodedb.isspace))
def unicode_strip__RopeUnicode_RopeUnicode(space, w_self, w_chars):
return W_RopeUnicodeObject(rope.strip(w_self._node, True, True, _contains,
w_chars._node.flatten_unicode()))
@@ -403,7 +378,7 @@
unicode_from_string(space, w_chars))
def unicode_lstrip__RopeUnicode_None(space, w_self, w_chars):
- return W_RopeUnicodeObject(rope.strip(w_self._node, True, False, _isspace))
+ return W_RopeUnicodeObject(rope.strip(w_self._node, True, False, unicodedb.isspace))
def unicode_lstrip__RopeUnicode_RopeUnicode(space, w_self, w_chars):
return W_RopeUnicodeObject(rope.strip(w_self._node, True, False, _contains,
w_chars._node.flatten_unicode()))
@@ -412,7 +387,7 @@
unicode_from_string(space, w_chars))
def unicode_rstrip__RopeUnicode_None(space, w_self, w_chars):
- return W_RopeUnicodeObject(rope.strip(w_self._node, False, True, _isspace))
+ return W_RopeUnicodeObject(rope.strip(w_self._node, False, True, unicodedb.isspace))
def unicode_rstrip__RopeUnicode_RopeUnicode(space, w_self, w_chars):
return W_RopeUnicodeObject(rope.strip(w_self._node, False, True, _contains,
w_chars._node.flatten_unicode()))
@@ -450,38 +425,14 @@
previous_is_cased = unicodedb.iscased(unichar)
return W_RopeUnicodeObject(rope.rope_from_unicharlist(result))
+def unicode_lower__RopeUnicode(space, w_self):
+ return w_self.lower(space)
-def _local_transform(node, transform):
- l = node.length()
- res = [u' '] * l
- iter = rope.ItemIterator(node)
- for i in range(l):
- ch = iter.nextint()
- res[i] = transform(ch)
-
- return W_RopeUnicodeObject(rope.rope_from_unicharlist(res))
-_local_transform._annspecialcase_ = "specialize:arg(1)"
-
-def _tolower(ordch):
- return unichr(unicodedb.tolower(ordch))
-def unicode_lower__RopeUnicode(space, w_self):
- return _local_transform(w_self._node, _tolower)
-
-def _toupper(ordch):
- return unichr(unicodedb.toupper(ordch))
def unicode_upper__RopeUnicode(space, w_self):
- return _local_transform(w_self._node, _toupper)
-
-def _swapcase(ordch):
- if unicodedb.islower(ordch):
- return unichr(unicodedb.toupper(ordch))
- elif unicodedb.isupper(ordch):
- return unichr(unicodedb.tolower(ordch))
- else:
- return unichr(ordch)
+ return w_self.upper(space)
def unicode_swapcase__RopeUnicode(space, w_self):
- return _local_transform(w_self._node, _swapcase)
+ return w_self.swapcase(space)
def _convert_idx_params(space, w_self, w_start, w_end):
self = w_self._node
@@ -658,7 +609,7 @@
selfnode = w_self._node
maxsplit = space.int_w(w_maxsplit)
res_w = [W_RopeUnicodeObject(node)
- for node in rope.split_chars(selfnode, maxsplit, _isspace)]
+ for node in rope.split_chars(selfnode, maxsplit, unicodedb.isspace)]
return space.newlist(res_w)
def unicode_split__RopeUnicode_RopeUnicode_ANY(space, w_self, w_delim, w_maxsplit):
@@ -677,7 +628,7 @@
selfnode = w_self._node
maxsplit = space.int_w(w_maxsplit)
res_w = [W_RopeUnicodeObject(node)
- for node in rope.rsplit_chars(selfnode, maxsplit, _isspace)]
+ for node in rope.rsplit_chars(selfnode, maxsplit, unicodedb.isspace)]
return space.newlist(res_w)
diff --git a/pypy/objspace/std/stringobject.py b/pypy/objspace/std/stringobject.py
--- a/pypy/objspace/std/stringobject.py
+++ b/pypy/objspace/std/stringobject.py
@@ -15,41 +15,80 @@
from pypy.rlib.rstring import StringBuilder, split
from pypy.interpreter.buffer import StringBuffer
+from pypy.objspace.std.abstractstring import \
+ W_AbstractBaseStringObject, Mixin_BaseStringMethods
+from pypy.objspace.std.formatting import mod_format
from pypy.objspace.std.stringtype import sliced, wrapstr, wrapchar, \
stringendswith, stringstartswith, joined2
-from pypy.objspace.std.formatting import mod_format
-class W_AbstractStringObject(W_Object):
+class Mixin_StringMethods(Mixin_BaseStringMethods):
__slots__ = ()
- def is_w(self, space, w_other):
- if not isinstance(w_other, W_AbstractStringObject):
- return False
- if self is w_other:
- return True
- if self.user_overridden_class or w_other.user_overridden_class:
- return False
- return space.str_w(self) is space.str_w(w_other)
- def immutable_unique_id(self, space):
- if self.user_overridden_class:
- return None
- return space.wrap(compute_unique_id(space.str_w(self)))
+class W_AbstractStringObject(W_AbstractBaseStringObject):
+ __slots__ = ()
+ def unwrap(w_self, space):
+ return w_self.str_w(space)
-class W_StringObject(W_AbstractStringObject):
+ def _isalnum(self, ch):
+ return ch.isalnum()
+
+ def _isalpha(self, ch):
+ return ch.isalpha()
+
+ def _isdigit(self, ch):
+ return ch.isdigit()
+
+ def _islower(self, ch):
+ return ch.islower()
+
+ def _isspace(self, ch):
+ return ch.isspace()
+
+ def _isupper(self, ch):
+ return ch.isupper()
+
+ def _lower(self, ch):
+ if ch.isupper():
+ o = ord(ch) + 32
+ return chr(o)
+ else:
+ return ch
+
+ def _upper(self, ch):
+ if ch.islower():
+ o = ord(ch) - 32
+ return chr(o)
+ else:
+ return ch
+
+ def _swapcase(self, ch):
+ if ch.isupper():
+ o = ord(ch) + 32
+ return chr(o)
+ elif ch.islower():
+ o = ord(ch) - 32
+ return chr(o)
+ else:
+ return ch
+
+
+class W_StringObject(W_AbstractStringObject, Mixin_StringMethods):
from pypy.objspace.std.stringtype import str_typedef as typedef
_immutable_fields_ = ['_value']
def __init__(w_self, str):
w_self._value = str
- def __repr__(w_self):
- """ representation for debugging purposes """
- return "%s(%r)" % (w_self.__class__.__name__, w_self._value)
+ def builder(w_self, space, size=0):
+ return StringBuilder(size)
- def unwrap(w_self, space):
+ def construct(w_self, space, data):
+ return W_StringObject(data)
+
+ def raw_value(w_self):
return w_self._value
def str_w(w_self, space):
@@ -60,140 +99,50 @@
from pypy.objspace.std.unicodetype import plain_str2unicode
return plain_str2unicode(space, w_self._value)
+
registerimplementation(W_StringObject)
W_StringObject.EMPTY = W_StringObject('')
W_StringObject.PREBUILT = [W_StringObject(chr(i)) for i in range(256)]
del i
- at specialize.arg(2)
-def _is_generic(space, w_self, fun):
- v = w_self._value
- if len(v) == 0:
- return space.w_False
- if len(v) == 1:
- c = v[0]
- return space.newbool(fun(c))
- else:
- return _is_generic_loop(space, v, fun)
+def str_isalnum__String(space, w_self):
+ return w_self.isalnum(space)
- at specialize.arg(2)
-def _is_generic_loop(space, v, fun):
- for idx in range(len(v)):
- if not fun(v[idx]):
- return space.w_False
- return space.w_True
+def str_isalpha__String(space, w_self):
+ return w_self.isalpha(space)
-def _upper(ch):
- if ch.islower():
- o = ord(ch) - 32
- return chr(o)
- else:
- return ch
-
-def _lower(ch):
- if ch.isupper():
- o = ord(ch) + 32
- return chr(o)
- else:
- return ch
-
-_isspace = lambda c: c.isspace()
-_isdigit = lambda c: c.isdigit()
-_isalpha = lambda c: c.isalpha()
-_isalnum = lambda c: c.isalnum()
+def str_isdigit__String(space, w_self):
+ return w_self.isdigit(space)
def str_isspace__String(space, w_self):
- return _is_generic(space, w_self, _isspace)
+ return w_self.isspace(space)
-def str_isdigit__String(space, w_self):
- return _is_generic(space, w_self, _isdigit)
-
-def str_isalpha__String(space, w_self):
- return _is_generic(space, w_self, _isalpha)
-
-def str_isalnum__String(space, w_self):
- return _is_generic(space, w_self, _isalnum)
+def str_islower__String(space, w_self):
+ """Return True if all cased characters in S are lowercase and there is
+at least one cased character in S, False otherwise."""
+ return w_self.islower(space)
def str_isupper__String(space, w_self):
"""Return True if all cased characters in S are uppercase and there is
at least one cased character in S, False otherwise."""
- v = w_self._value
- if len(v) == 1:
- c = v[0]
- return space.newbool(c.isupper())
- cased = False
- for idx in range(len(v)):
- if v[idx].islower():
- return space.w_False
- elif not cased and v[idx].isupper():
- cased = True
- return space.newbool(cased)
-
-def str_islower__String(space, w_self):
- """Return True if all cased characters in S are lowercase and there is
-at least one cased character in S, False otherwise."""
- v = w_self._value
- if len(v) == 1:
- c = v[0]
- return space.newbool(c.islower())
- cased = False
- for idx in range(len(v)):
- if v[idx].isupper():
- return space.w_False
- elif not cased and v[idx].islower():
- cased = True
- return space.newbool(cased)
+ return w_self.isupper(space)
def str_istitle__String(space, w_self):
"""Return True if S is a titlecased string and there is at least one
character in S, i.e. uppercase characters may only follow uncased
characters and lowercase characters only cased ones. Return False
otherwise."""
- input = w_self._value
- cased = False
- previous_is_cased = False
+ return w_self.istitle(space)
- for pos in range(0, len(input)):
- ch = input[pos]
- if ch.isupper():
- if previous_is_cased:
- return space.w_False
- previous_is_cased = True
- cased = True
- elif ch.islower():
- if not previous_is_cased:
- return space.w_False
- cased = True
- else:
- previous_is_cased = False
+def str_lower__String(space, w_self):
+ return w_self.lower(space)
- return space.newbool(cased)
+def str_swapcase__String(space, w_self):
+ return w_self.swapcase(space)
def str_upper__String(space, w_self):
- self = w_self._value
- return space.wrap(self.upper())
-
-def str_lower__String(space, w_self):
- self = w_self._value
- return space.wrap(self.lower())
-
-def str_swapcase__String(space, w_self):
- self = w_self._value
- builder = StringBuilder(len(self))
- for i in range(len(self)):
- ch = self[i]
- if ch.isupper():
- o = ord(ch) + 32
- builder.append(chr(o))
- elif ch.islower():
- o = ord(ch) - 32
- builder.append(chr(o))
- else:
- builder.append(ch)
-
- return space.wrap(builder.build())
-
+ return w_self.upper(space)
def str_capitalize__String(space, w_self):
input = w_self._value
@@ -224,10 +173,10 @@
for pos in range(len(input)):
ch = input[pos]
if not prev_letter.isalpha():
- ch = _upper(ch)
+ ch = w_self._upper(ch)
builder.append(ch)
else:
- ch = _lower(ch)
+ ch = w_self._lower(ch)
builder.append(ch)
prev_letter = ch
diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py
--- a/pypy/objspace/std/test/test_dictmultiobject.py
+++ b/pypy/objspace/std/test/test_dictmultiobject.py
@@ -613,6 +613,7 @@
assert len(keys) == 2
assert set(keys) == set([1, "a"])
assert keys == set([1, "a"])
+ assert keys == frozenset([1, "a"])
assert keys != set([1, "a", "b"])
assert keys != set([1, "b"])
assert keys != set([1])
@@ -633,6 +634,7 @@
assert len(items) == 2
assert set(items) == set([(1, 10), ("a", "ABC")])
assert items == set([(1, 10), ("a", "ABC")])
+ assert items == frozenset([(1, 10), ("a", "ABC")])
assert items != set([(1, 10), ("a", "ABC"), "junk"])
assert items != set([(1, 10), ("a", "def")])
assert items != set([(1, 10)])
diff --git a/pypy/objspace/std/test/test_listobject.py b/pypy/objspace/std/test/test_listobject.py
--- a/pypy/objspace/std/test/test_listobject.py
+++ b/pypy/objspace/std/test/test_listobject.py
@@ -1,6 +1,7 @@
# coding: iso-8859-15
import random
-from pypy.objspace.std.listobject import W_ListObject
+from pypy.objspace.std.listobject import W_ListObject, SizeListStrategy,\
+ IntegerListStrategy, ObjectListStrategy
from pypy.interpreter.error import OperationError
from pypy.conftest import gettestobjspace, option
@@ -390,6 +391,16 @@
assert self.space.eq_w(self.space.le(w_list4, w_list3),
self.space.w_True)
+ def test_sizehint(self):
+ space = self.space
+ w_l = space.newlist([], sizehint=10)
+ assert isinstance(w_l.strategy, SizeListStrategy)
+ space.call_method(w_l, 'append', space.wrap(3))
+ assert isinstance(w_l.strategy, IntegerListStrategy)
+ w_l = space.newlist([], sizehint=10)
+ space.call_method(w_l, 'append', space.w_None)
+ assert isinstance(w_l.strategy, ObjectListStrategy)
+
class AppTestW_ListObject(object):
def setup_class(cls):
diff --git a/pypy/objspace/std/test/test_newformat.py b/pypy/objspace/std/test/test_newformat.py
--- a/pypy/objspace/std/test/test_newformat.py
+++ b/pypy/objspace/std/test/test_newformat.py
@@ -11,6 +11,7 @@
assert self.s("}}").format() == self.s("}")
assert self.s("{} {{ {}").format(1, 2) == self.s("1 { 2")
assert self.s("{{}}").format() == self.s("{}")
+ assert self.s("{{{{").format() == self.s("{{")
def test_empty(self):
assert self.s().format() == self.s()
@@ -385,6 +386,12 @@
for x in l[0]:
assert isinstance(x, unicode)
+ def test_formatter_parser_escape(self):
+ l = list("{{a}}"._formatter_parser())
+ assert l == [('{', None, None, None), ('a}', None, None, None)]
+ l = list("{{{{"._formatter_parser())
+ assert l == [('{', None, None, None), ('{', None, None, None)]
+
def test_formatter_field_name_split(self):
first, rest = ''._formatter_field_name_split()
assert first == ''
diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py
--- a/pypy/objspace/std/test/test_unicodeobject.py
+++ b/pypy/objspace/std/test/test_unicodeobject.py
@@ -195,6 +195,58 @@
assert u"Brown Fox".title() == u"Brown Fox"
assert u"bro!wn fox".title() == u"Bro!Wn Fox"
+ def test_isalnum(self):
+ assert u"".isalnum() == False
+ assert u"!Bro12345w&&&&n Fox".isalnum() == False
+ assert u"125 Brown Foxes".isalnum() == False
+ assert u"125BrownFoxes".isalnum() == True
+
+ def test_isalpha(self):
+ assert u"".isalpha() == False
+ assert u"!Bro12345w&&&&nFox".isalpha() == False
+ assert u"Brown Foxes".isalpha() == False
+ assert u"125".isalpha() == False
+
+ def test_isdigit(self):
+ assert u"".isdigit() == False
+ assert u"!Bro12345w&&&&nFox".isdigit() == False
+ assert u"Brown Foxes".isdigit() == False
+ assert u"125".isdigit() == True
+
+ def test_isdecimal(self):
+ assert u"".isdecimal() == False
+ assert u"42!".isdecimal() == False
+ assert u"\t1337".isdecimal() == False
+ assert u"6".isdecimal() == True
+
+ def test_isspace(self):
+ assert u"".isspace() == False
+ assert u"!Bro12345w&&&&nFox".isspace() == False
+ assert u" ".isspace() == True
+ assert u"\t\t\b\b\n".isspace() == False
+ assert u"\t\t".isspace() == True
+ assert u"\t\t\r\r\n".isspace() == True
+
+ def test_islower(self):
+ assert u"".islower() == False
+ assert u" ".islower() == False
+ assert u"\t\t\b\b\n".islower() == False
+ assert u"b".islower() == True
+ assert u"bbb".islower() == True
+ assert u"!bbb".islower() == True
+ assert u"BBB".islower() == False
+ assert u"bbbBBB".islower() == False
+
+ def test_isupper(self):
+ assert u"".isupper() == False
+ assert u" ".isupper() == False
+ assert u"\t\t\b\b\n".isupper() == False
+ assert u"B".isupper() == True
+ assert u"BBB".isupper() == True
+ assert u"!BBB".isupper() == True
+ assert u"bbb".isupper() == False
+ assert u"BBBbbb".isupper() == False
+
def test_istitle(self):
assert u"".istitle() == False
assert u"!".istitle() == False
@@ -232,6 +284,12 @@
assert (u'\u019b\u1d00\u1d86\u0221\u1fb7'.capitalize() ==
u'\u019b\u1d00\u1d86\u0221\u1fb7')
+ def test_lower(self):
+ assert u"ABC".lower() == u"abc"
+
+ def test_upper(self):
+ assert u"abc".upper() == u"ABC"
+
def test_rjust(self):
s = u"abc"
assert s.rjust(2) == s
diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py
--- a/pypy/objspace/std/tupleobject.py
+++ b/pypy/objspace/std/tupleobject.py
@@ -6,8 +6,11 @@
from pypy.rlib.rarithmetic import intmask
from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
from pypy.objspace.std import slicetype
-from pypy.interpreter import gateway
from pypy.rlib.debug import make_sure_not_resized
+from pypy.rlib import jit
+
+# Tuples of known length up to UNROLL_TUPLE_LIMIT have unrolled certain methods
+UNROLL_TUPLE_LIMIT = 10
class W_AbstractTupleObject(W_Object):
__slots__ = ()
@@ -114,18 +117,28 @@
def mul__ANY_Tuple(space, w_times, w_tuple):
return mul_tuple_times(space, w_tuple, w_times)
+def tuple_unroll_condition(space, w_tuple1, w_tuple2):
+ lgt1 = len(w_tuple1.wrappeditems)
+ lgt2 = len(w_tuple2.wrappeditems)
+ return ((jit.isconstant(lgt1) and lgt1 <= UNROLL_TUPLE_LIMIT) or
+ (jit.isconstant(lgt2) and lgt2 <= UNROLL_TUPLE_LIMIT))
+
+ at jit.look_inside_iff(tuple_unroll_condition)
def eq__Tuple_Tuple(space, w_tuple1, w_tuple2):
items1 = w_tuple1.wrappeditems
items2 = w_tuple2.wrappeditems
- if len(items1) != len(items2):
+ lgt1 = len(items1)
+ lgt2 = len(items2)
+ if lgt1 != lgt2:
return space.w_False
- for i in range(len(items1)):
+ for i in range(lgt1):
item1 = items1[i]
item2 = items2[i]
if not space.eq_w(item1, item2):
return space.w_False
return space.w_True
+ at jit.look_inside_iff(tuple_unroll_condition)
def lt__Tuple_Tuple(space, w_tuple1, w_tuple2):
items1 = w_tuple1.wrappeditems
items2 = w_tuple2.wrappeditems
@@ -137,6 +150,7 @@
# No more items to compare -- compare sizes
return space.newbool(len(items1) < len(items2))
+ at jit.look_inside_iff(tuple_unroll_condition)
def gt__Tuple_Tuple(space, w_tuple1, w_tuple2):
items1 = w_tuple1.wrappeditems
items2 = w_tuple2.wrappeditems
@@ -161,6 +175,9 @@
def hash__Tuple(space, w_tuple):
return space.wrap(hash_tuple(space, w_tuple.wrappeditems))
+ at jit.look_inside_iff(lambda space, wrappeditems:
+ jit.isconstant(len(wrappeditems)) and
+ len(wrappeditems) < UNROLL_TUPLE_LIMIT)
def hash_tuple(space, wrappeditems):
# this is the CPython 2.4 algorithm (changed from 2.3)
mult = 1000003
diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py
--- a/pypy/objspace/std/unicodeobject.py
+++ b/pypy/objspace/std/unicodeobject.py
@@ -15,27 +15,61 @@
from pypy.rlib.rstring import UnicodeBuilder
from pypy.rlib.runicode import unicode_encode_unicode_escape
from pypy.module.unicodedata import unicodedb
-from pypy.tool.sourcetools import func_with_new_name
+from pypy.objspace.std.abstractstring import \
+ W_AbstractBaseStringObject, Mixin_BaseStringMethods
from pypy.objspace.std.formatting import mod_format
from pypy.objspace.std.stringtype import stringstartswith, stringendswith
-class W_AbstractUnicodeObject(W_Object):
+
+class Mixin_UnicodeMethods(Mixin_BaseStringMethods):
+ __slows__ = ()
+
+ def isdecimal(w_self, space):
+ return w_self._all_true(space, w_self._isdecimal)
+
+
+class W_AbstractUnicodeObject(W_AbstractBaseStringObject, Mixin_UnicodeMethods):
__slots__ = ()
- def is_w(self, space, w_other):
- if not isinstance(w_other, W_AbstractUnicodeObject):
- return False
- if self is w_other:
- return True
- if self.user_overridden_class or w_other.user_overridden_class:
- return False
- return space.unicode_w(self) is space.unicode_w(w_other)
+ def unwrap(w_self, space):
+ return w_self.unicode_w(space)
- def immutable_unique_id(self, space):
- if self.user_overridden_class:
- return None
- return space.wrap(compute_unique_id(space.unicode_w(self)))
+ def _isalnum(self, ch):
+ return unicodedb.isalnum(ord(ch))
+
+ def _isalpha(self, ch):
+ return unicodedb.isalpha(ord(ch))
+
+ def _isdigit(self, ch):
+ return unicodedb.isdigit(ord(ch))
+
+ def _isdecimal(self, ch):
+ return unicodedb.isdecimal(ord(ch))
+
+ def _islower(self, ch):
+ return unicodedb.islower(ord(ch))
+
+ def _isspace(self, ch):
+ return unicodedb.isspace(ord(ch))
+
+ def _isupper(self, ch):
+ return unicodedb.isupper(ord(ch))
+
+ def _lower(self, ch):
+ return unichr(unicodedb.tolower(ord(ch)))
+
+ def _upper(self, ch):
+ return unichr(unicodedb.toupper(ord(ch)))
+
+ def _swapcase(self, ch):
+ num = ord(ch)
+ if unicodedb.islower(num):
+ return unichr(unicodedb.toupper(num))
+ elif unicodedb.isupper(num):
+ return unichr(unicodedb.tolower(num))
+ else:
+ return ch
class W_UnicodeObject(W_AbstractUnicodeObject):
@@ -46,24 +80,26 @@
assert isinstance(unistr, unicode)
w_self._value = unistr
- def __repr__(w_self):
- """ representation for debugging purposes """
- return "%s(%r)" % (w_self.__class__.__name__, w_self._value)
+ def builder(w_self, space, size=0):
+ return UnicodeBuilder(size)
- def unwrap(w_self, space):
- # for testing
+ def construct(w_self, space, data):
+ return W_UnicodeObject(data)
+
+ def raw_value(w_self):
return w_self._value
+ def str_w(self, space):
+ return space.str_w(space.str(self))
+
+ def unicode_w(self, space):
+ return self._value
+
def create_if_subclassed(w_self):
if type(w_self) is W_UnicodeObject:
return w_self
return W_UnicodeObject(w_self._value)
- def str_w(self, space):
- return space.str_w(space.str(self))
-
- def unicode_w(self, space):
- return self._value
W_UnicodeObject.EMPTY = W_UnicodeObject(u'')
@@ -75,6 +111,7 @@
raise operationerrfmt(space.w_TypeError,
"expected unicode, got '%s'",
space.type(w_unistr).getname(space))
+ # XXX remove direct use of _value
unistr = w_unistr._value
result = ['\0'] * len(unistr)
digits = [ '0', '1', '2', '3', '4',
@@ -302,63 +339,32 @@
def mul__ANY_Unicode(space, w_times, w_uni):
return mul__Unicode_ANY(space, w_uni, w_times)
-def _isspace(uchar):
- return unicodedb.isspace(ord(uchar))
+def unicode_isspace__Unicode(space, w_self):
+ return w_self.isspace(space)
-def make_generic(funcname):
- def func(space, w_self):
- v = w_self._value
- if len(v) == 0:
- return space.w_False
- for idx in range(len(v)):
- if not getattr(unicodedb, funcname)(ord(v[idx])):
- return space.w_False
- return space.w_True
- return func_with_new_name(func, "unicode_%s__Unicode" % (funcname, ))
+def unicode_isalpha__Unicode(space, w_self):
+ return w_self.isalpha(space)
-unicode_isspace__Unicode = make_generic("isspace")
-unicode_isalpha__Unicode = make_generic("isalpha")
-unicode_isalnum__Unicode = make_generic("isalnum")
-unicode_isdecimal__Unicode = make_generic("isdecimal")
-unicode_isdigit__Unicode = make_generic("isdigit")
-unicode_isnumeric__Unicode = make_generic("isnumeric")
+def unicode_isalnum__Unicode(space, w_self):
+ return w_self.isalnum(space)
-def unicode_islower__Unicode(space, w_unicode):
- cased = False
- for uchar in w_unicode._value:
- if (unicodedb.isupper(ord(uchar)) or
- unicodedb.istitle(ord(uchar))):
- return space.w_False
- if not cased and unicodedb.islower(ord(uchar)):
- cased = True
- return space.newbool(cased)
+def unicode_isdecimal__Unicode(space, w_self):
+ return w_self.isdecimal(space)
-def unicode_isupper__Unicode(space, w_unicode):
- cased = False
- for uchar in w_unicode._value:
- if (unicodedb.islower(ord(uchar)) or
- unicodedb.istitle(ord(uchar))):
- return space.w_False
- if not cased and unicodedb.isupper(ord(uchar)):
- cased = True
- return space.newbool(cased)
+def unicode_isdigit__Unicode(space, w_self):
+ return w_self.isdigit(space)
-def unicode_istitle__Unicode(space, w_unicode):
- cased = False
- previous_is_cased = False
- for uchar in w_unicode._value:
- if (unicodedb.isupper(ord(uchar)) or
- unicodedb.istitle(ord(uchar))):
- if previous_is_cased:
- return space.w_False
- previous_is_cased = cased = True
- elif unicodedb.islower(ord(uchar)):
- if not previous_is_cased:
- return space.w_False
- previous_is_cased = cased = True
- else:
- previous_is_cased = False
- return space.newbool(cased)
+def unicode_isnumeric__Unicode(space, w_self):
+ return w_self.isnumeric(space)
+
+def unicode_islower__Unicode(space, w_self):
+ return w_self.islower(space)
+
+def unicode_isupper__Unicode(space, w_self):
+ return w_self.isupper(space)
+
+def unicode_istitle__Unicode(space, w_self):
+ return w_self.istitle(space)
def _strip(space, w_self, w_chars, left, right):
"internal function called by str_xstrip methods"
@@ -388,11 +394,11 @@
rpos = len(u_self)
if left:
- while lpos < rpos and _isspace(u_self[lpos]):
+ while lpos < rpos and w_self._isspace(u_self[lpos]):
lpos += 1
if right:
- while rpos > lpos and _isspace(u_self[rpos - 1]):
+ while rpos > lpos and w_self._isspace(u_self[rpos - 1]):
rpos -= 1
assert rpos >= 0
@@ -458,40 +464,13 @@
return W_UnicodeObject(builder.build())
def unicode_lower__Unicode(space, w_self):
- input = w_self._value
- builder = UnicodeBuilder(len(input))
- for i in range(len(input)):
- builder.append(unichr(unicodedb.tolower(ord(input[i]))))
- return W_UnicodeObject(builder.build())
+ return w_self.lower(space)
def unicode_upper__Unicode(space, w_self):
- input = w_self._value
- builder = UnicodeBuilder(len(input))
- for i in range(len(input)):
- builder.append(unichr(unicodedb.toupper(ord(input[i]))))
- return W_UnicodeObject(builder.build())
+ return w_self.upper(space)
def unicode_swapcase__Unicode(space, w_self):
- input = w_self._value
- builder = UnicodeBuilder(len(input))
- for i in range(len(input)):
- unichar = ord(input[i])
- if unicodedb.islower(unichar):
- builder.append(unichr(unicodedb.toupper(unichar)))
- elif unicodedb.isupper(unichar):
- builder.append(unichr(unicodedb.tolower(unichar)))
- else:
- builder.append(input[i])
- return W_UnicodeObject(builder.build())
-
-def _normalize_index(length, index):
- if index < 0:
- index += length
- if index < 0:
- index = 0
- elif index > length:
- index = length
- return index
+ return w_self.swapcase(space)
@specialize.arg(4)
def _convert_idx_params(space, w_self, w_start, w_end, upper_bound=False):
@@ -666,7 +645,7 @@
while True:
# find the beginning of the next word
while i < length:
- if not _isspace(value[i]):
+ if not w_self._isspace(value[i]):
break # found
i += 1
else:
@@ -677,7 +656,7 @@
j = length # take all the rest of the string
else:
j = i + 1
- while j < length and not _isspace(value[j]):
+ while j < length and not w_self._isspace(value[j]):
j += 1
maxsplit -= 1 # NB. if it's already < 0, it stays < 0
@@ -709,7 +688,7 @@
while True:
# starting from the end, find the end of the next word
while i >= 0:
- if not _isspace(value[i]):
+ if not w_self._isspace(value[i]):
break # found
i -= 1
else:
@@ -721,7 +700,7 @@
j = -1 # take all the rest of the string
else:
j = i - 1
- while j >= 0 and not _isspace(value[j]):
+ while j >= 0 and not w_self._isspace(value[j]):
j -= 1
maxsplit -= 1 # NB. if it's already < 0, it stays < 0
diff --git a/pypy/rlib/objectmodel.py b/pypy/rlib/objectmodel.py
--- a/pypy/rlib/objectmodel.py
+++ b/pypy/rlib/objectmodel.py
@@ -233,20 +233,22 @@
# ____________________________________________________________
-def newlist(sizehint=0):
+def newlist_hint(sizehint=0):
""" Create a new list, but pass a hint how big the size should be
preallocated
"""
return []
class Entry(ExtRegistryEntry):
- _about_ = newlist
+ _about_ = newlist_hint
def compute_result_annotation(self, s_sizehint):
from pypy.annotation.model import SomeInteger
assert isinstance(s_sizehint, SomeInteger)
- return self.bookkeeper.newlist()
+ s_l = self.bookkeeper.newlist()
+ s_l.listdef.listitem.resize()
+ return s_l
def specialize_call(self, orig_hop, i_sizehint=None):
from pypy.rpython.rlist import rtype_newlist
diff --git a/pypy/rlib/test/test_objectmodel.py b/pypy/rlib/test/test_objectmodel.py
--- a/pypy/rlib/test/test_objectmodel.py
+++ b/pypy/rlib/test/test_objectmodel.py
@@ -442,7 +442,7 @@
def test_newlist():
from pypy.annotation.model import SomeInteger
def f(z):
- x = newlist(sizehint=38)
+ x = newlist_hint(sizehint=38)
if z < 0:
x.append(1)
return len(x)
@@ -456,7 +456,7 @@
def test_newlist_nonconst():
from pypy.annotation.model import SomeInteger
def f(z):
- x = newlist(sizehint=z)
+ x = newlist_hint(sizehint=z)
return len(x)
graph = getgraph(f, [SomeInteger()])
diff --git a/pypy/rpython/lltypesystem/rlist.py b/pypy/rpython/lltypesystem/rlist.py
--- a/pypy/rpython/lltypesystem/rlist.py
+++ b/pypy/rpython/lltypesystem/rlist.py
@@ -60,7 +60,6 @@
ITEMARRAY = GcArray(ITEM,
adtmeths = ADTIFixedList({
"ll_newlist": ll_fixed_newlist,
- "ll_newlist_hint": ll_fixed_newlist,
"ll_newemptylist": ll_fixed_newemptylist,
"ll_length": ll_fixed_length,
"ll_items": ll_fixed_items,
@@ -271,7 +270,7 @@
l.items = malloc(LIST.items.TO, lengthhint)
return l
ll_newlist_hint = typeMethod(ll_newlist_hint)
-ll_newlist_hint.oopspec = 'newlist(lengthhint)'
+ll_newlist_hint.oopspec = 'newlist_hint(lengthhint)'
# should empty lists start with no allocated memory, or with a preallocated
# minimal number of entries? XXX compare memory usage versus speed, and
@@ -315,16 +314,16 @@
# fixed size versions
+ at typeMethod
def ll_fixed_newlist(LIST, length):
ll_assert(length >= 0, "negative fixed list length")
l = malloc(LIST, length)
return l
-ll_fixed_newlist = typeMethod(ll_fixed_newlist)
ll_fixed_newlist.oopspec = 'newlist(length)'
+ at typeMethod
def ll_fixed_newemptylist(LIST):
return ll_fixed_newlist(LIST, 0)
-ll_fixed_newemptylist = typeMethod(ll_fixed_newemptylist)
def ll_fixed_length(l):
return len(l)
diff --git a/pypy/rpython/test/test_rlist.py b/pypy/rpython/test/test_rlist.py
--- a/pypy/rpython/test/test_rlist.py
+++ b/pypy/rpython/test/test_rlist.py
@@ -1362,13 +1362,12 @@
("y[*]" in immutable_fields)
def test_hints(self):
- from pypy.rlib.objectmodel import newlist
- from pypy.rpython.annlowlevel import hlstr
+ from pypy.rlib.objectmodel import newlist_hint
strings = ['abc', 'def']
def f(i):
z = strings[i]
- x = newlist(sizehint=13)
+ x = newlist_hint(sizehint=13)
x += z
return ''.join(x)
diff --git a/pypy/translator/c/src/asm_gcc_x86.h b/pypy/translator/c/src/asm_gcc_x86.h
--- a/pypy/translator/c/src/asm_gcc_x86.h
+++ b/pypy/translator/c/src/asm_gcc_x86.h
@@ -124,10 +124,12 @@
{
//Read the CPU features.
int features;
- asm("mov $1, %%eax\n"
+ asm("movl $1, %%eax\n"
+ "pushl %%ebx\n"
"cpuid\n"
- "mov %%edx, %0"
- : "=g"(features) : : "eax", "ebx", "edx", "ecx");
+ "popl %%ebx\n"
+ "movl %%edx, %0"
+ : "=g"(features) : : "eax", "edx", "ecx");
//Check bits 25 and 26, this indicates SSE2 support
if (((features & (1 << 25)) == 0) || ((features & (1 << 26)) == 0))
diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py
--- a/pypy/translator/c/test/test_genc.py
+++ b/pypy/translator/c/test/test_genc.py
@@ -16,6 +16,8 @@
def compile(fn, argtypes, view=False, gcpolicy="ref", backendopt=True,
annotatorpolicy=None):
+ if argtypes is not None and "__pypy__" in sys.builtin_module_names:
+ py.test.skip("requires building cpython extension modules")
t = Translation(fn, argtypes, gc=gcpolicy, backend="c",
policy=annotatorpolicy)
if not backendopt:
More information about the pypy-commit
mailing list