Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: third_party/pylint/checkers/stdlib.py

Issue 876793002: pylint: upgrade to 1.4.1 (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/pylint/checkers/spelling.py ('k') | third_party/pylint/checkers/typecheck.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2012 Google Inc. 1 # Copyright 2012 Google Inc.
2 # 2 #
3 # http://www.logilab.fr/ -- mailto:contact@logilab.fr 3 # http://www.logilab.fr/ -- mailto:contact@logilab.fr
4 # This program is free software; you can redistribute it and/or modify it under 4 # This program is free software; you can redistribute it and/or modify it under
5 # the terms of the GNU General Public License as published by the Free Software 5 # the terms of the GNU General Public License as published by the Free Software
6 # Foundation; either version 2 of the License, or (at your option) any later 6 # Foundation; either version 2 of the License, or (at your option) any later
7 # version. 7 # version.
8 # 8 #
9 # This program is distributed in the hope that it will be useful, but WITHOUT 9 # This program is distributed in the hope that it will be useful, but WITHOUT
10 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details 11 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
12 # 12 #
13 # You should have received a copy of the GNU General Public License along with 13 # You should have received a copy of the GNU General Public License along with
14 # this program; if not, write to the Free Software Foundation, Inc., 14 # this program; if not, write to the Free Software Foundation, Inc.,
15 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 15 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 """Checkers for various standard library functions.""" 16 """Checkers for various standard library functions."""
17 17
18 import re 18 import re
19 import six
19 import sys 20 import sys
20 21
21 import astroid 22 import astroid
22 from astroid.bases import Instance 23 from astroid.bases import Instance
23 24
24 from pylint.interfaces import IAstroidChecker 25 from pylint.interfaces import IAstroidChecker
25 from pylint.checkers import BaseChecker 26 from pylint.checkers import BaseChecker
26 from pylint.checkers import utils 27 from pylint.checkers import utils
27 28
28 _VALID_OPEN_MODE_REGEX = re.compile(r'^(r?U|[rwa]\+?b?)$')
29 29
30 if sys.version_info >= (3, 0): 30 if sys.version_info >= (3, 0):
31 OPEN_MODULE = '_io' 31 OPEN_MODULE = '_io'
32 else: 32 else:
33 OPEN_MODULE = '__builtin__' 33 OPEN_MODULE = '__builtin__'
34 34
35
36 def _check_mode_str(mode):
37 # check type
38 if not isinstance(mode, six.string_types):
39 return False
40 # check syntax
41 modes = set(mode)
42 _mode = "rwatb+U"
43 creating = False
44 if six.PY3:
45 _mode += "x"
46 creating = "x" in modes
47 if modes - set(_mode) or len(mode) > len(modes):
48 return False
49 # check logic
50 reading = "r" in modes
51 writing = "w" in modes
52 appending = "a" in modes
53 updating = "+" in modes
54 text = "t" in modes
55 binary = "b" in modes
56 if "U" in modes:
57 if writing or appending or creating and six.PY3:
58 return False
59 reading = True
60 if not six.PY3:
61 binary = True
62 if text and binary:
63 return False
64 total = reading + writing + appending + (creating if six.PY3 else 0)
65 if total > 1:
66 return False
67 if not (reading or writing or appending or creating and six.PY3):
68 return False
69 # other 2.x constraints
70 if not six.PY3:
71 if "U" in mode:
72 mode = mode.replace("U", "")
73 if "r" not in mode:
74 mode = "r" + mode
75 return mode[0] in ("r", "w", "a", "U")
76 return True
77
78
35 class StdlibChecker(BaseChecker): 79 class StdlibChecker(BaseChecker):
36 __implements__ = (IAstroidChecker,) 80 __implements__ = (IAstroidChecker,)
37 name = 'stdlib' 81 name = 'stdlib'
38 82
39 msgs = { 83 msgs = {
40 'W1501': ('"%s" is not a valid mode for open.', 84 'W1501': ('"%s" is not a valid mode for open.',
41 'bad-open-mode', 85 'bad-open-mode',
42 'Python supports: r, w, a modes with b, +, and U options. ' 86 'Python supports: r, w, a[, x] modes with b, +, '
87 'and U (only with r) options. '
43 'See http://docs.python.org/2/library/functions.html#open'), 88 'See http://docs.python.org/2/library/functions.html#open'),
44 'W1502': ('Using datetime.time in a boolean context.', 89 'W1502': ('Using datetime.time in a boolean context.',
45 'boolean-datetime', 90 'boolean-datetime',
46 'Using datetetime.time in a boolean context can hide ' 91 'Using datetetime.time in a boolean context can hide '
47 'subtle bugs when the time they represent matches ' 92 'subtle bugs when the time they represent matches '
48 'midnight UTC. This behaviour was fixed in Python 3.5. ' 93 'midnight UTC. This behaviour was fixed in Python 3.5. '
49 'See http://bugs.python.org/issue13936 for reference.', 94 'See http://bugs.python.org/issue13936 for reference.',
50 {'maxversion': (3, 5)}), 95 {'maxversion': (3, 5)}),
51 } 96 'W1503': ('Redundant use of %s with constant '
97 'value %r',
98 'redundant-unittest-assert',
99 'The first argument of assertTrue and assertFalse is'
100 'a condition. If a constant is passed as parameter, that'
101 'condition will be always true. In this case a warning '
102 'should be emitted.')
103 }
52 104
53 @utils.check_messages('bad-open-mode') 105 @utils.check_messages('bad-open-mode', 'redundant-unittest-assert')
54 def visit_callfunc(self, node): 106 def visit_callfunc(self, node):
55 """Visit a CallFunc node.""" 107 """Visit a CallFunc node."""
56 if hasattr(node, 'func'): 108 if hasattr(node, 'func'):
57 infer = utils.safe_infer(node.func) 109 infer = utils.safe_infer(node.func)
58 if infer and infer.root().name == OPEN_MODULE: 110 if infer:
59 if getattr(node.func, 'name', None) in ('open', 'file'): 111 if infer.root().name == OPEN_MODULE:
60 self._check_open_mode(node) 112 if getattr(node.func, 'name', None) in ('open', 'file'):
113 self._check_open_mode(node)
114 if infer.root().name == 'unittest.case':
115 self._check_redundant_assert(node, infer)
61 116
62 @utils.check_messages('boolean-datetime') 117 @utils.check_messages('boolean-datetime')
63 def visit_unaryop(self, node): 118 def visit_unaryop(self, node):
64 if node.op == 'not': 119 if node.op == 'not':
65 self._check_datetime(node.operand) 120 self._check_datetime(node.operand)
66 121
67 @utils.check_messages('boolean-datetime') 122 @utils.check_messages('boolean-datetime')
68 def visit_if(self, node): 123 def visit_if(self, node):
69 self._check_datetime(node.test) 124 self._check_datetime(node.test)
70 125
71 @utils.check_messages('boolean-datetime') 126 @utils.check_messages('boolean-datetime')
72 def visit_ifexp(self, node): 127 def visit_ifexp(self, node):
73 self._check_datetime(node.test) 128 self._check_datetime(node.test)
74 129
75 @utils.check_messages('boolean-datetime') 130 @utils.check_messages('boolean-datetime')
76 def visit_boolop(self, node): 131 def visit_boolop(self, node):
77 for value in node.values: 132 for value in node.values:
78 self._check_datetime(value) 133 self._check_datetime(value)
79 134
135 def _check_redundant_assert(self, node, infer):
136 if (isinstance(infer, astroid.BoundMethod) and
137 node.args and isinstance(node.args[0], astroid.Const) and
138 infer.name in ['assertTrue', 'assertFalse']):
139 self.add_message('redundant-unittest-assert',
140 args=(infer.name, node.args[0].value, ),
141 node=node)
142
80 def _check_datetime(self, node): 143 def _check_datetime(self, node):
81 """ Check that a datetime was infered. 144 """ Check that a datetime was infered.
82 If so, emit boolean-datetime warning. 145 If so, emit boolean-datetime warning.
83 """ 146 """
84 try: 147 try:
85 infered = next(node.infer()) 148 infered = next(node.infer())
86 except astroid.InferenceError: 149 except astroid.InferenceError:
87 return 150 return
88 if (isinstance(infered, Instance) and 151 if (isinstance(infered, Instance) and
89 infered.qname() == 'datetime.time'): 152 infered.qname() == 'datetime.time'):
90 self.add_message('boolean-datetime', node=node) 153 self.add_message('boolean-datetime', node=node)
91 154
155
92 def _check_open_mode(self, node): 156 def _check_open_mode(self, node):
93 """Check that the mode argument of an open or file call is valid.""" 157 """Check that the mode argument of an open or file call is valid."""
94 try: 158 try:
95 mode_arg = utils.get_argument_from_call(node, position=1, keyword='m ode') 159 mode_arg = utils.get_argument_from_call(node, position=1,
96 if mode_arg: 160 keyword='mode')
97 mode_arg = utils.safe_infer(mode_arg) 161 except utils.NoSuchArgumentError:
98 if (isinstance(mode_arg, astroid.Const) 162 return
99 and not _VALID_OPEN_MODE_REGEX.match(mode_arg.value)): 163 if mode_arg:
100 self.add_message('bad-open-mode', node=node, 164 mode_arg = utils.safe_infer(mode_arg)
101 args=(mode_arg.value)) 165 if (isinstance(mode_arg, astroid.Const)
102 except (utils.NoSuchArgumentError, TypeError): 166 and not _check_mode_str(mode_arg.value)):
103 pass 167 self.add_message('bad-open-mode', node=node,
168 args=mode_arg.value)
169
104 170
105 def register(linter): 171 def register(linter):
106 """required method to auto register this checker """ 172 """required method to auto register this checker """
107 linter.register_checker(StdlibChecker(linter)) 173 linter.register_checker(StdlibChecker(linter))
108
OLDNEW
« no previous file with comments | « third_party/pylint/checkers/spelling.py ('k') | third_party/pylint/checkers/typecheck.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698