[pypy-commit] pypy stm-thread-2: hg merge default

arigo noreply at buildbot.pypy.org
Fri Feb 1 19:09:55 CET 2013


Author: Armin Rigo <arigo at tunes.org>
Branch: stm-thread-2
Changeset: r60810:fe07a7c23088
Date: 2013-02-01 16:29 +0100
http://bitbucket.org/pypy/pypy/changeset/fe07a7c23088/

Log:	hg merge default

diff --git a/lib-python/2.7/test/test_zipfile.py b/lib-python/2.7/test/test_zipfile.py
--- a/lib-python/2.7/test/test_zipfile.py
+++ b/lib-python/2.7/test/test_zipfile.py
@@ -1213,6 +1213,17 @@
             self.assertEqual(data1, '1'*FIXEDTEST_SIZE)
             self.assertEqual(data2, '2'*FIXEDTEST_SIZE)
 
+    def test_many_opens(self):
+        # Verify that read() and open() promptly close the file descriptor,
+        # and don't rely on the garbage collector to free resources.
+        with zipfile.ZipFile(TESTFN2, mode="r") as zipf:
+            for x in range(100):
+                zipf.read('ones')
+                with zipf.open('ones') as zopen1:
+                    pass
+        for x in range(10):
+            self.assertLess(open('/dev/null').fileno(), 100)
+
     def tearDown(self):
         unlink(TESTFN2)
 
diff --git a/lib-python/2.7/zipfile.py b/lib-python/2.7/zipfile.py
--- a/lib-python/2.7/zipfile.py
+++ b/lib-python/2.7/zipfile.py
@@ -475,9 +475,11 @@
     # Search for universal newlines or line chunks.
     PATTERN = re.compile(r'^(?P<chunk>[^\r\n]+)|(?P<newline>\n|\r\n?)')
 
-    def __init__(self, fileobj, mode, zipinfo, decrypter=None):
+    def __init__(self, fileobj, mode, zipinfo, decrypter=None,
+                 close_fileobj=False):
         self._fileobj = fileobj
         self._decrypter = decrypter
+        self._close_fileobj = close_fileobj
 
         self._compress_type = zipinfo.compress_type
         self._compress_size = zipinfo.compress_size
@@ -649,6 +651,12 @@
         self._offset += len(data)
         return data
 
+    def close(self):
+        try:
+            if self._close_fileobj:
+                self._fileobj.close()
+        finally:
+            super(ZipExtFile, self).close()
 
 
 class ZipFile:
@@ -866,7 +874,8 @@
 
     def read(self, name, pwd=None):
         """Return file bytes (as a string) for name."""
-        return self.open(name, "r", pwd).read()
+        with self.open(name, "r", pwd) as fp:
+            return fp.read()
 
     def open(self, name, mode="r", pwd=None):
         """Return file-like object for 'name'."""
@@ -889,8 +898,12 @@
             zinfo = name
         else:
             # Get info object for name
-            zinfo = self.getinfo(name)
-
+            try:
+                zinfo = self.getinfo(name)
+            except KeyError:
+                if not self._filePassed:
+                    zef_file.close()
+                raise
         zef_file.seek(zinfo.header_offset, 0)
 
         # Skip the file header:
@@ -904,6 +917,8 @@
             zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH])
 
         if fname != zinfo.orig_filename:
+            if not self._filePassed:
+                zef_file.close()
             raise BadZipfile, \
                       'File name in directory "%s" and header "%s" differ.' % (
                           zinfo.orig_filename, fname)
@@ -915,6 +930,8 @@
             if not pwd:
                 pwd = self.pwd
             if not pwd:
+                if not self._filePassed:
+                    zef_file.close()
                 raise RuntimeError, "File %s is encrypted, " \
                       "password required for extraction" % name
 
@@ -933,9 +950,12 @@
                 # compare against the CRC otherwise
                 check_byte = (zinfo.CRC >> 24) & 0xff
             if ord(h[11]) != check_byte:
+                if not self._filePassed:
+                    zef_file.close()
                 raise RuntimeError("Bad password for file", name)
 
