Commits

Philip Jenvey committed 6f87956 Merge

merge default

Comments (0)

Files changed (32)

pypy/interpreter/miscutils.py

     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}

pypy/interpreter/test2/test_app_main.py

     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
         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'])
         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')
 
                         '-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

pypy/module/__pypy__/__init__.py

                 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 = {
     }
     submodules = {
         "builders": BuildersModule,
         "time": TimeModule,
+        "thread": ThreadModule,
     }
 
     def setup_after_space_initialization(self):

pypy/module/__pypy__/app_signal.py

+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()

pypy/module/__pypy__/interp_signal.py

+
+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()

pypy/module/__pypy__/test/test_signal.py

+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__

pypy/module/_cffi_backend/test/_backend_test_c.py

     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:

pypy/module/gc/test/test_ztranslation.py

+from pypy.objspace.fake.checkmodule import checkmodule
+
+def test_checkmodule():
+    checkmodule('gc')

pypy/module/micronumpy/test/test_module.py

         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)) == []

pypy/module/micronumpy/test/test_numarray.py

         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
 
     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()
         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

pypy/module/micronumpy/types.py

 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
         swapped_value = byteswap(rffi.cast(self.T, value))
         raw_storage_setitem(storage, i + offset, swapped_value)
 
-
 class Float32(BaseType, Float):
     _attrs_ = ()
 
     BoxType = interp_boxes.W_Complex64Box
     ComponentBoxType = interp_boxes.W_Float32Box
 
-
 NonNativeComplex64 = Complex64
 
 class Complex128(ComplexFloating, BaseType):
     BoxType = interp_boxes.W_Complex128Box
     ComponentBoxType = interp_boxes.W_Float64Box
 
-
 NonNativeComplex128 = Complex128
 
 if interp_boxes.long_double_size == 12:
 
         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_ = ()
 
     NonNativeComplex192 = Complex192
 
-
 elif interp_boxes.long_double_size == 16:
     class Float128(BaseType, Float):
         _attrs_ = ()
 
         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
 
         BoxType = interp_boxes.W_Complex256Box
         ComponentBoxType = interp_boxes.W_Float128Box
 
-
     NonNativeComplex256 = Complex256
 
 class BaseStringType(object):

pypy/module/signal/interp_signal.py

         "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
         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
                 # 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):
         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
 
 # ____________________________________________________________
 
     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)):
 
     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))
 

pypy/module/sys/initpath.py

     stdlib.
     If it cannot be found, return (None, None).
     """
+    if executable == '':
+        return None, None
     search = executable
     while True:
         dirname = resolvedirof(search)

pypy/module/sys/test/test_initpath.py

     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):
     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)

pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py

         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))
         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]])

pypy/module/test_lib_pypy/numpypy/test_numpy.py

             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

pypy/module/thread/__init__.py

File contents unchanged.

pypy/module/thread/gil.py

 # 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
                                                   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):
     # 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
     # 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

pypy/module/thread/os_lock.py

 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
 ##    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)
 
 
     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)
 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):

pypy/module/thread/os_thread.py

 """
 
 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
     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
         # 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
             except OSError:
                 pass
         bootstrapper.nbthreads -= 1
-        thread.gc_thread_die()
+        rthread.gc_thread_die()
     bootstrap = staticmethod(bootstrap)
 
     def acquire(space, w_callable, args):
             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)
     "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')
     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)
 
 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)
     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)

pypy/module/thread/threadlocals.py

-from rpython.rlib import rthread as thread
+from rpython.rlib import rthread
 
 
 class OSThreadLocals:
 
     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:
         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:
         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
 
     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

rpython/jit/codewriter/assembler.py

         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]))

rpython/rlib/jit.py

                  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
         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
 
     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

rpython/rlib/rarithmetic.py

          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:
                (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)

rpython/rlib/rstruct/ieee.py

     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()
         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)

rpython/rlib/rstruct/runpack.py

     def __init__(self, fmt):
         self.formats = []
         self.fmt = fmt
-    
+
     def operate(self, fmtdesc, repetitions):
         if fmtdesc.needcount:
             self.formats.append((fmtdesc, repetitions, None))
     unpacker = create_unpacker(fmt)
     return unpacker.unpack(input)
 runpack._annspecialcase_ = 'specialize:arg(0)'
-
-    

rpython/rlib/rstruct/test/test_ieee.py

-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):
 
     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
         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
             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'))
 
     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):
 
     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
                  [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)

rpython/rlib/rstruct/test/test_runpack.py

+from rpython.rtyper.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin
+from rpython.rlib.rstruct.runpack import runpack
+from rpython.rlib.rarithmetic import LONG_BIT
+import struct
+
+class BaseTestRStruct(BaseRtypingTest):
+    def test_unpack(self):
+        pad = '\x00' * (LONG_BIT//8-1)    # 3 or 7 null bytes
+        def fn():
+            return runpack('sll', 'a'+pad+'\x03'+pad+'\x04'+pad)[1]
+        assert fn() == 3
+        assert self.interpret(fn, []) == 3
+
+    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
+
+    def test_unpack_single(self):
+        data = struct.pack('i', 123)
+        def fn():
+            return runpack('i', data)
+        assert fn() == 123
+        assert self.interpret(fn, []) == 123
+
+class TestLLType(BaseTestRStruct, LLRtypeMixin):
+    pass
+
+class TestOOType(BaseTestRStruct, OORtypeMixin):
+    pass

rpython/rlib/streamio.py

                 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:

rpython/rlib/test/test_rarithmetic.py

     
     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
 

rpython/rlib/test/test_rstruct.py

-
-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):
-    def test_unpack(self):
-        pad = '\x00' * (LONG_BIT//8-1)    # 3 or 7 null bytes
-        def fn():
-            return runpack('sll', 'a'+pad+'\x03'+pad+'\x04'+pad)[1]
-        assert fn() == 3
-        assert self.interpret(fn, []) == 3
-
-    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
-
-    def test_unpack_single(self):
-        data = struct.pack('i', 123)
-        def fn():
-            return runpack('i', data)
-        assert fn() == 123
-        assert self.interpret(fn, []) == 123
-
-class TestLLType(BaseTestRStruct, LLRtypeMixin):
-    pass
-
-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)
-

rpython/rtyper/lltypesystem/rlist.py

     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):