[PATCH] check-code: catch Python 'is' comparing number or string literals

Adrian Buehlmann adrian at cadifra.com
Sun Nov 21 05:18:26 CST 2010


# HG changeset patch
# User Adrian Buehlmann <adrian at cadifra.com>
# Date 1290336747 -3600
# Node ID 4a8e6496931b78b4e4db8d51b019c751e1a27d2a
# Parent  42ac864ed3946df2a3b7b87dcbc05cd4d35a62c3
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.

diff --git a/contrib/check-code.py b/contrib/check-code.py
--- a/contrib/check-code.py
+++ b/contrib/check-code.py
@@ -149,6 +149,7 @@ pypats = [
     (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 = [
diff --git a/tests/test-check-code.t b/tests/test-check-code.t
--- a/tests/test-check-code.t
+++ b/tests/test-check-code.t
@@ -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]
+


More information about the Mercurial-devel mailing list