From 592eb6da9c47d655448bc3f5284c094bc68a45d4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Piotr=20O=C5=BCarowski?= <piotr@debian.org>
Date: Sun, 25 Jul 2010 12:11:49 +0200
Subject: [PATCH] pycompile: do not exit before all background byte compilation
 is finished (closes: 590224)

---
 debian/changelog     |  2 ++
 debpython/depends.py |  2 +-
 pyclean              | 22 +++++++---------------
 pycompile            | 25 +++++++++++++++----------
 4 files changed, 25 insertions(+), 26 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index e483046..a8f05a0 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -4,6 +4,8 @@ python-defaults (2.6.5-10) UNRELEASED; urgency=low
     - add --depend command line option (use it if requires.txt
       doesn't contain dependency that package needs)
     - add {/usr,}/sbin to the list of directories with checked shebangs
+  * pycompile: do not exit before all background byte compilation is finished
+    (closes: 590224)
 
  -- Piotr Ożarowski <piotr@debian.org>  Wed, 21 Jul 2010 21:10:19 +0200
 
diff --git a/debpython/depends.py b/debpython/depends.py
index 87d4c77..4505ff9 100644
--- a/debpython/depends.py
+++ b/debpython/depends.py
@@ -119,7 +119,7 @@ class Dependencies(object):
 
         # make sure pycompile binary is available
         if stats['compile']:
-            self.depend("python (>= 2.6.5-9~)")
+            self.depend("python (>= 2.6.5-10~)")
 
         for interpreter, version in stats['shebangs']:
             self.depend(interpreter)
diff --git a/pyclean b/pyclean
index 72dbd5a..3995ee0 100755
--- a/pyclean
+++ b/pyclean
@@ -33,7 +33,7 @@ from subprocess import Popen, PIPE
 # initialize script
 logging.basicConfig(format='%(levelname).1s: %(module)s:%(lineno)d: '
                            '%(message)s')
-log = logging.getLogger('pyclean')
+log = logging.getLogger(__name__)
 
 """TODO: move it to manpage
 Examples:
@@ -43,12 +43,7 @@ Examples:
 
 
 def destroyer():  # ;-)
-    """Removes every .py[co] file associated to received .py file.
-
-    :param magic_tags: if True, removes __pycache__ directories,
-        if None, removes .py[co] files (PEP 3147 mode turned off),
-        otherwise removes set of magic tags from __pycache__ directory
-    """
+    """Removes every .py[co] file associated to received .py file."""
 
     def find_files_to_remove(pyfile):
         for filename in ("%sc" % pyfile, "%so" % pyfile):
@@ -61,14 +56,14 @@ def destroyer():  # ;-)
             pyfile = (yield)
             for filename in find_files_to_remove(pyfile):
                 try:
+                    log.debug('removing %s', filename)
                     remove(filename)
                     counter += 1
                 except (IOError, OSError), e:
                     log.error('cannot remove %s', filename)
                     log.debug(e)
     except GeneratorExit:
-        if counter:
-            log.info("removed files: %s", counter)
+        log.info("removed files: %s", counter)
 
 
 def get_files(items):
@@ -108,16 +103,13 @@ def main():
 
     (options, args) = parser.parse_args()
 
-    if options.verbose:
-        log.setLevel(logging.INFO)
-    else:
-        log.setLevel(logging.WARNING)
-
-    if environ.get('PYCLEAN_DEBUG') == '1':
+    if options.verbose or environ.get('PYCLEAN_DEBUG') == '1':
         log.setLevel(logging.DEBUG)
         log.debug('argv: %s', sys.argv)
         log.debug('options: %s', options)
         log.debug('args: %s', args)
+    else:
+        log.setLevel(logging.WARNING)
 
     d = destroyer()
     d.next()  # initialize coroutine
diff --git a/pycompile b/pycompile
index 976aa28..6ad8ec3 100755
--- a/pycompile
+++ b/pycompile
@@ -38,8 +38,9 @@ from debpython.tools import memoize
 # initialize script
 logging.basicConfig(format='%(levelname).1s: %(module)s:%(lineno)d: '
                            '%(message)s')
-log = logging.getLogger('pycompile')
+log = logging.getLogger(__name__)
 STDINS = {}
+WORKERS = {}
 
 """TODO: move it to manpage
 Examples:
@@ -158,22 +159,24 @@ def filter_files(files, e_patterns, compile_versions):
 
 
 ### COMPILE ####################################################
-def py_compile(version):
+def py_compile(version, workers):
     if not isinstance(version, basestring):
         version = vrepr(version)
     cmd = "python%s -m py_compile -" % version
-    stdin = Popen(cmd, bufsize=1, shell=True, stdin=PIPE).stdin
+    process = Popen(cmd, bufsize=1, shell=True, stdin=PIPE)
+    workers[version] = process  # keep the reference for .communicate()
+    stdin = process.stdin
     while True:
         filename = (yield)
         stdin.write(filename + '\n')
 
 
 def compile(files, versions, e_patterns=None):
-    global STDINS
+    global STDINS, WORKERS
     # start Python interpreters that will handle byte compilation
     for version in versions:
         if version not in STDINS:
-            coroutine = py_compile(version)
+            coroutine = py_compile(version, WORKERS)
             coroutine.next()
             STDINS[version] = coroutine
 
@@ -213,15 +216,13 @@ multiple times to build up a list of things to exclude.')
 
     (options, args) = parser.parse_args()
 
-    if options.verbose:
-        log.setLevel(logging.INFO)
-    else:
-        log.setLevel(logging.WARN)
-    if environ.get('PYCOMPILE_DEBUG') == '1':
+    if options.verbose or environ.get('PYCOMPILE_DEBUG') == '1':
         log.setLevel(logging.DEBUG)
         log.debug('argv: %s', sys.argv)
         log.debug('options: %s', options)
         log.debug('args: %s', args)
+    else:
+        log.setLevel(logging.WARN)
 
     if options.regexpr and not args:
         parser.error('--exclude option works with private directories '
@@ -266,5 +267,9 @@ multiple times to build up a list of things to exclude.')
         parser.print_usage()
         exit(1)
 
+    # wait for all processes to finish
+    for process in WORKERS.itervalues():
+        process.communicate()
+
 if __name__ == '__main__':
     main()
-- 
GitLab