check-code: disallow use of hasattr()
authorAugie Fackler <durin42@gmail.com>
Mon, 25 Jul 2011 14:59:31 -0500
changeset 14978 5a0fdc715769
parent 14977 1dbd42a02153
child 14979 a5046880eca3
check-code: disallow use of hasattr() The hasattr() builtin from Python < 3.2 [1] has slightly surprising behavior: it catches all exceptions, even KeyboardInterrupt. This causes it to have several surprising side effects, such as hiding warnings that occur during attribute load and causing mysterious failure modes when ^Cing an application. In later versions of Python 2.x [0], exception classes which do not inherit from Exception (such as SystemExit and KeyboardInterrupt) are not caught, but other types of exceptions may still silently cause returning False instead of getting a reasonable exception. [0] http://bugs.python.org/issue2196 [1] http://docs.python.org/dev/whatsnew/3.2.html
contrib/check-code.py
--- a/contrib/check-code.py	Mon Jul 25 21:15:48 2011 -0500
+++ b/contrib/check-code.py	Mon Jul 25 14:59:31 2011 -0500
@@ -148,7 +148,7 @@
     (r'(?<!def)\s+(any|all|format)\(',
      "any/all/format not available in Python 2.4"),
     (r'(?<!def)\s+(callable)\(',
-     "callable not available in Python 3, use hasattr(f, '__call__')"),
+     "callable not available in Python 3, use getattr(f, '__call__', None)"),
     (r'if\s.*\selse', "if ... else form not available in Python 2.4"),
     (r'^\s*(%s)\s\s' % '|'.join(keyword.kwlist),
      "gratuitous whitespace after Python keyword"),
@@ -168,6 +168,8 @@
      "comparison with singleton, use 'is' or 'is not' instead"),
     (r'^\s*(while|if) [01]:',
      "use True/False for constant Boolean expression"),
+    (r'(?<!def)\s+hasattr',
+     'hasattr(foo, bar) is broken, use util.safehasattr(foo, bar) instead'),
     (r'opener\([^)]*\).read\(',
      "use opener.read() instead"),
     (r'opener\([^)]*\).write\(',