[pypy-commit] pypy py3k: merge default
pjenvey
noreply at buildbot.pypy.org
Sat Feb 16 01:22:54 CET 2013
Author: Philip Jenvey <pjenvey at underboss.org>
Branch: py3k
Changeset: r61291:6f8795612ffd
Date: 2013-02-15 16:20 -0800
http://bitbucket.org/pypy/pypy/changeset/6f8795612ffd/
Log: merge default
diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py
--- a/pypy/interpreter/miscutils.py
+++ b/pypy/interpreter/miscutils.py
@@ -17,8 +17,14 @@
def setvalue(self, value):
self._value = value
- def ismainthread(self):
+ def signals_enabled(self):
return True
+ def enable_signals(self):
+ pass
+
+ def disable_signals(self):
+ pass
+
def getallvalues(self):
return {0: self._value}
diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py
--- a/pypy/interpreter/test2/test_app_main.py
+++ b/pypy/interpreter/test2/test_app_main.py
@@ -225,11 +225,6 @@
These tests require pexpect (UNIX-only).
http://pexpect.sourceforge.net/
"""
- def setup_class(cls):
- # some tests need to be able to import test2, change the cwd
- goal_dir = os.path.abspath(os.path.join(os.path.realpath(os.path.dirname(__file__)), '..'))
- os.chdir(goal_dir)
-
def _spawn(self, *args, **kwds):
try:
import pexpect
@@ -484,13 +479,14 @@
child = self.spawn(['-c', 'import sys; print(sys.stdin.mode)'])
child.expect('r')
- def test_options_i_m(self):
+ def test_options_i_m(self, monkeypatch):
if sys.platform == "win32":
skip("close_fds is not supported on Windows platforms")
if not hasattr(runpy, '_run_module_as_main'):
skip("requires CPython >= 2.6")
p = os.path.join(os.path.realpath(os.path.dirname(__file__)), 'mymodule.py')
p = os.path.abspath(p)
+ monkeypatch.chdir(os.path.dirname(app_main))
child = self.spawn(['-i',
'-m', 'test2.mymodule',
'extra'])
@@ -590,12 +586,13 @@
child.sendline('Not at all. They could be carried.')
child.expect('A five ounce bird could not carry a one pound coconut.')
- def test_no_space_before_argument(self):
+ def test_no_space_before_argument(self, monkeypatch):
if not hasattr(runpy, '_run_module_as_main'):
skip("requires CPython >= 2.6")
child = self.spawn(['-cprint("hel" + "lo")'])
child.expect('hello')
+ monkeypatch.chdir(os.path.dirname(app_main))
child = self.spawn(['-mtest2.mymodule'])
child.expect('mymodule running')
@@ -696,11 +693,12 @@
'-c "import sys; print(sys.warnoptions)"')
assert "['ignore', 'default', 'once', 'error']" in data
- def test_option_m(self):
+ def test_option_m(self, monkeypatch):
if not hasattr(runpy, '_run_module_as_main'):
skip("requires CPython >= 2.6")
p = os.path.join(os.path.realpath(os.path.dirname(__file__)), 'mymodule.py')
p = os.path.abspath(p)
+ monkeypatch.chdir(os.path.dirname(app_main))
data = self.run('-m test2.mymodule extra')
assert 'mymodule running' in data
assert 'Name: __main__' in data
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
@@ -26,6 +26,16 @@
interpleveldefs[name] = "space.wrap(interp_time.%s)" % name
+class ThreadModule(MixedModule):
+ appleveldefs = {
+ 'signals_enabled': 'app_signal.signals_enabled',
+ }
+ interpleveldefs = {
+ '_signals_enter': 'interp_signal.signals_enter',
+ '_signals_exit': 'interp_signal.signals_exit',
+ }
+
+
class Module(MixedModule):
appleveldefs = {
}
@@ -54,6 +64,7 @@
submodules = {
"builders": BuildersModule,
"time": TimeModule,
+ "thread": ThreadModule,
}
def setup_after_space_initialization(self):
diff --git a/pypy/module/__pypy__/app_signal.py b/pypy/module/__pypy__/app_signal.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/__pypy__/app_signal.py
@@ -0,0 +1,14 @@
+import __pypy__.thread
+
+class SignalsEnabled(object):
+ '''A context manager to use in non-main threads:
+enables receiving signals in a "with" statement. More precisely, if a
+signal is received by the process, then the signal handler might be
+called either in the main thread (as usual) or within another thread
+that is within a "with signals_enabled:". This other thread should be
+ready to handle unexpected exceptions that the signal handler might
+raise --- notably KeyboardInterrupt.'''
+ __enter__ = __pypy__.thread._signals_enter
+ __exit__ = __pypy__.thread._signals_exit
+
+signals_enabled = SignalsEnabled()
diff --git a/pypy/module/__pypy__/interp_signal.py b/pypy/module/__pypy__/interp_signal.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/__pypy__/interp_signal.py
@@ -0,0 +1,6 @@
+
+def signals_enter(space):
+ space.threadlocals.enable_signals()
+
+def signals_exit(space, w_ignored1=None, w_ignored2=None, w_ignored3=None):
+ space.threadlocals.disable_signals()
diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/__pypy__/test/test_signal.py
@@ -0,0 +1,81 @@
+import sys
+
+
+class AppTestMinimal:
+ spaceconfig = dict(usemodules=['__pypy__'])
+
+ def test_signal(self):
+ from __pypy__ import thread
+ with thread.signals_enabled:
+ pass
+ # assert did not crash
+
+
+class AppTestThreadSignal:
+ spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal', 'time'])
+
+ def test_enable_signals(self):
+ import __pypy__, thread, signal, time
+
+ def subthread():
+ try:
+ with __pypy__.thread.signals_enabled:
+ thread.interrupt_main()
+ for i in range(10):
+ print 'x'
+ time.sleep(0.1)
+ except BaseException, e:
+ interrupted.append(e)
+ finally:
+ done.append(None)
+
+ # This is normally called by app_main.py
+ signal.signal(signal.SIGINT, signal.default_int_handler)
+
+ for i in range(10):
+ __pypy__.thread._signals_exit()
+ try:
+ done = []
+ interrupted = []
+ thread.start_new_thread(subthread, ())
+ for i in range(10):
+ if len(done): break
+ print '.'
+ time.sleep(0.1)
+ assert len(done) == 1
+ assert len(interrupted) == 1
+ assert 'KeyboardInterrupt' in interrupted[0].__class__.__name__
+ finally:
+ __pypy__.thread._signals_enter()
+
+
+class AppTestThreadSignalLock:
+ spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal'])
+
+ def setup_class(cls):
+ if (not cls.runappdirect or
+ '__pypy__' not in sys.builtin_module_names):
+ import py
+ py.test.skip("this is only a test for -A runs on top of pypy")
+
+ def test_enable_signals(self):
+ import __pypy__, thread, signal, time
+
+ interrupted = []
+ lock = thread.allocate_lock()
+ lock.acquire()
+
+ def subthread():
+ try:
+ time.sleep(0.25)
+ with __pypy__.thread.signals_enabled:
+ thread.interrupt_main()
+ except BaseException, e:
+ interrupted.append(e)
+ finally:
+ lock.release()
+
+ thread.start_new_thread(subthread, ())
+ lock.acquire()
+ assert len(interrupted) == 1
+ assert 'KeyboardInterrupt' in interrupted[0].__class__.__name__
diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -1404,7 +1404,6 @@
BInt = new_primitive_type("int")
BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, 20))
def cb(n):
- print n
if n & 1:
return cast(BEnum, n)
else:
diff --git a/pypy/module/gc/test/test_ztranslation.py b/pypy/module/gc/test/test_ztranslation.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/gc/test/test_ztranslation.py
@@ -0,0 +1,4 @@
+from pypy.objspace.fake.checkmodule import checkmodule
+
+def test_checkmodule():
+ checkmodule('gc')
diff --git a/pypy/module/micronumpy/test/test_module.py b/pypy/module/micronumpy/test/test_module.py
--- a/pypy/module/micronumpy/test/test_module.py
+++ b/pypy/module/micronumpy/test/test_module.py
@@ -13,11 +13,13 @@
assert sum(array(range(10))) == 45
def test_min(self):
- from _numpypy import array, min
+ from _numpypy import array, min, zeros
assert min(range(10)) == 0
assert min(array(range(10))) == 0
+ assert list(min(zeros((0, 2)), axis=1)) == []
def test_max(self):
- from _numpypy import array, max
+ from _numpypy import array, max, zeros
assert max(range(10)) == 9
assert max(array(range(10))) == 9
+ assert list(max(zeros((0, 2)), axis=1)) == []
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
@@ -1662,13 +1662,13 @@
b = array([0, 1, 2], dtype=complex).astype(bool)
assert (b == [False, True, True]).all()
assert b.dtype == 'bool'
-
+
a = arange(6, dtype='f4').reshape(2,3)
b = a.astype('i4')
a = array('x').astype('S3').dtype
assert a.itemsize == 3
-
+
def test_base(self):
from _numpypy import array
assert array(1).base is None
@@ -1679,6 +1679,11 @@
def test_byteswap(self):
from _numpypy import array
+
+ s1 = array(1.).byteswap().tostring()
+ s2 = array([1.]).byteswap().tostring()
+ assert s1 == s2
+
a = array([1, 256 + 2, 3], dtype='i2')
assert (a.byteswap() == [0x0100, 0x0201, 0x0300]).all()
assert (a == [1, 256 + 2, 3]).all()
@@ -1686,39 +1691,40 @@
assert (a == [0x0100, 0x0201, 0x0300]).all()
a = array([1, -1, 1e300], dtype=float)
- s1 = map(ord,a.tostring())
+ s1 = map(ord, a.tostring())
s2 = map(ord, a.byteswap().tostring())
- assert s1[7::-1] == s2[:8]
- assert s1[15:7:-1] == s2[8:16]
- assert s1[:15:-1] == s2[16:]
+ assert a.dtype.itemsize == 8
+ for i in range(a.size):
+ i1 = i * a.dtype.itemsize
+ i2 = (i+1) * a.dtype.itemsize
+ assert list(reversed(s1[i1:i2])) == s2[i1:i2]
a = array([1+1e30j, -1, 1e10], dtype=complex)
- s1 = map(ord,a.tostring())
+ s1 = map(ord, a.tostring())
s2 = map(ord, a.byteswap().tostring())
- assert s1[7::-1] == s2[:8]
- assert s1[15:7:-1] == s2[8:16]
- assert s1[23:15:-1] == s2[16:24]
- assert s1[31:23:-1] == s2[24:32]
- assert s1[39:31:-1] == s2[32:40]
- assert s1[:39:-1] == s2[40:]
+ assert a.dtype.itemsize == 16
+ for i in range(a.size*2):
+ i1 = i * a.dtype.itemsize/2
+ i2 = (i+1) * a.dtype.itemsize/2
+ assert list(reversed(s1[i1:i2])) == s2[i1:i2]
a = array([3.14, -1.5, 10000], dtype='float16')
- s1 = map(ord,a.tostring())
+ s1 = map(ord, a.tostring())
s2 = map(ord, a.byteswap().tostring())
- s3 = [s1[1], s1[0],s1[3], s1[2], s1[5], s1[4]]
- assert s3 == s2
+ assert a.dtype.itemsize == 2
+ for i in range(a.size):
+ i1 = i * a.dtype.itemsize
+ i2 = (i+1) * a.dtype.itemsize
+ assert list(reversed(s1[i1:i2])) == s2[i1:i2]
a = array([1, -1, 10000], dtype='longfloat')
- s1 = map(ord,a.tostring())
- s2 = map(ord, a.byteswap().tostring())
- n = a.dtype.itemsize
- assert s1[n-1] == s2[0]
-
- a = array(0., dtype='longfloat')
s1 = map(ord, a.tostring())
s2 = map(ord, a.byteswap().tostring())
- n = a.dtype.itemsize
- assert s1[n-1] == s2[0]
+ assert a.dtype.itemsize >= 8
+ for i in range(a.size):
+ i1 = i * a.dtype.itemsize
+ i2 = (i+1) * a.dtype.itemsize
+ assert list(reversed(s1[i1:i2])) == s2[i1:i2]
def test_clip(self):
from _numpypy import array
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
@@ -14,8 +14,8 @@
from rpython.rtyper.lltypesystem import lltype, rffi
from rpython.rlib.rstruct.runpack import runpack
from rpython.rlib.rstruct.nativefmttable import native_is_bigendian
-from rpython.rlib.rstruct.ieee import (float_pack, float_unpack, pack_float80,
- unpack_float, unpack_float128)
+from rpython.rlib.rstruct.ieee import (float_pack, float_unpack, unpack_float,
+ pack_float80, unpack_float80)
from rpython.tool.sourcetools import func_with_new_name
from rpython.rlib import jit
from rpython.rlib.rstring import StringBuilder
@@ -958,7 +958,6 @@
swapped_value = byteswap(rffi.cast(self.T, value))
raw_storage_setitem(storage, i + offset, swapped_value)
-
class Float32(BaseType, Float):
_attrs_ = ()
@@ -1505,7 +1504,6 @@
BoxType = interp_boxes.W_Complex64Box
ComponentBoxType = interp_boxes.W_Float32Box
-
NonNativeComplex64 = Complex64
class Complex128(ComplexFloating, BaseType):
@@ -1515,7 +1513,6 @@
BoxType = interp_boxes.W_Complex128Box
ComponentBoxType = interp_boxes.W_Float64Box
-
NonNativeComplex128 = Complex128
if interp_boxes.long_double_size == 12:
@@ -1528,17 +1525,16 @@
def runpack_str(self, s):
assert len(s) == 12
- fval = unpack_float128(s, native_is_bigendian)
+ fval = unpack_float80(s, native_is_bigendian)
return self.box(fval)
def byteswap(self, w_v):
value = self.unbox(w_v)
result = StringBuilder(12)
- pack_float80(result, value, 12, not native_is_bigendian)
- return self.box(unpack_float128(result.build(), native_is_bigendian))
+ pack_float80(result, value, not native_is_bigendian)
+ return self.box(unpack_float80(result.build(), native_is_bigendian))
- class NonNativeFloat96(Float96):
- pass
+ NonNativeFloat96 = Float96
class Complex192(ComplexFloating, BaseType):
_attrs_ = ()
@@ -1549,7 +1545,6 @@
NonNativeComplex192 = Complex192
-
elif interp_boxes.long_double_size == 16:
class Float128(BaseType, Float):
_attrs_ = ()
@@ -1560,14 +1555,14 @@
def runpack_str(self, s):
assert len(s) == 16
- fval = unpack_float128(s, native_is_bigendian)
+ fval = unpack_float80(s, native_is_bigendian)
return self.box(fval)
def byteswap(self, w_v):
value = self.unbox(w_v)
result = StringBuilder(16)
- pack_float80(result, value, 16, not native_is_bigendian)
- return self.box(unpack_float128(result.build(), native_is_bigendian))
+ pack_float80(result, value, not native_is_bigendian)
+ return self.box(unpack_float80(result.build(), native_is_bigendian))
NonNativeFloat128 = Float128
@@ -1578,7 +1573,6 @@
BoxType = interp_boxes.W_Complex256Box
ComponentBoxType = interp_boxes.W_Float128Box
-
NonNativeComplex256 = Complex256
class BaseStringType(object):
diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py
--- a/pypy/module/signal/interp_signal.py
+++ b/pypy/module/signal/interp_signal.py
@@ -61,16 +61,16 @@
"NOT_RPYTHON"
AsyncAction.__init__(self, space)
self.pending_signal = -1
- self.fire_in_main_thread = False
+ self.fire_in_another_thread = False
if self.space.config.objspace.usemodules.thread:
from pypy.module.thread import gil
gil.after_thread_switch = self._after_thread_switch
@rgc.no_collect
def _after_thread_switch(self):
- if self.fire_in_main_thread:
- if self.space.threadlocals.ismainthread():
- self.fire_in_main_thread = False
+ if self.fire_in_another_thread:
+ if self.space.threadlocals.signals_enabled():
+ self.fire_in_another_thread = False
SignalActionFlag.rearm_ticker()
# this occurs when we just switched to the main thread
# and there is a signal pending: we force the ticker to
@@ -82,11 +82,7 @@
n = self.pending_signal
if n < 0: n = pypysig_poll()
while n >= 0:
- if self.space.config.objspace.usemodules.thread:
- in_main = self.space.threadlocals.ismainthread()
- else:
- in_main = True
- if in_main:
+ if self.space.threadlocals.signals_enabled():
# If we are in the main thread, report the signal now,
# and poll more
self.pending_signal = -1
@@ -97,7 +93,7 @@
# Otherwise, arrange for perform() to be called again
# after we switch to the main thread.
self.pending_signal = n
- self.fire_in_main_thread = True
+ self.fire_in_another_thread = True
break
def set_interrupt(self):
@@ -105,9 +101,9 @@
if not we_are_translated():
self.pending_signal = cpy_signal.SIGINT
# ^^^ may override another signal, but it's just for testing
+ self.fire_in_another_thread = True
else:
pypysig_pushback(cpy_signal.SIGINT)
- self.fire_in_main_thread = True
# ____________________________________________________________
@@ -204,9 +200,10 @@
if WIN32 and signum not in signal_values:
raise OperationError(space.w_ValueError,
space.wrap("invalid signal value"))
- if not space.threadlocals.ismainthread():
+ if not space.threadlocals.signals_enabled():
raise OperationError(space.w_ValueError,
- space.wrap("signal only works in main thread"))
+ space.wrap("signal only works in main thread "
+ "or with __pypy__.thread.enable_signals()"))
check_signum_in_range(space, signum)
if space.eq_w(w_handler, space.wrap(SIG_DFL)):
@@ -235,10 +232,11 @@
The fd must be non-blocking.
"""
- if not space.threadlocals.ismainthread():
+ if not space.threadlocals.signals_enabled():
raise OperationError(
space.w_ValueError,
- space.wrap("set_wakeup_fd only works in main thread"))
+ space.wrap("set_wakeup_fd only works in main thread "
+ "or with __pypy__.thread.enable_signals()"))
old_fd = pypysig_set_wakeup_fd(fd)
return space.wrap(intmask(old_fd))
diff --git a/pypy/module/sys/initpath.py b/pypy/module/sys/initpath.py
--- a/pypy/module/sys/initpath.py
+++ b/pypy/module/sys/initpath.py
@@ -67,6 +67,8 @@
stdlib.
If it cannot be found, return (None, None).
"""
+ if executable == '':
+ return None, None
search = executable
while True:
dirname = resolvedirof(search)
diff --git a/pypy/module/sys/test/test_initpath.py b/pypy/module/sys/test/test_initpath.py
--- a/pypy/module/sys/test/test_initpath.py
+++ b/pypy/module/sys/test/test_initpath.py
@@ -10,12 +10,15 @@
b = prefix.join('lib-python', dirname).ensure(dir=1)
return a, b
-def test_find_stdlib(tmpdir):
+def test_find_stdlib(tmpdir, monkeypatch):
bin_dir = tmpdir.join('bin').ensure(dir=True)
pypy = bin_dir.join('pypy').ensure(file=True)
build_hierarchy(tmpdir)
path, prefix = find_stdlib(None, str(pypy))
assert prefix == tmpdir
+ # shouldn't find stdlib if executable == '' even if parent dir has a stdlib
+ monkeypatch.chdir(tmpdir.join('bin'))
+ assert find_stdlib(None, '') == (None, None)
@py.test.mark.skipif('not hasattr(os, "symlink")')
def test_find_stdlib_follow_symlink(tmpdir):
@@ -84,6 +87,7 @@
assert find_executable('pypy') == a.join('pypy.exe')
def test_resolvedirof(tmpdir):
+ assert resolvedirof('') == os.path.abspath(os.path.join(os.getcwd(), '..'))
foo = tmpdir.join('foo').ensure(dir=True)
bar = tmpdir.join('bar').ensure(dir=True)
myfile = foo.join('myfile').ensure(file=True)
diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py b/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py
--- a/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py
+++ b/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py
@@ -132,7 +132,7 @@
assert reshape(a, (1, -1)).shape == (1, 105)
assert reshape(a, (1, 1, -1)).shape == (1, 1, 105)
assert reshape(a, (-1, 1, 1)).shape == (105, 1, 1)
-
+
def test_transpose(self):
from numpypy import arange, array, transpose, ones
x = arange(4).reshape((2,2))
@@ -141,7 +141,7 @@
raises(NotImplementedError, "transpose(x, axes=(1, 0, 2))")
# x = ones((1, 2, 3))
# assert transpose(x, (1, 0, 2)).shape == (2, 1, 3)
-
+
def test_fromnumeric(self):
from numpypy import array, swapaxes
x = array([[1,2,3]])
diff --git a/pypy/module/test_lib_pypy/numpypy/test_numpy.py b/pypy/module/test_lib_pypy/numpypy/test_numpy.py
--- a/pypy/module/test_lib_pypy/numpypy/test_numpy.py
+++ b/pypy/module/test_lib_pypy/numpypy/test_numpy.py
@@ -12,3 +12,11 @@
pass
import numpypy
import numpy # works after 'numpypy' has been imported
+
+ def test_min_max_after_import(self):
+ from numpypy import *
+ assert min(1, 100) == 1
+ assert min(100, 1) == 1
+
+ assert max(1, 100) == 100
+ assert max(100, 1) == 100
diff --git a/pypy/module/thread/gil.py b/pypy/module/thread/gil.py
--- a/pypy/module/thread/gil.py
+++ b/pypy/module/thread/gil.py
@@ -7,7 +7,7 @@
# all but one will be blocked. The other threads get a chance to run
# from time to time, using the periodic action GILReleaseAction.
-from rpython.rlib import rthread as thread
+from rpython.rlib import rthread
from pypy.module.thread.error import wrap_thread_error
from pypy.interpreter.executioncontext import PeriodicAsyncAction
from pypy.module.thread.threadlocals import OSThreadLocals
@@ -25,7 +25,7 @@
use_bytecode_counter=True)
def _initialize_gil(self, space):
- if not thread.gil_allocate():
+ if not rthread.gil_allocate():
raise wrap_thread_error(space, "can't allocate GIL")
def setup_threads(self, space):
@@ -72,15 +72,15 @@
# this function must not raise, in such a way that the exception
# transformer knows that it cannot raise!
e = get_errno()
- thread.gil_release()
+ rthread.gil_release()
set_errno(e)
before_external_call._gctransformer_hint_cannot_collect_ = True
before_external_call._dont_reach_me_in_del_ = True
def after_external_call():
e = get_errno()
- thread.gil_acquire()
- thread.gc_thread_run()
+ rthread.gil_acquire()
+ rthread.gc_thread_run()
after_thread_switch()
set_errno(e)
after_external_call._gctransformer_hint_cannot_collect_ = True
@@ -97,8 +97,8 @@
# explicitly release the gil, in a way that tries to give more
# priority to other threads (as opposed to continuing to run in
# the same thread).
- if thread.gil_yield_thread():
- thread.gc_thread_run()
+ if rthread.gil_yield_thread():
+ rthread.gc_thread_run()
after_thread_switch()
do_yield_thread._gctransformer_hint_close_stack_ = True
do_yield_thread._dont_reach_me_in_del_ = True
diff --git a/pypy/module/thread/os_lock.py b/pypy/module/thread/os_lock.py
--- a/pypy/module/thread/os_lock.py
+++ b/pypy/module/thread/os_lock.py
@@ -2,7 +2,7 @@
Python locks, based on true threading locks provided by the OS.
"""
-from rpython.rlib import rthread as thread
+from rpython.rlib import rthread
from pypy.module.thread.error import wrap_thread_error
from pypy.interpreter.baseobjspace import Wrappable
from pypy.interpreter.gateway import interp2app, unwrap_spec
@@ -27,7 +27,7 @@
## except:
## pass
## tb = ' '.join(tb)
-## msg = '| %6d | %d %s | %s\n' % (thread.get_ident(), n, msg, tb)
+## msg = '| %6d | %d %s | %s\n' % (rthread.get_ident(), n, msg, tb)
## sys.stderr.write(msg)
@@ -57,8 +57,8 @@
def __init__(self, space):
self.space = space
try:
- self.lock = thread.allocate_lock()
- except thread.error:
+ self.lock = rthread.allocate_lock()
+ except rthread.error:
raise wrap_thread_error(space, "out of resources")
@unwrap_spec(blocking=int, timeout=float)
@@ -81,7 +81,7 @@
but it needn't be locked by the same thread that unlocks it."""
try:
self.lock.release()
- except thread.error:
+ except rthread.error:
raise wrap_thread_error(space, "release unlocked lock")
def descr_lock_locked(self, space):
diff --git a/pypy/module/thread/os_thread.py b/pypy/module/thread/os_thread.py
--- a/pypy/module/thread/os_thread.py
+++ b/pypy/module/thread/os_thread.py
@@ -3,7 +3,7 @@
"""
import os
-from rpython.rlib import rthread as thread
+from rpython.rlib import rthread
from pypy.module.thread.error import wrap_thread_error
from pypy.interpreter.error import OperationError, operationerrfmt
from pypy.interpreter.gateway import unwrap_spec, Arguments
@@ -65,8 +65,8 @@
def setup(space):
if bootstrapper.lock is None:
try:
- bootstrapper.lock = thread.allocate_lock()
- except thread.error:
+ bootstrapper.lock = rthread.allocate_lock()
+ except rthread.error:
raise wrap_thread_error(space, "can't allocate bootstrap lock")
@staticmethod
@@ -83,7 +83,7 @@
# Note that when this runs, we already hold the GIL. This is ensured
# by rffi's callback mecanism: we are a callback for the
# c_thread_start() external function.
- thread.gc_thread_start()
+ rthread.gc_thread_start()
space = bootstrapper.space
w_callable = bootstrapper.w_callable
args = bootstrapper.args
@@ -103,7 +103,7 @@
except OSError:
pass
bootstrapper.nbthreads -= 1
- thread.gc_thread_die()
+ rthread.gc_thread_die()
bootstrap = staticmethod(bootstrap)
def acquire(space, w_callable, args):
@@ -130,7 +130,7 @@
space.call_args(w_callable, args)
except OperationError, e:
if not e.match(space, space.w_SystemExit):
- ident = thread.get_ident()
+ ident = rthread.get_ident()
where = 'thread %d started by ' % ident
e.write_unraisable(space, where, w_callable)
e.clear(space)
@@ -150,7 +150,7 @@
"Called in the child process after a fork()"
space.threadlocals.reinit_threads(space)
bootstrapper.reinit()
- thread.thread_after_fork()
+ rthread.thread_after_fork()
# Clean the threading module after a fork()
w_modules = space.sys.get('modules')
@@ -181,12 +181,12 @@
bootstrapper.acquire(space, w_callable, args)
try:
try:
- thread.gc_thread_prepare() # (this has no effect any more)
- ident = thread.start_new_thread(bootstrapper.bootstrap, ())
+ rthread.gc_thread_prepare() # (this has no effect any more)
+ ident = rthread.start_new_thread(bootstrapper.bootstrap, ())
except Exception, e:
bootstrapper.release() # normally called by the new thread
raise
- except thread.error:
+ except rthread.error:
raise wrap_thread_error(space, "can't start new thread")
return space.wrap(ident)
@@ -199,7 +199,7 @@
allocated consecutive numbers starting at 1, this behavior should not
be relied upon, and the number should be seen purely as a magic cookie.
A thread's identity may be reused for another thread after it exits."""
- ident = thread.get_ident()
+ ident = rthread.get_ident()
return space.wrap(ident)
@unwrap_spec(size=int)
@@ -225,8 +225,8 @@
if size < 0:
raise OperationError(space.w_ValueError,
space.wrap("size must be 0 or a positive value"))
- old_size = thread.get_stacksize()
- error = thread.set_stacksize(size)
+ old_size = rthread.get_stacksize()
+ error = rthread.set_stacksize(size)
if error == -1:
raise operationerrfmt(space.w_ValueError,
"size not valid: %d bytes", size)
diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py
--- a/pypy/module/thread/threadlocals.py
+++ b/pypy/module/thread/threadlocals.py
@@ -1,4 +1,4 @@
-from rpython.rlib import rthread as thread
+from rpython.rlib import rthread
class OSThreadLocals:
@@ -9,16 +9,17 @@
def __init__(self):
self._valuedict = {} # {thread_ident: ExecutionContext()}
+ self._signalsenabled = {} # {thread_ident: number-of-times}
self._cleanup_()
def _cleanup_(self):
self._valuedict.clear()
- self._mainthreadident = 0
+ self._signalsenabled.clear()
self._mostrecentkey = 0 # fast minicaching for the common case
self._mostrecentvalue = None # fast minicaching for the common case
def getvalue(self):
- ident = thread.get_ident()
+ ident = rthread.get_ident()
if ident == self._mostrecentkey:
result = self._mostrecentvalue
else:
@@ -30,10 +31,10 @@
return result
def setvalue(self, value):
- ident = thread.get_ident()
+ ident = rthread.get_ident()
if value is not None:
if len(self._valuedict) == 0:
- self._mainthreadident = ident
+ self._signalsenabled[ident] = 1 # the main thread is enabled
self._valuedict[ident] = value
else:
try:
@@ -44,8 +45,24 @@
self._mostrecentkey = ident
self._mostrecentvalue = value
- def ismainthread(self):
- return thread.get_ident() == self._mainthreadident
+ def signals_enabled(self):
+ return rthread.get_ident() in self._signalsenabled
+
+ def enable_signals(self):
+ ident = rthread.get_ident()
+ old = self._signalsenabled.get(ident, 0)
+ self._signalsenabled[ident] = old + 1
+
+ def disable_signals(self):
+ ident = rthread.get_ident()
+ try:
+ new = self._signalsenabled[ident] - 1
+ except KeyError:
+ return
+ if new > 0:
+ self._signalsenabled[ident] = new
+ else:
+ del self._signalsenabled[ident]
def getallvalues(self):
return self._valuedict
@@ -60,4 +77,13 @@
def reinit_threads(self, space):
"Called in the child process after a fork()"
- self._mainthreadident = thread.get_ident()
+ # clear the _signalsenabled dictionary for all other threads
+ # (which are now dead); and for the current thread, force an
+ # enable_signals() if necessary. That's a hack but I cannot
+ # figure out a non-hackish way to handle thread+signal+fork :-(
+ ident = rthread.get_ident()
+ old = self._signalsenabled.get(ident, 0)
+ self._signalsenabled.clear()
+ if old == 0:
+ old = 1
+ self._signalsenabled[ident] = old
diff --git a/rpython/jit/codewriter/assembler.py b/rpython/jit/codewriter/assembler.py
--- a/rpython/jit/codewriter/assembler.py
+++ b/rpython/jit/codewriter/assembler.py
@@ -107,7 +107,9 @@
key = (kind, Constant(value))
if key not in self.constants_dict:
constants.append(value)
- self.constants_dict[key] = 256 - len(constants)
+ val = 256 - len(constants)
+ assert val >= 0, "too many constants"
+ self.constants_dict[key] = val
# emit the constant normally, as one byte that is an index in the
# list of constants
self.code.append(chr(self.constants_dict[key]))
diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py
--- a/rpython/rlib/jit.py
+++ b/rpython/rlib/jit.py
@@ -476,7 +476,7 @@
get_jitcell_at=None, set_jitcell_at=None,
get_printable_location=None, confirm_enter_jit=None,
can_never_inline=None, should_unroll_one_iteration=None,
- name='jitdriver'):
+ name='jitdriver', check_untranslated=True):
if greens is not None:
self.greens = greens
self.name = name
@@ -511,6 +511,7 @@
self.confirm_enter_jit = confirm_enter_jit
self.can_never_inline = can_never_inline
self.should_unroll_one_iteration = should_unroll_one_iteration
+ self.check_untranslated = check_untranslated
def _freeze_(self):
return True
@@ -565,13 +566,15 @@
def jit_merge_point(_self, **livevars):
# special-cased by ExtRegistryEntry
- _self._check_arguments(livevars)
+ if _self.check_untranslated:
+ _self._check_arguments(livevars)
def can_enter_jit(_self, **livevars):
if _self.autoreds:
raise TypeError, "Cannot call can_enter_jit on a driver with reds='auto'"
# special-cased by ExtRegistryEntry
- _self._check_arguments(livevars)
+ if _self.check_untranslated:
+ _self._check_arguments(livevars)
def loop_header(self):
# special-cased by ExtRegistryEntry
diff --git a/rpython/rlib/rarithmetic.py b/rpython/rlib/rarithmetic.py
--- a/rpython/rlib/rarithmetic.py
+++ b/rpython/rlib/rarithmetic.py
@@ -630,21 +630,16 @@
uint2singlefloat, singlefloat2uint
T = lltype.typeOf(arg)
- is_float = False
- is_single_float = False
if T == lltype.SingleFloat:
- T = rffi.UINT
- is_single_float = True
arg = singlefloat2uint(arg)
elif T == lltype.Float:
- is_float = True
- T = rffi.LONGLONG
arg = float2longlong(arg)
elif T == lltype.LongFloat:
assert False
else:
# we cannot do arithmetics on small ints
arg = widen(arg)
+
if rffi.sizeof(T) == 1:
res = arg
elif rffi.sizeof(T) == 2:
@@ -667,9 +662,9 @@
(f >> 24) | (g >> 40) | (h >> 56))
else:
assert False # unreachable code
- if is_single_float:
+
+ if T == lltype.SingleFloat:
return uint2singlefloat(rffi.cast(rffi.UINT, res))
- if is_float:
- res = rffi.cast(rffi.LONGLONG, res)
- return longlong2float(res)
+ if T == lltype.Float:
+ return longlong2float(rffi.cast(rffi.LONGLONG, res))
return rffi.cast(T, res)
diff --git a/rpython/rlib/rstruct/ieee.py b/rpython/rlib/rstruct/ieee.py
--- a/rpython/rlib/rstruct/ieee.py
+++ b/rpython/rlib/rstruct/ieee.py
@@ -235,12 +235,12 @@
result.append("".join(l))
@jit.unroll_safe
-def pack_float80(result, x, size, be):
+def pack_float80(result, x, be):
l = []
unsigned = float_pack80(x)
for i in range(8):
l.append(chr((unsigned[0] >> (i * 8)) & 0xFF))
- for i in range(size - 8):
+ for i in range(2):
l.append(chr((unsigned[1] >> (i * 8)) & 0xFF))
if be:
l.reverse()
@@ -253,12 +253,14 @@
unsigned |= r_ulonglong(c) << (i * 8)
return float_unpack(unsigned, len(s))
-def unpack_float128(s, be):
+def unpack_float80(s, be):
+ if len(s) != 10:
+ raise ValueError
QQ = [r_ulonglong(0), r_ulonglong(0)]
for i in range(8):
- c = ord(s[len(s) - 1 - i if be else i])
+ c = ord(s[9 - i if be else i])
QQ[0] |= r_ulonglong(c) << (i * 8)
- for i in range(8, len(s)):
- c = ord(s[len(s) - 1 - i if be else i])
+ for i in range(8, 10):
+ c = ord(s[9 - i if be else i])
QQ[1] |= r_ulonglong(c) << ((i - 8) * 8)
return float_unpack80(QQ)
diff --git a/rpython/rlib/rstruct/runpack.py b/rpython/rlib/rstruct/runpack.py
--- a/rpython/rlib/rstruct/runpack.py
+++ b/rpython/rlib/rstruct/runpack.py
@@ -46,7 +46,7 @@
def __init__(self, fmt):
self.formats = []
self.fmt = fmt
-
+
def operate(self, fmtdesc, repetitions):
if fmtdesc.needcount:
self.formats.append((fmtdesc, repetitions, None))
@@ -110,5 +110,3 @@
unpacker = create_unpacker(fmt)
return unpacker.unpack(input)
runpack._annspecialcase_ = 'specialize:arg(0)'
-
-
diff --git a/rpython/rlib/rstruct/test/test_ieee.py b/rpython/rlib/rstruct/test/test_ieee.py
--- a/rpython/rlib/rstruct/test/test_ieee.py
+++ b/rpython/rlib/rstruct/test/test_ieee.py
@@ -1,9 +1,12 @@
-import py, sys
+import py
+import sys
import random
import struct
-from rpython.rlib.rfloat import isnan
-from rpython.rlib.rstruct.ieee import float_pack, float_unpack, float_pack80, float_unpack80
+from rpython.rlib.rstruct import ieee
+from rpython.rlib.rfloat import isnan, NAN, INFINITY
+from rpython.translator.c.test.test_genc import compile
+
class TestFloatPacking:
def setup_class(cls):
@@ -12,17 +15,29 @@
def check_float(self, x):
# check roundtrip
- Q = float_pack(x, 8)
- y = float_unpack(Q, 8)
- assert repr(x) == repr(y)
+ Q = ieee.float_pack(x, 8)
+ y = ieee.float_unpack(Q, 8)
+ assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q)
- Q = float_pack80(x)
- y = float_unpack80(Q)
- assert repr(x) == repr(y),'%r != %r, Q=%r'%(x, y, Q)
+ Q = ieee.float_pack80(x)
+ y = ieee.float_unpack80(Q)
+ assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q)
+
+ Q = []
+ ieee.pack_float(Q, x, 8, False)
+ Q = Q[0]
+ y = ieee.unpack_float(Q, False)
+ assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q)
+
+ Q = []
+ ieee.pack_float80(Q, x, False)
+ Q = Q[0]
+ y = ieee.unpack_float80(Q, False)
+ assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q)
# check that packing agrees with the struct module
struct_pack8 = struct.unpack('<Q', struct.pack('<d', x))[0]
- float_pack8 = float_pack(x, 8)
+ float_pack8 = ieee.float_pack(x, 8)
assert struct_pack8 == float_pack8
# check that packing agrees with the struct module
@@ -31,7 +46,7 @@
except OverflowError:
struct_pack4 = "overflow"
try:
- float_pack4 = float_pack(x, 4)
+ float_pack4 = ieee.float_pack(x, 4)
except OverflowError:
float_pack4 = "overflow"
assert struct_pack4 == float_pack4
@@ -40,16 +55,16 @@
return
# if we didn't overflow, try round-tripping the binary32 value
- roundtrip = float_pack(float_unpack(float_pack4, 4), 4)
+ roundtrip = ieee.float_pack(ieee.float_unpack(float_pack4, 4), 4)
assert float_pack4 == roundtrip
try:
- float_pack2 = float_pack(x, 2)
+ float_pack2 = ieee.float_pack(x, 2)
except OverflowError:
return
- roundtrip = float_pack(float_unpack(float_pack2, 2), 2)
- assert (float_pack2,x) == (roundtrip,x)
+ roundtrip = ieee.float_pack(ieee.float_unpack(float_pack2, 2), 2)
+ assert (float_pack2, x) == (roundtrip, x)
def test_infinities(self):
self.check_float(float('inf'))
@@ -61,23 +76,23 @@
def test_check_size(self):
# these were refactored into separate pack80/unpack80 functions
- py.test.raises(ValueError, float_pack, 1.0, 12)
- py.test.raises(ValueError, float_pack, 1.0, 16)
- py.test.raises(ValueError, float_unpack, 1, 12)
- py.test.raises(ValueError, float_unpack, 1, 16)
+ py.test.raises(ValueError, ieee.float_pack, 1.0, 12)
+ py.test.raises(ValueError, ieee.float_pack, 1.0, 16)
+ py.test.raises(ValueError, ieee.float_unpack, 1, 12)
+ py.test.raises(ValueError, ieee.float_unpack, 1, 16)
def test_nans(self):
- Q = float_pack80(float('nan'))
- y = float_unpack80(Q)
+ Q = ieee.float_pack80(float('nan'))
+ y = ieee.float_unpack80(Q)
assert repr(y) == 'nan'
- Q = float_pack(float('nan'), 8)
- y = float_unpack(Q, 8)
+ Q = ieee.float_pack(float('nan'), 8)
+ y = ieee.float_unpack(Q, 8)
assert repr(y) == 'nan'
- L = float_pack(float('nan'), 4)
- z = float_unpack(L, 4)
+ L = ieee.float_pack(float('nan'), 4)
+ z = ieee.float_unpack(L, 4)
assert repr(z) == 'nan'
- L = float_pack(float('nan'), 2)
- z = float_unpack(L, 2)
+ L = ieee.float_pack(float('nan'), 2)
+ z = ieee.float_unpack(L, 2)
assert repr(z) == 'nan'
def test_simple(self):
@@ -138,22 +153,22 @@
def test_halffloat_exact(self):
#testcases generated from numpy.float16(x).view('uint16')
- cases = [[0, 0], [10, 18688], [-10, 51456], [10e3, 28898],
+ cases = [[0, 0], [10, 18688], [-10, 51456], [10e3, 28898],
[float('inf'), 31744], [-float('inf'), 64512]]
- for c,h in cases:
- hbit = float_pack(c, 2)
+ for c, h in cases:
+ hbit = ieee.float_pack(c, 2)
assert hbit == h
- assert c == float_unpack(h, 2)
+ assert c == ieee.float_unpack(h, 2)
def test_halffloat_inexact(self):
#testcases generated from numpy.float16(x).view('uint16')
cases = [[10.001, 18688, 10.], [-10.001, 51456, -10],
[0.027588, 10000, 0.027587890625],
[22001, 30047, 22000]]
- for c,h,f in cases:
- hbit = float_pack(c, 2)
+ for c, h, f in cases:
+ hbit = ieee.float_pack(c, 2)
assert hbit == h
- assert f == float_unpack(h, 2)
+ assert f == ieee.float_unpack(h, 2)
def test_halffloat_overunderflow(self):
import math
@@ -161,8 +176,43 @@
[1e-08, 0], [-1e-8, -0.]]
for f1, f2 in cases:
try:
- f_out = float_unpack(float_pack(f1, 2), 2)
+ f_out = ieee.float_unpack(ieee.float_pack(f1, 2), 2)
except OverflowError:
f_out = math.copysign(float('inf'), f1)
assert f_out == f2
assert math.copysign(1., f_out) == math.copysign(1., f2)
+
+
+class TestCompiled:
+ def test_pack_float(self):
+ def pack(x, size):
+ result = []
+ ieee.pack_float(result, x, size, False)
+ l = []
+ for x in result:
+ for c in x:
+ l.append(str(ord(c)))
+ return ','.join(l)
+ c_pack = compile(pack, [float, int])
+
+ def unpack(s):
+ l = s.split(',')
+ s = ''.join([chr(int(x)) for x in l])
+ return ieee.unpack_float(s, False)
+ c_unpack = compile(unpack, [str])
+
+ def check_roundtrip(x, size):
+ s = c_pack(x, size)
+ assert s == pack(x, size)
+ if not isnan(x):
+ assert unpack(s) == x
+ assert c_unpack(s) == x
+ else:
+ assert isnan(unpack(s))
+ assert isnan(c_unpack(s))
+
+ for size in [2, 4, 8]:
+ check_roundtrip(123.4375, size)
+ check_roundtrip(-123.4375, size)
+ check_roundtrip(INFINITY, size)
+ check_roundtrip(NAN, size)
diff --git a/rpython/rlib/test/test_rstruct.py b/rpython/rlib/rstruct/test/test_runpack.py
rename from rpython/rlib/test/test_rstruct.py
rename to rpython/rlib/rstruct/test/test_runpack.py
--- a/rpython/rlib/test/test_rstruct.py
+++ b/rpython/rlib/rstruct/test/test_runpack.py
@@ -1,10 +1,6 @@
-
from rpython.rtyper.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin
from rpython.rlib.rstruct.runpack import runpack
-from rpython.rlib.rstruct import ieee
from rpython.rlib.rarithmetic import LONG_BIT
-from rpython.rlib.rfloat import INFINITY, NAN, isnan
-from rpython.translator.c.test.test_genc import compile
import struct
class BaseTestRStruct(BaseRtypingTest):
@@ -17,11 +13,9 @@
def test_unpack_2(self):
data = struct.pack('iiii', 0, 1, 2, 4)
-
def fn():
a, b, c, d = runpack('iiii', data)
return a * 1000 + b * 100 + c * 10 + d
-
assert fn() == 124
assert self.interpret(fn, []) == 124
@@ -37,36 +31,3 @@
class TestOOType(BaseTestRStruct, OORtypeMixin):
pass
-
-class TestCompiled:
- def test_pack_float(self):
- def pack(x):
- result = []
- ieee.pack_float(result, x, 8, False)
- l = []
- for x in result:
- for c in x:
- l.append(str(ord(c)))
- return ','.join(l)
- c_pack = compile(pack, [float])
- def unpack(s):
- l = s.split(',')
- s = ''.join([chr(int(x)) for x in l])
- return ieee.unpack_float(s, False)
- c_unpack = compile(unpack, [str])
-
- def check_roundtrip(x):
- s = c_pack(x)
- assert s == pack(x)
- if not isnan(x):
- assert unpack(s) == x
- assert c_unpack(s) == x
- else:
- assert isnan(unpack(s))
- assert isnan(c_unpack(s))
-
- check_roundtrip(123.456)
- check_roundtrip(-123.456)
- check_roundtrip(INFINITY)
- check_roundtrip(NAN)
-
diff --git a/rpython/rlib/streamio.py b/rpython/rlib/streamio.py
--- a/rpython/rlib/streamio.py
+++ b/rpython/rlib/streamio.py
@@ -795,8 +795,10 @@
self.buflen += len(data)
else:
if self.buflen:
+ self.buf.append(data[:p])
self.do_write(''.join(self.buf))
- self.do_write(data[:p])
+ else:
+ self.do_write(data[:p])
self.buf = [data[p:]]
self.buflen = len(self.buf[0])
else:
diff --git a/rpython/rlib/test/test_rarithmetic.py b/rpython/rlib/test/test_rarithmetic.py
--- a/rpython/rlib/test/test_rarithmetic.py
+++ b/rpython/rlib/test/test_rarithmetic.py
@@ -400,8 +400,8 @@
assert rffi.cast(lltype.Signed, byteswap(rffi.cast(rffi.USHORT, 0x0102))) == 0x0201
assert rffi.cast(lltype.Signed, byteswap(rffi.cast(rffi.INT, 0x01020304))) == 0x04030201
- assert byteswap(rffi.cast(rffi.ULONGLONG, 0x0102030405060708L)) == 0x0807060504030201L
- assert byteswap(rffi.cast(rffi.LONGLONG, 0x0102030405060708L)) == 0x0807060504030201L
+ assert byteswap(r_ulonglong(0x0102030405060708L)) == r_ulonglong(0x0807060504030201L)
+ assert byteswap(r_longlong(0x0102030405060708L)) == r_longlong(0x0807060504030201L)
assert ((byteswap(2.3) - 1.903598566252326e+185) / 1e185) < 0.000001
assert (rffi.cast(lltype.Float, byteswap(rffi.cast(lltype.SingleFloat, 2.3))) - 4.173496037651603e-08) < 1e-16
diff --git a/rpython/rtyper/lltypesystem/rlist.py b/rpython/rtyper/lltypesystem/rlist.py
--- a/rpython/rtyper/lltypesystem/rlist.py
+++ b/rpython/rtyper/lltypesystem/rlist.py
@@ -246,6 +246,7 @@
of the list to be 'newsize'."""
_ll_list_resize_really(l, newsize, False)
+
@jit.look_inside_iff(lambda l, newsize: jit.isconstant(len(l.items)) and jit.isconstant(newsize))
@jit.oopspec("list._resize_ge(l, newsize)")
def _ll_list_resize_ge(l, newsize):
More information about the pypy-commit
mailing list