diff options
author | cpopa <devnull@localhost> | 2014-08-19 17:41:27 +0300 |
---|---|---|
committer | cpopa <devnull@localhost> | 2014-08-19 17:41:27 +0300 |
commit | 70d8a57553d3c2d32fd26e79a86637957b5bbc11 (patch) | |
tree | 5747d9b4e86ff2a0d12bf70f684d1f59a09a2d65 | |
parent | 45fbd61f07d7b689a108632d719717473118c245 (diff) | |
download | pylint-70d8a57553d3c2d32fd26e79a86637957b5bbc11.tar.gz |
Add a new warning, 'boolean-datetime', emitted when an instance of 'datetime.time' is used in a boolean context. Closes issue #239.
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | checkers/stdlib.py | 37 | ||||
-rw-r--r-- | test/functional/boolean_datetime.py | 30 | ||||
-rw-r--r-- | test/functional/boolean_datetime.txt | 8 |
4 files changed, 78 insertions, 0 deletions
@@ -80,6 +80,9 @@ ChangeLog for Pylint * Order of reporting is consistent. + * Add a new warning, 'boolean-datetime', emitted when an instance + of 'datetime.time' is used in a boolean context. Closes issue #239. + 2014-07-26 -- 1.3.0 diff --git a/checkers/stdlib.py b/checkers/stdlib.py index 9913e99..4188429 100644 --- a/checkers/stdlib.py +++ b/checkers/stdlib.py @@ -19,6 +19,7 @@ import re import sys import astroid +from astroid.bases import Instance from pylint.interfaces import IAstroidChecker from pylint.checkers import BaseChecker @@ -40,6 +41,12 @@ class OpenModeChecker(BaseChecker): 'bad-open-mode', 'Python supports: r, w, a modes with b, +, and U options. ' 'See http://docs.python.org/2/library/functions.html#open'), + 'W1502': ('Using datetime.time in a boolean context.', + 'boolean-datetime', + 'Using datetetime.time in a boolean context can hide ' + 'subtle bugs when the time they represent matches ' + 'midnight UTC. This behaviour was fixed in Python 3.5. ' + 'See http://bugs.python.org/issue13936 for reference.'), } @utils.check_messages('bad-open-mode') @@ -51,6 +58,36 @@ class OpenModeChecker(BaseChecker): if getattr(node.func, 'name', None) in ('open', 'file'): self._check_open_mode(node) + @utils.check_messages('boolean-datetime') + def visit_unaryop(self, node): + if node.op == 'not': + self._check_datetime(node.operand) + + @utils.check_messages('boolean-datetime') + def visit_if(self, node): + self._check_datetime(node.test) + + @utils.check_messages('boolean-datetime') + def visit_ifexp(self, node): + self._check_datetime(node.test) + + @utils.check_messages('boolean-datetime') + def visit_boolop(self, node): + for value in node.values: + self._check_datetime(value) + + def _check_datetime(self, node): + """ Check that a datetime was infered. + If so, emit boolean-datetime warning. + """ + try: + infered = next(node.infer()) + except astroid.InferenceError: + return + if (isinstance(infered, Instance) and + infered.qname() == 'datetime.time'): + self.add_message('boolean-datetime', node=node) + def _check_open_mode(self, node): """Check that the mode argument of an open or file call is valid.""" try: diff --git a/test/functional/boolean_datetime.py b/test/functional/boolean_datetime.py new file mode 100644 index 0000000..39a424f --- /dev/null +++ b/test/functional/boolean_datetime.py @@ -0,0 +1,30 @@ +""" Checks for boolean uses of datetime.time. """
+
+import datetime
+
+if datetime.time(0, 0, 0): # [boolean-datetime]
+ print("datetime.time(0,0,0) is not a bug!")
+else:
+ print("datetime.time(0,0,0) is a bug!")
+
+if not datetime.time(0, 0, 1): # [boolean-datetime]
+ print("datetime.time(0,0,1) is not a bug!")
+else:
+ print("datetime.time(0,0,1) is a bug!")
+
+DATA = not datetime.time(0, 0, 0) # [boolean-datetime]
+DATA = True if datetime.time(0, 0, 0) else False # [boolean-datetime]
+DATA = datetime.time(0, 0, 0) or True # [boolean-datetime]
+DATA = datetime.time(0, 0, 0) and True # [boolean-datetime]
+DATA = False or True or datetime.time(0, 0, 0) # [boolean-datetime]
+DATA = False and datetime.time(0, 0, 0) or True # [boolean-datetime]
+
+
+def cant_infer(data):
+ """ Can't infer what data is """
+ hophop = not data
+ troptrop = True if data else False
+ toptop = data or True
+ return hophop, troptrop, toptop
+
+cant_infer(datetime.time(0, 0, 0))
diff --git a/test/functional/boolean_datetime.txt b/test/functional/boolean_datetime.txt new file mode 100644 index 0000000..f3287d4 --- /dev/null +++ b/test/functional/boolean_datetime.txt @@ -0,0 +1,8 @@ +boolean-datetime:5::Using datetime.time in a boolean context. +boolean-datetime:10::Using datetime.time in a boolean context. +boolean-datetime:15::Using datetime.time in a boolean context. +boolean-datetime:16::Using datetime.time in a boolean context. +boolean-datetime:17::Using datetime.time in a boolean context. +boolean-datetime:18::Using datetime.time in a boolean context. +boolean-datetime:19::Using datetime.time in a boolean context. +boolean-datetime:20::Using datetime.time in a boolean context. |