-        return  ZipExtFile(zef_file, mode, zinfo, zd)
+        return ZipExtFile(zef_file, mode, zinfo, zd,
+                          close_fileobj=not self._filePassed)
 
     def extract(self, member, path=None, pwd=None):
         """Extract a member from the archive to the current working directory,
@@ -993,7 +1013,7 @@
             return targetpath
 
         source = self.open(member, pwd=pwd)
-        target = file(targetpath, "wb")
+        target = open(targetpath, "wb")
         shutil.copyfileobj(source, target)
         source.close()
         target.close()
diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py
--- a/pypy/interpreter/executioncontext.py
+++ b/pypy/interpreter/executioncontext.py
@@ -45,6 +45,7 @@
     def gettopframe(self):
         return self.topframeref()
 
+    @jit.unroll_safe
     def gettopframe_nohidden(self):
         frame = self.topframeref()
         while frame and frame.hide():
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
@@ -60,7 +60,6 @@
     def __init__(self, space):
         "NOT_RPYTHON"
         AsyncAction.__init__(self, space)
-        self.handlers_w = {}
         self.pending_signal = -1
         self.fire_in_main_thread = False
         if self.space.config.objspace.usemodules.thread:
@@ -91,7 +90,7 @@
                 # If we are in the main thread, report the signal now,
                 # and poll more
                 self.pending_signal = -1
-                self._report_signal(n)
+                report_signal(self.space, n)
                 n = self.pending_signal
                 if n < 0: n = pypysig_poll()
             else:
@@ -110,20 +109,31 @@
             pypysig_pushback(cpy_signal.SIGINT)
         self.fire_in_main_thread = True
 
-    def _report_signal(self, n):
-        try:
-            w_handler = self.handlers_w[n]
-        except KeyError:
-            return    # no handler, ignore signal
-        space = self.space
-        if not space.is_true(space.callable(w_handler)):
-            return    # w_handler is SIG_IGN or SIG_DFL?
-        # re-install signal handler, for OSes that clear it
-        pypysig_reinstall(n)
-        # invoke the app-level handler
-        ec = space.getexecutioncontext()
-        w_frame = space.wrap(ec.gettopframe_nohidden())
-        space.call_function(w_handler, space.wrap(n), w_frame)
+# ____________________________________________________________
+
+
+class Handlers:
+    def __init__(self, space):
+        self.handlers_w = {}
+
+def _get_handlers(space):
+    return space.fromcache(Handlers).handlers_w
+
+
+def report_signal(space, n):
+    handlers_w = _get_handlers(space)
+    try:
+        w_handler = handlers_w[n]
+    except KeyError:
+        return    # no handler, ignore signal
+    if not space.is_true(space.callable(w_handler)):
+        return    # w_handler is SIG_IGN or SIG_DFL?
+    # re-install signal handler, for OSes that clear it
+    pypysig_reinstall(n)
+    # invoke the app-level handler
+    ec = space.getexecutioncontext()
+    w_frame = space.wrap(ec.gettopframe_nohidden())
+    space.call_function(w_handler, space.wrap(n), w_frame)
 
 
 @unwrap_spec(signum=int)
@@ -141,9 +151,9 @@
         check_signum_exists(space, signum)
     else:
         check_signum_in_range(space, signum)
-    action = space.check_signal_action
-    if signum in action.handlers_w:
-        return action.handlers_w[signum]
+    handlers_w = _get_handlers(space)
+    if signum in handlers_w:
+        return handlers_w[signum]
     return space.wrap(SIG_DFL)
 
 
@@ -204,7 +214,6 @@
                                         "main thread"))
     old_handler = getsignal(space, signum)
 
-    action = space.check_signal_action
     if space.eq_w(w_handler, space.wrap(SIG_DFL)):
         pypysig_default(signum)
     elif space.eq_w(w_handler, space.wrap(SIG_IGN)):
@@ -215,7 +224,8 @@
                                  space.wrap("'handler' must be a callable "
                                             "or SIG_DFL or SIG_IGN"))
         pypysig_setflag(signum)
-    action.handlers_w[signum] = w_handler
+    handlers_w = _get_handlers(space)
+    handlers_w[signum] = w_handler
     return old_handler
 
 
diff --git a/rpython/translator/c/src/profiling.c b/rpython/translator/c/src/profiling.c
--- a/rpython/translator/c/src/profiling.c
+++ b/rpython/translator/c/src/profiling.c
@@ -8,8 +8,8 @@
 #include <sched.h>
 #endif
 
-cpu_set_t base_cpu_set;
-int profiling_setup = 0;
+static cpu_set_t base_cpu_set;
+static int profiling_setup = 0;
 
 void pypy_setup_profiling()
 {
@@ -37,8 +37,8 @@
 
 #include <windows.h>
 
-DWORD_PTR base_affinity_mask;
-int profiling_setup = 0;
+static DWORD_PTR base_affinity_mask;
+static int profiling_setup = 0;
 
 void pypy_setup_profiling() { 
     if (!profiling_setup) {
diff --git a/rpython/translator/platform/__init__.py b/rpython/translator/platform/__init__.py
--- a/rpython/translator/platform/__init__.py
+++ b/rpython/translator/platform/__init__.py
@@ -53,9 +53,18 @@
         ofiles = self._compile_o_files(cfiles, eci, standalone)
         return self._finish_linking(ofiles, eci, outputfilename, standalone)
 
+    def _all_cfiles(self, cfiles, eci):
+        seen = set()
+        result = []
+        for cfile in list(cfiles) + list(eci.separate_module_files):
+            cfile = py.path.local(cfile)
+            if cfile not in seen:
+                seen.add(cfile)
+                result.append(cfile)
+        return result
+
     def _compile_o_files(self, cfiles, eci, standalone=True):
-        cfiles = [py.path.local(f) for f in cfiles]
-        cfiles += [py.path.local(f) for f in eci.separate_module_files]
+        cfiles = self._all_cfiles(cfiles, eci)
         compile_args = self._compile_args_from_eci(eci, standalone)
         ofiles = []
         for cfile in cfiles:
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
@@ -84,8 +84,7 @@
 
     def gen_makefile(self, cfiles, eci, exe_name=None, path=None,
                      shared=False):
-        cfiles = [py.path.local(f) for f in cfiles]
-        cfiles += [py.path.local(f) for f in eci.separate_module_files]
+        cfiles = self._all_cfiles(cfiles, eci)
 
         if path is None:
             path = cfiles[0].dirpath()
diff --git a/rpython/translator/platform/windows.py b/rpython/translator/platform/windows.py
--- a/rpython/translator/platform/windows.py
+++ b/rpython/translator/platform/windows.py
@@ -248,8 +248,7 @@
 
     def gen_makefile(self, cfiles, eci, exe_name=None, path=None,
                      shared=False):
-        cfiles = [py.path.local(f) for f in cfiles]
-        cfiles += [py.path.local(f) for f in eci.separate_module_files]
+        cfiles = self._all_cfiles(cfiles, eci)
 
         if path is None:
             path = cfiles[0].dirpath()


More information about the pypy-commit mailing list