[pypy-commit] pypy jitframe-on-heap: merge

bivab noreply at buildbot.pypy.org
Fri Feb 8 16:41:56 CET 2013


Author: David Schneider <david.schneider at picle.org>
Branch: jitframe-on-heap
Changeset: r60980:0b7ee0aefa60
Date: 2013-02-08 16:41 +0100
http://bitbucket.org/pypy/pypy/changeset/0b7ee0aefa60/

Log:	merge

diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py
--- a/lib-python/2.7/collections.py
+++ b/lib-python/2.7/collections.py
@@ -6,11 +6,12 @@
 __all__ += _abcoll.__all__
 
 from _collections import deque, defaultdict
-from operator import itemgetter as _itemgetter
+from operator import itemgetter as _itemgetter, eq as _eq
 from keyword import iskeyword as _iskeyword
 import sys as _sys
 import heapq as _heapq
 from itertools import repeat as _repeat, chain as _chain, starmap as _starmap
+from itertools import imap as _imap
 
 try:
     from thread import get_ident as _get_ident
@@ -50,49 +51,45 @@
             self.__map = {}
         self.__update(*args, **kwds)
 
-    def __setitem__(self, key, value, PREV=0, NEXT=1, dict_setitem=dict.__setitem__):
+    def __setitem__(self, key, value, dict_setitem=dict.__setitem__):
         'od.__setitem__(i, y) <==> od[i]=y'
         # Setting a new item creates a new link at the end of the linked list,
         # and the inherited dictionary is updated with the new key/value pair.
         if key not in self:
             root = self.__root
-            last = root[PREV]
-            last[NEXT] = root[PREV] = self.__map[key] = [last, root, key]
-        dict_setitem(self, key, value)
+            last = root[0]
+            last[1] = root[0] = self.__map[key] = [last, root, key]
+        return dict_setitem(self, key, value)
 
-    def __delitem__(self, key, PREV=0, NEXT=1, dict_delitem=dict.__delitem__):
+    def __delitem__(self, key, dict_delitem=dict.__delitem__):
         'od.__delitem__(y) <==> del od[y]'
         # Deleting an existing item uses self.__map to find the link which gets
         # removed by updating the links in the predecessor and successor nodes.
         dict_delitem(self, key)
         link_prev, link_next, key = self.__map.pop(key)
-        link_prev[NEXT] = link_next
-        link_next[PREV] = link_prev
+        link_prev[1] = link_next                        # update link_prev[NEXT]
+        link_next[0] = link_prev                        # update link_next[PREV]
 
     def __iter__(self):
         'od.__iter__() <==> iter(od)'
         # Traverse the linked list in order.
-        NEXT, KEY = 1, 2
         root = self.__root
-        curr = root[NEXT]
+        curr = root[1]                                  # start at the first node
         while curr is not root:
-            yield curr[KEY]
-            curr = curr[NEXT]
+            yield curr[2]                               # yield the curr[KEY]
+            curr = curr[1]                              # move to next node
 
     def __reversed__(self):
         'od.__reversed__() <==> reversed(od)'
         # Traverse the linked list in reverse order.
-        PREV, KEY = 0, 2
         root = self.__root
-        curr = root[PREV]
+        curr = root[0]                                  # start at the last node
         while curr is not root:
-            yield curr[KEY]
-            curr = curr[PREV]
+            yield curr[2]                               # yield the curr[KEY]
+            curr = curr[0]                              # move to previous node
 
     def clear(self):
         'od.clear() -> None.  Remove all items from od.'
-        for node in self.__map.itervalues():
-            del node[:]
         root = self.__root
         root[:] = [root, root, None]
         self.__map.clear()
