check-code: catch Python 'is' comparing number or string literals
authorAdrian Buehlmann <adrian@cadifra.com>
Sun, 21 Nov 2010 11:52:27 +0100
changeset 13026 53391819f195
parent 13024 da69a1597285
child 13027 7f2ecb64140d
check-code: catch Python 'is' comparing number or string literals The Python 'is' operator compares object identity, so it should definitely not be applied to string or number literals, which Python implementations are free to represent with a temporary object. This should catch the following kinds of bogus expressions (examples): x is 'foo' x is not 'foo' x is "bar" x is not "bar" x is 42 x is not 42 x is -36 x is not -36 As originally proposed by Martin Geisler, amended with catching negative numbers.
contrib/check-code.py
tests/test-check-code.t
--- a/contrib/check-code.py	Sun Nov 21 13:16:59 2010 +0100
+++ b/contrib/check-code.py	Sun Nov 21 11:52:27 2010 +0100
@@ -149,6 +149,7 @@
     (r'raise Exception', "don't raise generic exceptions"),
     (r'ui\.(status|progress|write|note|warn)\([\'\"]x',
      "warning: unwrapped ui message"),
+    (r' is\s+(not\s+)?["\'0-9-]', "object comparison with literal"),
 ]
 
 pyfilters = [
--- a/tests/test-check-code.t	Sun Nov 21 13:16:59 2010 +0100
+++ b/tests/test-check-code.t	Sun Nov 21 11:52:27 2010 +0100
@@ -52,3 +52,44 @@
    >     y = format(x)
    any/all/format not available in Python 2.4
   [1]
+
+  $ cat > is-op.py <<EOF
+  > # is-operator comparing number or string literal
+  > x = None
+  > y = x is 'foo'
+  > y = x is "foo"
+  > y = x is 5346
+  > y = x is -6
+  > y = x is not 'foo'
+  > y = x is not "foo"
+  > y = x is not 5346
+  > y = x is not -6
+  > EOF
+
+  $ "$check_code" ./is-op.py
+  ./is-op.py:3:
+   > y = x is 'foo'
+   object comparison with literal
+  ./is-op.py:4:
+   > y = x is "foo"
+   object comparison with literal
+  ./is-op.py:5:
+   > y = x is 5346
+   object comparison with literal
+  ./is-op.py:6:
+   > y = x is -6
+   object comparison with literal
+  ./is-op.py:7:
+   > y = x is not 'foo'
+   object comparison with literal
+  ./is-op.py:8:
+   > y = x is not "foo"
+   object comparison with literal
+  ./is-op.py:9:
+   > y = x is not 5346
+   object comparison with literal
+  ./is-op.py:10:
+   > y = x is not -6
+   object comparison with literal
+  [1]
+