]> granicus.if.org Git - python/commitdiff
Add py3k warnings for code and method inequality comparisons. This should resolve...
authorSteven Bethard <steven.bethard@gmail.com>
Tue, 18 Mar 2008 22:08:20 +0000 (22:08 +0000)
committerSteven Bethard <steven.bethard@gmail.com>
Tue, 18 Mar 2008 22:08:20 +0000 (22:08 +0000)
Lib/test/test_py3kwarn.py
Objects/codeobject.c
Objects/methodobject.c

index 61de7a22bdef1cfaa166a9b62c5e25867e379004..cdb103844972da7aec9e2a537f4f36cd68d290df 100644 (file)
@@ -50,6 +50,35 @@ class TestPy3KWarnings(unittest.TestCase):
         with catch_warning() as w:
             self.assertWarning(cell0 < cell1, w, expected)
 
+    def test_code_inequality_comparisons(self):
+        expected = 'code inequality comparisons not supported in 3.x.'
+        def f(x):
+            pass
+        def g(x):
+            pass
+        with catch_warning() as w:
+            self.assertWarning(f.func_code < g.func_code, w, expected)
+        with catch_warning() as w:
+            self.assertWarning(f.func_code <= g.func_code, w, expected)
+        with catch_warning() as w:
+            self.assertWarning(f.func_code >= g.func_code, w, expected)
+        with catch_warning() as w:
+            self.assertWarning(f.func_code > g.func_code, w, expected)
+
+    def test_builtin_function_or_method_comparisons(self):
+        expected = ('builtin_function_or_method '
+                    'inequality comparisons not supported in 3.x.')
+        func = eval
+        meth = {}.get
+        with catch_warning() as w:
+            self.assertWarning(func < meth, w, expected)
+        with catch_warning() as w:
+            self.assertWarning(func > meth, w, expected)
+        with catch_warning() as w:
+            self.assertWarning(meth <= func, w, expected)
+        with catch_warning() as w:
+            self.assertWarning(meth >= func, w, expected)
+
     def assertWarning(self, _, warning, expected_message):
         self.assertEqual(str(warning.message), expected_message)
 
index e75ab94e10f788a372570689dd4d6ff017a81c53..57cd2e626448f5c45400b8cb48175667411d8b24 100644 (file)
@@ -327,6 +327,72 @@ code_compare(PyCodeObject *co, PyCodeObject *cp)
                return 0;
 }
 
+static PyObject *
+code_richcompare(PyObject *self, PyObject *other, int op)
+{
+       PyCodeObject *co, *cp;
+       int eq;
+       PyObject *res;
+
+       if ((op != Py_EQ && op != Py_NE) ||
+           !PyCode_Check(self) ||
+           !PyCode_Check(other)) {
+
+               /* Py3K warning if types are not equal and comparison isn't == or !=  */
+               if (Py_Py3kWarningFlag && PyErr_Warn(PyExc_DeprecationWarning,
+                               "code inequality comparisons not supported in 3.x.") < 0) {
+                       return NULL;
+               }
+
+               Py_INCREF(Py_NotImplemented);
+               return Py_NotImplemented;
+       }
+
+       co = (PyCodeObject *)self;
+       cp = (PyCodeObject *)other;
+
+       eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ);
+       if (eq <= 0) goto unequal;
+       eq = co->co_argcount == cp->co_argcount;
+       if (!eq) goto unequal;
+       eq = co->co_nlocals == cp->co_nlocals;
+       if (!eq) goto unequal;
+       eq = co->co_flags == cp->co_flags;
+       if (!eq) goto unequal;
+       eq = co->co_firstlineno == cp->co_firstlineno;
+       if (!eq) goto unequal;
+       eq = PyObject_RichCompareBool(co->co_code, cp->co_code, Py_EQ);
+       if (eq <= 0) goto unequal;
+       eq = PyObject_RichCompareBool(co->co_consts, cp->co_consts, Py_EQ);
+       if (eq <= 0) goto unequal;
+       eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ);
+       if (eq <= 0) goto unequal;
+       eq = PyObject_RichCompareBool(co->co_varnames, cp->co_varnames, Py_EQ);
+       if (eq <= 0) goto unequal;
+       eq = PyObject_RichCompareBool(co->co_freevars, cp->co_freevars, Py_EQ);
+       if (eq <= 0) goto unequal;
+       eq = PyObject_RichCompareBool(co->co_cellvars, cp->co_cellvars, Py_EQ);
+       if (eq <= 0) goto unequal;
+
+       if (op == Py_EQ)
+               res = Py_True;
+       else
+               res = Py_False;
+       goto done;
+
+  unequal:
+       if (eq < 0)
+               return NULL;
+       if (op == Py_NE)
+               res = Py_True;
+       else
+               res = Py_False;
+
+  done:
+       Py_INCREF(res);
+       return res;
+}
+
 static long
 code_hash(PyCodeObject *co)
 {
@@ -377,7 +443,7 @@ PyTypeObject PyCode_Type = {
        code_doc,                       /* tp_doc */
        0,                              /* tp_traverse */
        0,                              /* tp_clear */
-       0,                              /* tp_richcompare */
+       code_richcompare,                               /* tp_richcompare */
        0,                              /* tp_weaklistoffset */
        0,                              /* tp_iter */
        0,                              /* tp_iternext */
index d661c47500675573bee8bb6409a3fe6c036688fc..5b9a3643aa53e7cc4c15a4f01e50835e1aa654d9 100644 (file)
@@ -223,6 +223,40 @@ meth_compare(PyCFunctionObject *a, PyCFunctionObject *b)
                return 1;
 }
 
+static PyObject *
+meth_richcompare(PyObject *self, PyObject *other, int op)
+{
+       PyCFunctionObject *a, *b;
+       PyObject *res;
+       int eq;
+
+       if ((op != Py_EQ && op != Py_NE) ||
+           !PyCFunction_Check(self) ||
+           !PyCFunction_Check(other))
+       {
+               /* Py3K warning if types are not equal and comparison isn't == or !=  */
+               if (Py_Py3kWarningFlag && PyErr_Warn(PyExc_DeprecationWarning,
+                               "builtin_function_or_method "
+                               "inequality comparisons not supported in 3.x.") < 0) {
+                       return NULL;
+               }
+
+               Py_INCREF(Py_NotImplemented);
+               return Py_NotImplemented;
+       }
+       a = (PyCFunctionObject *)self;
+       b = (PyCFunctionObject *)other;
+       eq = a->m_self == b->m_self;
+       if (eq)
+               eq = a->m_ml->ml_meth == b->m_ml->ml_meth;
+       if (op == Py_EQ)
+               res = eq ? Py_True : Py_False;
+       else
+               res = eq ? Py_False : Py_True;
+       Py_INCREF(res);
+       return res;
+}
+
 static long
 meth_hash(PyCFunctionObject *a)
 {
@@ -268,7 +302,7 @@ PyTypeObject PyCFunction_Type = {
        0,                                      /* tp_doc */
        (traverseproc)meth_traverse,            /* tp_traverse */
        0,                                      /* tp_clear */
-       0,                                      /* tp_richcompare */
+       meth_richcompare,                                       /* tp_richcompare */
        0,                                      /* tp_weaklistoffset */
        0,                                      /* tp_iter */
        0,                                      /* tp_iternext */