[Python-checkins] r87499 - in python/branches/release31-maint: Lib/site.py Lib/test/test_site.py Misc/NEWS

r.david.murray python-checkins at python.org
Sun Dec 26 23:24:55 CET 2010


Author: r.david.murray
Date: Sun Dec 26 23:24:54 2010
New Revision: 87499

Log:
Merged revisions 87497 via svnmerge from 
svn+ssh://pythondev@svn.python.org/python/branches/py3k

........
  r87497 | r.david.murray | 2010-12-26 14:54:29 -0500 (Sun, 26 Dec 2010) | 7 lines
  
  ##5258/#10642: print fn, line, traceback and continue when .pth file is broken
  
  Previously site.py would end with a traceback and not complete the
  initialization of site-packages, but the interpreter would start.
  now site.py does as much initialization as it can, while reporting
  more useful information to help debug the problem in the .pth file.
........


Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/Lib/site.py
   python/branches/release31-maint/Lib/test/test_site.py
   python/branches/release31-maint/Misc/NEWS

Modified: python/branches/release31-maint/Lib/site.py
==============================================================================
--- python/branches/release31-maint/Lib/site.py	(original)
+++ python/branches/release31-maint/Lib/site.py	Sun Dec 26 23:24:54 2010
@@ -55,6 +55,7 @@
 import sys
 import os
 import builtins
+import traceback
 
 # Prefixes for site-packages; add additional prefixes like /usr/local here
 PREFIXES = [sys.prefix, sys.exec_prefix]
@@ -146,17 +147,26 @@
     except IOError:
         return
     with f:
-        for line in f:
+        for n, line in enumerate(f):
             if line.startswith("#"):
                 continue
-            if line.startswith(("import ", "import\t")):
-                exec(line)
-                continue
-            line = line.rstrip()
-            dir, dircase = makepath(sitedir, line)
-            if not dircase in known_paths and os.path.exists(dir):
-                sys.path.append(dir)
-                known_paths.add(dircase)
+            try:
+                if line.startswith(("import ", "import\t")):
+                    exec(line)
+                    continue
+                line = line.rstrip()
+                dir, dircase = makepath(sitedir, line)
+                if not dircase in known_paths and os.path.exists(dir):
+                    sys.path.append(dir)
+                    known_paths.add(dircase)
+            except Exception as err:
+                print("Error processing line {:d} of {}:\n".format(n+1, fullname),
+                      file=sys.stderr)
+                for record in traceback.format_exception(*sys.exc_info()):
+                    for line in record.splitlines():
+                        print('  '+line, file=sys.stderr)
+                print("\nRemainder of file ignored", file=sys.stderr)
+                break
     if reset:
         known_paths = None
     return known_paths

Modified: python/branches/release31-maint/Lib/test/test_site.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_site.py	(original)
+++ python/branches/release31-maint/Lib/test/test_site.py	Sun Dec 26 23:24:54 2010
@@ -6,6 +6,7 @@
 """
 import unittest
 from test.support import run_unittest, TESTFN, EnvironmentVarGuard
+from test.support import captured_output
 import builtins
 import os
 import sys
@@ -83,6 +84,53 @@
         finally:
             pth_file.cleanup()
 
+    def make_pth(self, contents, pth_dir='.', pth_name=TESTFN):
+        # Create a .pth file and return its (abspath, basename).
+        pth_dir = os.path.abspath(pth_dir)
+        pth_basename = pth_name + '.pth'
+        pth_fn = os.path.join(pth_dir, pth_basename)
+        pth_file = open(pth_fn, 'w', encoding='utf-8')
+        self.addCleanup(lambda: os.remove(pth_fn))
+        pth_file.write(contents)
+        pth_file.close()
+        return pth_dir, pth_basename
+
+    def test_addpackage_import_bad_syntax(self):
+        # Issue 10642
+        pth_dir, pth_fn = self.make_pth("import bad)syntax\n")
+        with captured_output("stderr") as err_out:
+            site.addpackage(pth_dir, pth_fn, set())
+        self.assertRegexpMatches(err_out.getvalue(), "line 1")
+        self.assertRegexpMatches(err_out.getvalue(), os.path.join(pth_dir, pth_fn))
+        # XXX: the previous two should be independent checks so that the
+        # order doesn't matter.  The next three could be a single check
+        # but my regex foo isn't good enough to write it.
+        self.assertRegexpMatches(err_out.getvalue(), 'Traceback')
+        self.assertRegexpMatches(err_out.getvalue(), r'import bad\)syntax')
+        self.assertRegexpMatches(err_out.getvalue(), 'SyntaxError')
+
+    def test_addpackage_import_bad_exec(self):
+        # Issue 10642
+        pth_dir, pth_fn = self.make_pth("randompath\nimport nosuchmodule\n")
+        with captured_output("stderr") as err_out:
+            site.addpackage(pth_dir, pth_fn, set())
+        self.assertRegexpMatches(err_out.getvalue(), "line 2")
+        self.assertRegexpMatches(err_out.getvalue(), os.path.join(pth_dir, pth_fn))
+        # XXX: ditto previous XXX comment.
+        self.assertRegexpMatches(err_out.getvalue(), 'Traceback')
+        self.assertRegexpMatches(err_out.getvalue(), 'ImportError')
+
+    def test_addpackage_import_bad_pth_file(self):
+        # Issue 5258
+        pth_dir, pth_fn = self.make_pth("abc\x00def\n")
+        with captured_output("stderr") as err_out:
+            site.addpackage(pth_dir, pth_fn, set())
+        self.assertRegexpMatches(err_out.getvalue(), "line 1")
+        self.assertRegexpMatches(err_out.getvalue(), os.path.join(pth_dir, pth_fn))
+        # XXX: ditto previous XXX comment.
+        self.assertRegexpMatches(err_out.getvalue(), 'Traceback')
+        self.assertRegexpMatches(err_out.getvalue(), 'TypeError')
+
     def test_addsitedir(self):
         # Same tests for test_addpackage since addsitedir() essentially just
         # calls addpackage() for every .pth file in the directory

Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS	(original)
+++ python/branches/release31-maint/Misc/NEWS	Sun Dec 26 23:24:54 2010
@@ -24,6 +24,10 @@
 Library
 -------
 
+- Issue #5258/#10642: if site.py encounters a .pth file that generates an error,
+  it now prints the filename, line number, and traceback to stderr and skips
+  the rest of that individual file, instead of stopping processing entirely.
+
 - Issue #4871: The zipfile module now gives a more useful error message if
   an attempt is made to use a string to specify the archive password.
 


More information about the Python-checkins mailing list