[Python-checkins] r61570 - in python/trunk: Lib/test/test_py3kwarn.py Objects/codeobject.c Objects/methodobject.c

steven.bethard python-checkins at python.org
Tue Mar 18 23:08:20 CET 2008


Author: steven.bethard
Date: Tue Mar 18 23:08:20 2008
New Revision: 61570

Modified:
   python/trunk/Lib/test/test_py3kwarn.py
   python/trunk/Objects/codeobject.c
   python/trunk/Objects/methodobject.c
Log:
Add py3k warnings for code and method inequality comparisons. This should resolve issue 2373. The codeobject.c and methodobject.c changes are both just backports of the Python 3 code.

Modified: python/trunk/Lib/test/test_py3kwarn.py
==============================================================================
--- python/trunk/Lib/test/test_py3kwarn.py	(original)
+++ python/trunk/Lib/test/test_py3kwarn.py	Tue Mar 18 23:08:20 2008
@@ -50,6 +50,35 @@
         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)
 

Modified: python/trunk/Objects/codeobject.c
==============================================================================
--- python/trunk/Objects/codeobject.c	(original)
+++ python/trunk/Objects/codeobject.c	Tue Mar 18 23:08:20 2008
@@ -327,6 +327,72 @@
 		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 @@
 	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 */

Modified: python/trunk/Objects/methodobject.c
==============================================================================
--- python/trunk/Objects/methodobject.c	(original)
+++ python/trunk/Objects/methodobject.c	Tue Mar 18 23:08:20 2008
@@ -223,6 +223,40 @@
 		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 @@
  	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 */


More information about the Python-checkins mailing list