Emit a warning if __all__ contains non-string objects.

Closes #112728

authortmarek@google.com
changesetcf3e66c40cd8
branchdefault
phasepublic
hiddenno
parent revision#2c9220f1ee1c backport stable
child revision#221bbad0f277 Two small fixes for suppression warnings I00{2,1}:
files modified by this revision
ChangeLog
checkers/variables.py
test/input/func_e0604.py
test/input/func_more_e0604.py
test/messages/func_e0604.txt
test/messages/func_more_e0604.txt
# HG changeset patch
# User tmarek@google.com
# Date 1357669822 -3600
# Tue Jan 08 19:30:22 2013 +0100
# Node ID cf3e66c40cd8e901ce44f06b3f2e03d532869f7b
# Parent 2c9220f1ee1c68de593fd0de2bcb40dd82d99481
Emit a warning if __all__ contains non-string objects.

Closes #112728

diff --git a/ChangeLog b/ChangeLog
@@ -1,27 +1,30 @@
1  ChangeLog for PyLint
2  ====================
3 
4  --
5 
6 +    * Changed the regular expression for inline options so that it must be
7 +      preceeded by a # (patch by Torsten Marek)
8 +
9 +    * Make dot output for import graph predictable and not depend
10 +      on ordering of strings in hashes. (patch by Torsten Marek)
11 +
12 +    * Add hooks for import path setup and move pylint's sys.path
13 +      modifications into them. (patch by Torsten Marek)
14 +
15      * #20693: replace pylint.el by Ian Eure version (patch by J.Kotta)
16 
17      * #105327: add support for --disable=all option and deprecate the
18        'disable-all' inline directive in favour of 'skip-file' (patch by
19        A.Fayolle)
20 
21      * #110840: Add messages I0020 and I0021 for reporting of suppressed messages
22        and useless suppression pragmas. (patch by Torsten Marek)
23 
24 -    * Changed the regular expression for inline options so that it must be
25 -      preceeded by a # (patch by Torsten Marek)
26 -
27 -    * Make dot output for import graph predictable and not depend
28 -      on ordering of strings in hashes. (patch by Torsten Marek)
29 -
30 -    * Add hooks for import path setup and move pylint's sys.path
31 -      modifications into them. (patch by Torsten Marek)
32 +    * #112728: Add warning E0604 for non-string objects in __all__
33 +      (patch by Torsten Marek)
34 
35  --
36      * #115580: fix erroneous W0212 (access to protected member) on super call
37        (patch by Martin Pool)
38 
diff --git a/checkers/variables.py b/checkers/variables.py
@@ -61,10 +61,13 @@
39                'undefined-variable',
40                'Used when an undefined variable is accessed.'),
41      'E0603': ('Undefined variable name %r in __all__',
42                'undefined-all-variable',
43                'Used when an undefined variable name is referenced in __all__.'),
44 +    'E0604': ('Invalid object %r in __all__, must contain only strings',
45 +              'invalid-all-object',
46 +              'Used when an invalid (non-string) object occurs in __all__.'),
47      'E0611': ('No name %r in module %r',
48                'no-name-in-module',
49                'Used when a name cannot be found in a module.'),
50 
51      'W0601': ('Global variable %r undefined at the module level',
@@ -177,11 +180,12 @@
52                      try:
53                          elt_name = elt.infer().next()
54                      except astng.InferenceError:
55                          continue
56 
57 -                    if not isinstance(elt_name, astng.Const):
58 +                    if not isinstance(elt_name, astng.Const) or not isinstance(elt_name.value, basestring):
59 +                        self.add_message('E0604', args=elt.as_string(), node=elt)
60                          continue
61                      elt_name = elt.value
62                      # If elt is in not_consumed, remove it from not_consumed
63                      if elt_name in not_consumed:
64                          del not_consumed[elt_name]
diff --git a/test/input/func_e0604.py b/test/input/func_e0604.py
@@ -0,0 +1,13 @@
65 +"""Test for invalid objects in a module's __all__ variable.
66 +
67 +"""
68 +#  pylint: disable=R0903,R0201,W0612
69 +
70 +__revision__ = 0
71 +
72 +def some_function():
73 +    """Just a function."""
74 +    pass
75 +
76 +
77 +__all__ = [some_function]
diff --git a/test/input/func_more_e0604.py b/test/input/func_more_e0604.py
@@ -0,0 +1,9 @@
78 +"""Test for invalid objects in a module's __all__ variable.
79 +
80 +"""
81 +#  pylint: disable=R0903,R0201,W0612
82 +
83 +__revision__ = 0
84 +
85 +
86 +__all__ = [1]
diff --git a/test/messages/func_e0604.txt b/test/messages/func_e0604.txt
@@ -0,0 +1,1 @@
87 +E: 13: Invalid object 'some_function' in __all__, must contain only strings
diff --git a/test/messages/func_more_e0604.txt b/test/messages/func_more_e0604.txt
@@ -0,0 +1,1 @@
88 +E:  9: Invalid object '1' in __all__, must contain only strings