Patchwork [3,of,3] import-checker: include lineno in warning message

login
register
mail settings
Submitter Yuya Nishihara
Date Nov. 12, 2015, 3:04 p.m.
Message ID <3f0ec1b456ed947b456b.1447340650@mimosa>
Download mbox | patch
Permalink /patch/11374/
State Accepted
Headers show

Comments

Yuya Nishihara - Nov. 12, 2015, 3:04 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1446360366 -32400
#      Sun Nov 01 15:46:06 2015 +0900
# Node ID 3f0ec1b456ed947b456b74f855b39f0ef0de4873
# Parent  d442558ca3c13c854b779fef4184ff09c8cdb6e7
import-checker: include lineno in warning message

This makes it easy to look for imports in function scope.
Pierre-Yves David - Nov. 14, 2015, 1:06 a.m.
On 11/12/2015 07:04 AM, Yuya Nishihara wrote:
> # HG changeset patch
> # User Yuya Nishihara <yuya@tcha.org>
> # Date 1446360366 -32400
> #      Sun Nov 01 15:46:06 2015 +0900
> # Node ID 3f0ec1b456ed947b456b74f855b39f0ef0de4873
> # Parent  d442558ca3c13c854b779fef4184ff09c8cdb6e7
> import-checker: include lineno in warning message

Nice, pushed to the clowncopter. Thanks.

Patch

diff --git a/contrib/import-checker.py b/contrib/import-checker.py
--- a/contrib/import-checker.py
+++ b/contrib/import-checker.py
@@ -356,7 +356,7 @@  def verify_modern_convention(module, roo
 
     for node in ast.walk(root):
         def msg(fmt, *args):
-            return fmt % args
+            return (fmt % args, node.lineno)
         if isinstance(node, ast.Import):
             # Disallow "import foo, bar" and require separate imports
             # for each module.
@@ -464,7 +464,7 @@  def verify_stdlib_on_own_line(root):
     http://bugs.python.org/issue19510.
 
     >>> list(verify_stdlib_on_own_line(ast.parse('import sys, foo')))
-    ['mixed imports\\n   stdlib:    sys\\n   relative:  foo']
+    [('mixed imports\\n   stdlib:    sys\\n   relative:  foo', 1)]
     >>> list(verify_stdlib_on_own_line(ast.parse('import sys, os')))
     []
     >>> list(verify_stdlib_on_own_line(ast.parse('import foo, bar')))
@@ -478,7 +478,7 @@  def verify_stdlib_on_own_line(root):
             if from_stdlib[True] and from_stdlib[False]:
                 yield ('mixed imports\n   stdlib:    %s\n   relative:  %s' %
                        (', '.join(sorted(from_stdlib[True])),
-                        ', '.join(sorted(from_stdlib[False]))))
+                        ', '.join(sorted(from_stdlib[False]))), node.lineno)
 
 class CircularImport(Exception):
     pass
@@ -550,9 +550,9 @@  def main(argv):
         src = f.read()
         used_imports[modname] = sorted(
             imported_modules(src, modname, localmods, ignore_nested=True))
-        for error in verify_import_convention(modname, src):
+        for error, lineno in verify_import_convention(modname, src):
             any_errors = True
-            print source_path, error
+            print '%s:%d: %s' % (source_path, lineno, error)
         f.close()
     cycles = find_cycles(used_imports)
     if cycles:
diff --git a/tests/test-module-imports.t b/tests/test-module-imports.t
--- a/tests/test-module-imports.t
+++ b/tests/test-module-imports.t
@@ -87,20 +87,20 @@  Run additional tests for the import chec
   > EOF
 
   $ python "$import_checker" testpackage/*.py testpackage/subpackage/*.py
-  testpackage/importalias.py ui module must be "as" aliased to uimod
-  testpackage/importfromalias.py ui from testpackage must be "as" aliased to uimod
-  testpackage/importfromrelative.py import should be relative: testpackage.unsorted
-  testpackage/importfromrelative.py direct symbol import from testpackage.unsorted
-  testpackage/latesymbolimport.py symbol import follows non-symbol import: mercurial.node
-  testpackage/multiple.py multiple imported names: os, sys
-  testpackage/multiplegroups.py multiple "from . import" statements
-  testpackage/relativestdlib.py relative import of stdlib module
-  testpackage/requirerelative.py import should be relative: testpackage.unsorted
-  testpackage/sortedentries.py imports from testpackage not lexically sorted: bar < foo
-  testpackage/stdafterlocal.py stdlib import follows local import: os
-  testpackage/subpackage/levelpriority.py higher-level import should come first: testpackage
-  testpackage/symbolimport.py direct symbol import from testpackage.unsorted
-  testpackage/unsorted.py imports not lexically sorted: os < sys
+  testpackage/importalias.py:2: ui module must be "as" aliased to uimod
+  testpackage/importfromalias.py:2: ui from testpackage must be "as" aliased to uimod
+  testpackage/importfromrelative.py:2: import should be relative: testpackage.unsorted
+  testpackage/importfromrelative.py:2: direct symbol import from testpackage.unsorted
+  testpackage/latesymbolimport.py:3: symbol import follows non-symbol import: mercurial.node
+  testpackage/multiple.py:2: multiple imported names: os, sys
+  testpackage/multiplegroups.py:3: multiple "from . import" statements
+  testpackage/relativestdlib.py:2: relative import of stdlib module
+  testpackage/requirerelative.py:2: import should be relative: testpackage.unsorted
+  testpackage/sortedentries.py:2: imports from testpackage not lexically sorted: bar < foo
+  testpackage/stdafterlocal.py:3: stdlib import follows local import: os
+  testpackage/subpackage/levelpriority.py:3: higher-level import should come first: testpackage
+  testpackage/symbolimport.py:2: direct symbol import from testpackage.unsorted
+  testpackage/unsorted.py:3: imports not lexically sorted: os < sys
   [1]
 
   $ cd "$TESTDIR"/..