@@ -208,7 +205,7 @@
 
         '''
         if isinstance(other, OrderedDict):
-            return len(self)==len(other) and self.items() == other.items()
+            return dict.__eq__(self, other) and all(_imap(_eq, self, other))
         return dict.__eq__(self, other)
 
     def __ne__(self, other):
diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py
--- a/lib_pypy/greenlet.py
+++ b/lib_pypy/greenlet.py
@@ -1,5 +1,6 @@
 import _continuation, sys
 
+__version__ = "0.4.0"
 
 # ____________________________________________________________
 # Exceptions
diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py
--- a/lib_pypy/pyrepl/unix_console.py
+++ b/lib_pypy/pyrepl/unix_console.py
@@ -398,6 +398,7 @@
 
         if hasattr(self, 'old_sigwinch'):
             signal.signal(signal.SIGWINCH, self.old_sigwinch)
+            del self.old_sigwinch
 
     def __sigwinch(self, signum, frame):
         self.height, self.width = self.getheightwidth()
diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py
--- a/pypy/interpreter/app_main.py
+++ b/pypy/interpreter/app_main.py
@@ -436,11 +436,14 @@
     # (relevant in case of "reload(sys)")
     sys.argv[:] = argv
 
-    if PYTHON26 and not options["ignore_environment"]:
-        if os.getenv('PYTHONNOUSERSITE'):
-            options["no_user_site"] = 1
-        if os.getenv('PYTHONDONTWRITEBYTECODE'):
-            options["dont_write_bytecode"] = 1
+    if not options["ignore_environment"]:
+        if os.getenv('PYTHONUNBUFFERED'):
+            options["unbuffered"] = 1
+        if PYTHON26:
+            if os.getenv('PYTHONNOUSERSITE'):
+                options["no_user_site"] = 1
+            if os.getenv('PYTHONDONTWRITEBYTECODE'):
+                options["dont_write_bytecode"] = 1
 
     if (options["interactive"] or
         (not options["ignore_environment"] and os.getenv('PYTHONINSPECT'))):
@@ -716,7 +719,7 @@
         root = dn(dn(dn(thisfile)))
         return [join(root, 'lib-python', '2.7'),
                 join(root, 'lib_pypy')]
-    
+
     def pypy_resolvedirof(s):
         # we ignore the issue of symlinks; for tests, the executable is always
         # interpreter/app_main.py anyway
@@ -756,6 +759,10 @@
     del os # make sure that os is not available globally, because this is what
            # happens in "real life" outside the tests
 
+    if 'time' not in sys.builtin_module_names:
+        # make some tests happy by loading this before we clobber sys.path
+        import time; del time
+
     # no one should change to which lists sys.argv and sys.path are bound
     old_argv = sys.argv
     old_path = sys.path
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
@@ -712,6 +712,26 @@
         assert data == '\x00(STDOUT)\n\x00'    # from stdout
         child_out_err.close()
 
+    def test_non_interactive_stdout_unbuffered(self, monkeypatch):
+        monkeypatch.setenv('PYTHONUNBUFFERED', '1')
+        path = getscript(r"""
+            import sys, time
+            sys.stdout.write('\x00(STDOUT)\n\x00')
+            time.sleep(1)
+            sys.stderr.write('\x00[STDERR]\n\x00')
+            time.sleep(1)
+            # stdout flushed automatically here
+            """)
+        cmdline = '%s -E "%s" %s' % (sys.executable, app_main, path)
+        print 'POPEN:', cmdline
+        child_in, child_out_err = os.popen4(cmdline)
+        data = child_out_err.read(11)
+        assert data == '\x00(STDOUT)\n\x00'    # from stderr
+        data = child_out_err.read(11)
+        assert data == '\x00[STDERR]\n\x00'    # from stdout
+        child_out_err.close()
+        child_in.close()
+
     def test_proper_sys_path(self, tmpdir):
         data = self.run('-c "import _ctypes"', python_flags='-S')
         if data.startswith('Traceback'):
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
@@ -14,7 +14,7 @@
 class TimeModule(MixedModule):
     appleveldefs = {}
     interpleveldefs = {}
-    if sys.platform.startswith("linux"):
+    if sys.platform.startswith("linux") or 'bsd' in sys.platform:
         from pypy.module.__pypy__ import interp_time
         interpleveldefs["clock_gettime"] = "interp_time.clock_gettime"
         interpleveldefs["clock_getres"] = "interp_time.clock_getres"
diff --git a/pypy/module/_cffi_backend/cbuffer.py b/pypy/module/_cffi_backend/cbuffer.py
--- a/pypy/module/_cffi_backend/cbuffer.py
+++ b/pypy/module/_cffi_backend/cbuffer.py
@@ -2,7 +2,7 @@
 from pypy.interpreter.baseobjspace import Wrappable
 from pypy.interpreter.buffer import RWBuffer
 from pypy.interpreter.gateway import unwrap_spec, interp2app
-from pypy.interpreter.typedef import TypeDef
+from pypy.interpreter.typedef import TypeDef, make_weakref_descr
 from rpython.rtyper.lltypesystem import rffi
 from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray
 
@@ -41,8 +41,9 @@
     # a different subclass of Wrappable for the MiniBuffer, because we
     # want a slightly different (simplified) API at the level of Python.
 
-    def __init__(self, buffer):
+    def __init__(self, buffer, keepalive=None):
         self.buffer = buffer
+        self.keepalive = keepalive
 
     def descr_len(self, space):
         return self.buffer.descr_len(space)
@@ -65,6 +66,7 @@
     __getitem__ = interp2app(MiniBuffer.descr_getitem),
     __setitem__ = interp2app(MiniBuffer.descr_setitem),
     __buffer__ = interp2app(MiniBuffer.descr__buffer__),
+    __weakref__ = make_weakref_descr(MiniBuffer),
     )
 MiniBuffer.typedef.acceptable_as_base_class = False
 
@@ -86,4 +88,4 @@
         raise operationerrfmt(space.w_TypeError,
                               "don't know the size pointed to by '%s'",
                               ctype.name)
-    return space.wrap(MiniBuffer(LLBuffer(cdata._cdata, size)))
+    return space.wrap(MiniBuffer(LLBuffer(cdata._cdata, size), cdata))
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
@@ -12,6 +12,7 @@
             return eval('u'+repr(other).replace(r'\\u', r'\u')
                                        .replace(r'\\U', r'\U'))
     u = U()
+    str2bytes = str
 else:
     type_or_class = "class"
     long = int
@@ -22,6 +23,7 @@
     bytechr = lambda n: bytes([n])
     bitem2bchr = bytechr
     u = ""
+    str2bytes = lambda s: bytes(s, "ascii")
 
 def size_of_int():
     BInt = new_primitive_type("int")
@@ -1438,10 +1440,16 @@
     import _weakref
     BInt = new_primitive_type("int")
     BPtr = new_pointer_type(BInt)
-    _weakref.ref(BInt)
-    _weakref.ref(newp(BPtr, 42))
-    _weakref.ref(cast(BPtr, 42))
-    _weakref.ref(cast(BInt, 42))
+    rlist = [_weakref.ref(BInt),
+             _weakref.ref(newp(BPtr, 42)),
+             _weakref.ref(cast(BPtr, 42)),
+             _weakref.ref(cast(BInt, 42)),
+             _weakref.ref(buffer(newp(BPtr, 42))),
+             ]
+    for i in range(5):
+        import gc; gc.collect()
+        if [r() for r in rlist] == [None for r in rlist]:
+            break
 
 def test_no_inheritance():
     BInt = new_primitive_type("int")
@@ -2544,3 +2552,15 @@
     BCharP = new_pointer_type(new_primitive_type("char"))
     BCharArray = new_array_type(BCharP, None)
     py.test.raises(TypeError, newp, BCharArray, u+'foobar')
+
+def test_buffer_keepalive():
+    BCharP = new_pointer_type(new_primitive_type("char"))
+    BCharArray = new_array_type(BCharP, None)
+    buflist = []
+    for i in range(20):
+        c = newp(BCharArray, str2bytes("hi there %d" % i))
+        buflist.append(buffer(c))
+    import gc; gc.collect()
+    for i in range(20):
+        buf = buflist[i]
+        assert buf[:] == str2bytes("hi there %d\x00" % i)
diff --git a/pypy/module/_multibytecodec/c_codecs.py b/pypy/module/_multibytecodec/c_codecs.py
--- a/pypy/module/_multibytecodec/c_codecs.py
+++ b/pypy/module/_multibytecodec/c_codecs.py
@@ -62,7 +62,7 @@
         "pypy_cjk_enc_init", "pypy_cjk_enc_free", "pypy_cjk_enc_chunk",
         "pypy_cjk_enc_reset", "pypy_cjk_enc_outbuf", "pypy_cjk_enc_outlen",
         "pypy_cjk_enc_inbuf_remaining", "pypy_cjk_enc_inbuf_consumed",
-        "pypy_cjk_enc_replace_on_error",
+        "pypy_cjk_enc_replace_on_error", "pypy_cjk_enc_getcodec",
     ] + ["pypy_cjkcodec_%s" % codec for codec in codecs],
 )
 
diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py
--- a/pypy/module/micronumpy/arrayimpl/concrete.py
+++ b/pypy/module/micronumpy/arrayimpl/concrete.py
@@ -275,6 +275,11 @@
     def get_buffer(self, space):
         return ArrayBuffer(self)
 
+    def astype(self, space, dtype):
+        new_arr = W_NDimArray.from_shape(self.get_shape(), dtype)
+        loop.copy_from_to(self, new_arr.implementation, dtype)
+        return new_arr
+
 class ConcreteArrayNotOwning(BaseConcreteArray):
     def __init__(self, shape, dtype, order, strides, backstrides, storage):
 
@@ -309,11 +314,6 @@
     def argsort(self, space, w_axis):
         return argsort_array(self, space, w_axis)
 
-    def astype(self, space, dtype):
-        new_arr = W_NDimArray.from_shape(self.get_shape(), dtype)
-        loop.copy_from_to(self, new_arr.implementation, dtype)
-        return new_arr
-
     def base(self):
         return None
 
diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py
--- a/pypy/module/micronumpy/arrayimpl/scalar.py
+++ b/pypy/module/micronumpy/arrayimpl/scalar.py
@@ -7,18 +7,19 @@
 class ScalarIterator(base.BaseArrayIterator):
     def __init__(self, v):
         self.v = v
+        self.called_once = False
 
     def next(self):
-        pass
+        self.called_once = True
 
     def getitem(self):
-        return self.v
+        return self.v.get_scalar_value()
 
     def setitem(self, v):
-        raise Exception("Don't call setitem on scalar iterators")
+        self.v.set_scalar_value(v)
 
     def done(self):
-        raise Exception("should not call done on scalar")
+        return self.called_once
 
     def reset(self):
         pass
@@ -38,7 +39,7 @@
         return []
 
     def create_iter(self, shape=None):
-        return ScalarIterator(self.value)
+        return ScalarIterator(self)
 
     def get_scalar_value(self):
         return self.value
diff --git a/pypy/module/micronumpy/base.py b/pypy/module/micronumpy/base.py
--- a/pypy/module/micronumpy/base.py
+++ b/pypy/module/micronumpy/base.py
@@ -21,11 +21,13 @@
     
     @staticmethod
     def from_shape(shape, dtype, order='C'):
-        from pypy.module.micronumpy.arrayimpl import concrete
-
-        assert shape
-        strides, backstrides = calc_strides(shape, dtype, order)
-        impl = concrete.ConcreteArray(shape, dtype, order, strides,
+        from pypy.module.micronumpy.arrayimpl import concrete, scalar
+        
+        if not shape:
+            impl = scalar.Scalar(dtype)
+        else:
+            strides, backstrides = calc_strides(shape, dtype, order)
+            impl = concrete.ConcreteArray(shape, dtype, order, strides,
                                       backstrides)
         return W_NDimArray(impl)
 
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
@@ -1640,7 +1640,7 @@
         assert _weakref.ref(a)
 
     def test_astype(self):
-        from _numpypy import array
+        from _numpypy import array, arange
         b = array(1).astype(float)
         assert b == 1
         assert b.dtype == float
@@ -1653,7 +1653,9 @@
         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')
 
     def test_base(self):
         from _numpypy import array
@@ -1700,6 +1702,12 @@
         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]
+
     def test_clip(self):
         from _numpypy import array
         a = array([1, 2, 17, -3, 12])
@@ -2368,6 +2376,7 @@
         assert array([1, 2, 3], 'i2')[::2].tostring() == '\x01\x00\x03\x00'
         assert array([1, 2, 3], '<i2')[::2].tostring() == '\x01\x00\x03\x00'
         assert array([1, 2, 3], '>i2')[::2].tostring() == '\x00\x01\x00\x03'
+        assert array(0, dtype='i2').tostring() == '\x00\x00'
 
     def test_argsort_dtypes(self):
         from _numpypy import array, arange
diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py
--- a/pypy/module/posix/test/test_posix2.py
+++ b/pypy/module/posix/test/test_posix2.py
@@ -514,12 +514,14 @@
             assert res == '1\n'
 
     def test_popen_child_fds(self):
-        os = self.posix
-        from os.path import join
-        with open(join(self.pdir, 'file1'), 'r') as fd:
-            with os.popen('%s -c "import os; print os.read(%d, 10)"' % (self.python, fd.fileno())) as stream:
+        import os
+        with open(os.path.join(self.pdir, 'file1'), 'r') as fd:
+            with self.posix.popen('%s -c "import os; print os.read(%d, 10)" 2>&1' % (self.python, fd.fileno())) as stream:
                 res = stream.read()
-                assert res == 'test1\n'
+                if os.name == 'nt':
+                    assert '\nOSError: [Errno 9]' in res
+                else:
+                    assert res == 'test1\n'
 
     if hasattr(__import__(os.name), '_getfullpathname'):
         def test__getfullpathname(self):
diff --git a/pypy/module/pyexpat/interp_pyexpat.py b/pypy/module/pyexpat/interp_pyexpat.py
--- a/pypy/module/pyexpat/interp_pyexpat.py
+++ b/pypy/module/pyexpat/interp_pyexpat.py
@@ -443,7 +443,10 @@
         if XML_ParserFree: # careful with CPython interpreter shutdown
             XML_ParserFree(self.itself)
         if global_storage:
-            global_storage.free_nonmoving_id(self.id)
+            try:
+                global_storage.free_nonmoving_id(self.id)
+            except KeyError:
+                pass    # maybe global_storage.clear() was already called
 
     @unwrap_spec(flag=int)
     def SetParamEntityParsing(self, space, flag):
@@ -636,10 +639,13 @@
     def ParseFile(self, space, w_file):
         """ParseFile(file)
 Parse XML data from file-like object."""
-        # XXX not the more efficient method
-        w_data = space.call_method(w_file, 'read')
-        data = space.str_w(w_data)
-        return self.Parse(space, data, isfinal=True)
+        eof = False
+        while not eof:
+            w_data = space.call_method(w_file, 'read', space.wrap(2048))
+            data = space.str_w(w_data)
+            eof = len(data) == 0
+            w_res = self.Parse(space, data, isfinal=eof)
+        return w_res
 
     @unwrap_spec(base=str)
     def SetBase(self, space, base):
diff --git a/pypy/module/pyexpat/test/test_parser.py b/pypy/module/pyexpat/test/test_parser.py
--- a/pypy/module/pyexpat/test/test_parser.py
+++ b/pypy/module/pyexpat/test/test_parser.py
@@ -146,3 +146,24 @@
     def test_model(self):
         import pyexpat
         assert isinstance(pyexpat.model.XML_CTYPE_EMPTY, int)
+
+    def test_read_chunks(self):
+        import pyexpat
+        import StringIO
+        from contextlib import closing
+
+        xml = '<xml>' + (' ' * 4096) + '</xml>'
+        with closing(StringIO.StringIO(xml)) as sio:
+            class FakeReader():
+                def __init__(self):
+                    self.read_count = 0
+
+                def read(self, size):
+                    self.read_count += 1
+                    assert size > 0
+                    return sio.read(size)
+
+            fake_reader = FakeReader()
+            p = pyexpat.ParserCreate()
+            p.ParseFile(fake_reader)
+            assert fake_reader.read_count == 4
diff --git a/pypy/module/rctime/test/test_rctime.py b/pypy/module/rctime/test/test_rctime.py
--- a/pypy/module/rctime/test/test_rctime.py
+++ b/pypy/module/rctime/test/test_rctime.py
@@ -237,7 +237,7 @@
         # input to [w]strftime is not kosher.
         if os.name == 'nt':
             raises(ValueError, rctime.strftime, '%f')
-        elif sys.platform == 'darwin':
+        elif sys.platform == 'darwin' or 'bsd' in sys.platform:
             # darwin strips % of unknown format codes
             # http://bugs.python.org/issue9811
             assert rctime.strftime('%f') == 'f'
diff --git a/pypy/module/signal/test/test_signal.py b/pypy/module/signal/test/test_signal.py
--- a/pypy/module/signal/test/test_signal.py
+++ b/pypy/module/signal/test/test_signal.py
@@ -157,7 +157,7 @@
         if sys.platform == 'win32':
             raises(ValueError, signal, 42, lambda *args: None)
             raises(ValueError, signal, 7, lambda *args: None)
-        elif sys.platform == 'darwin':
+        elif sys.platform == 'darwin' or 'bsd' in sys.platform:
             raises(ValueError, signal, 42, lambda *args: None)
         else:
             signal(42, lambda *args: None)
diff --git a/pypy/module/zipimport/interp_zipimport.py b/pypy/module/zipimport/interp_zipimport.py
--- a/pypy/module/zipimport/interp_zipimport.py
+++ b/pypy/module/zipimport/interp_zipimport.py
@@ -172,24 +172,24 @@
             return mtime
 
     def check_newer_pyfile(self, space, filename, timestamp):
+        # check if the timestamp stored in the .pyc is matching
+        # the actual timestamp of the .py file, if any
         mtime = self._parse_mtime(space, filename)
         if mtime == 0:
             return False
-        return mtime > timestamp
-
-    def check_compatible_mtime(self, space, filename, timestamp):
-        mtime = self._parse_mtime(space, filename)
-        if mtime == 0 or mtime != (timestamp & (~1)):
-            return False
-        return True
+        # Lenient date/time comparison function. The precision of the mtime
+        # in the archive is lower than the mtime stored in a .pyc: we
+        # must allow a difference of at most one second.
+        d = mtime - timestamp
+        if d < 0:
+            d = -d
+        return d > 1    # more than one second => different
 
     def can_use_pyc(self, space, filename, magic, timestamp):
         if magic != importing.get_pyc_magic(space):
             return False
         if self.check_newer_pyfile(space, filename[:-1], timestamp):
             return False
-        if not self.check_compatible_mtime(space, filename, timestamp):
-            return False
         return True
 
     def import_pyc_file(self, space, modname, filename, buf, pkgpath):
diff --git a/pypy/module/zipimport/test/test_zipimport.py b/pypy/module/zipimport/test/test_zipimport.py
--- a/pypy/module/zipimport/test/test_zipimport.py
+++ b/pypy/module/zipimport/test/test_zipimport.py
@@ -95,6 +95,9 @@
         """)
         self.w_modules = []
 
+    def w_now_in_the_future(self, delta):
+        self.now += delta
+
     def w_writefile(self, filename, data):
         import sys
         import time
@@ -264,10 +267,12 @@
         import os
         import zipimport
         data = "saddsadsa"
+        pyc_data = self.test_pyc
+        self.now_in_the_future(+5)   # write the zipfile 5 secs after the .pyc
         self.writefile("xxx", data)
         self.writefile("xx/__init__.py", "5")
         self.writefile("yy.py", "3")
-        self.writefile('uu.pyc', self.test_pyc)
+        self.writefile('uu.pyc', pyc_data)
         z = zipimport.zipimporter(self.zipfile)
         assert z.get_data(self.zipfile + os.sep + "xxx") == data
         assert z.is_package("xx")
@@ -277,6 +282,7 @@
         raises(ImportError, "z.get_source('zz')")
         #assert z.get_code('yy') == py.code.Source('3').compile()
         #assert z.get_code('uu') == self.co
+        assert z.get_code('uu')
         assert z.get_code('xx')
         assert z.get_source('xx') == "5"
         assert z.archive == self.zipfile
diff --git a/rpython/annotator/description.py b/rpython/annotator/description.py
--- a/rpython/annotator/description.py
+++ b/rpython/annotator/description.py
@@ -497,8 +497,8 @@
             # will do the right thing in s_get_value().
         if isinstance(value, staticmethod) and mixin:
             # make a new copy of staticmethod
-            value =  staticmethod(func_with_new_name(value.__func__,
-                                                     value.__func__.__name__))
+            func = value.__get__(42)
+            value =  staticmethod(func_with_new_name(func, func.__name__))
 
         if type(value) in MemberDescriptorTypes:
             # skip __slots__, showing up in the class as 'member' objects
diff --git a/rpython/translator/platform/posix.py b/rpython/translator/platform/posix.py
--- a/rpython/translator/platform/posix.py
+++ b/rpython/translator/platform/posix.py
@@ -49,10 +49,10 @@
 
         response_file = self._make_response_file("dynamic-symbols-")
         f = response_file.open("w")
-        f.write("{\n")
+        f.write("{\n\tglobal:\n")
         for sym in eci.export_symbols:
-            f.write("%s;\n" % (sym,))
-        f.write("};")
+            f.write("\t\t%s;\n" % (sym,))
+        f.write("\tlocal:\n\t\t*;\n};")
         f.close()
 
         if relto:
diff --git a/rpython/translator/tool/test/test_cbuild.py b/rpython/translator/tool/test/test_cbuild.py
--- a/rpython/translator/tool/test/test_cbuild.py
+++ b/rpython/translator/tool/test/test_cbuild.py
@@ -77,6 +77,10 @@
             int get()
             {
                 return 42;
+            }
+            int shouldnt_export()
+            {
+                return 43;
             }'''],
             export_symbols = ['get']
         )
@@ -87,6 +91,7 @@
         except ImportError:
             py.test.skip("Need ctypes for that test")
         assert ctypes.CDLL(neweci.libraries[0]).get() == 42
+        assert not hasattr(ctypes.CDLL(neweci.libraries[0]), 'shouldnt_export')
         assert not neweci.separate_module_sources
         assert not neweci.separate_module_files
 


More information about the pypy-commit mailing list