Commit ae42f33c authored by Steven Bethard's avatar Steven Bethard

Add py3k warnings for object, type, cell and dict comparisons. This should...

Add py3k warnings for object, type, cell and dict comparisons. This should resolve issue2342 and partly resolve issue2373.
parent a8b09fd4
import unittest
from test.test_support import catch_warning, TestSkipped, run_unittest
import warnings
# TODO: This is a hack to raise TestSkipped if -3 is not enabled. Instead
# of relying on callable to have a warning, we should expose the -3 flag
# to Python code somehow
with catch_warning() as w:
callable(int)
if w.message is None:
raise TestSkipped('%s must be run with the -3 flag' % __name__)
class TestPy3KWarnings(unittest.TestCase):
def test_type_inequality_comparisons(self):
expected = 'type inequality comparisons not supported in 3.x.'
with catch_warning() as w:
self.assertWarning(int < str, w, expected)
with catch_warning() as w:
self.assertWarning(type < object, w, expected)
def test_object_inequality_comparisons(self):
expected = 'comparing unequal types not supported in 3.x.'
with catch_warning() as w:
self.assertWarning(str < [], w, expected)
with catch_warning() as w:
self.assertWarning(object() < (1, 2), w, expected)
def test_dict_inequality_comparisons(self):
expected = 'dict inequality comparisons not supported in 3.x.'
with catch_warning() as w:
self.assertWarning({} < {2:3}, w, expected)
with catch_warning() as w:
self.assertWarning({} <= {}, w, expected)
with catch_warning() as w:
self.assertWarning({} > {2:3}, w, expected)
with catch_warning() as w:
self.assertWarning({2:3} >= {}, w, expected)
def test_cell_inequality_comparisons(self):
expected = 'cell comparisons not supported in 3.x.'
def f(x):
def g():
return x
return g
cell0, = f(0).func_closure
cell1, = f(1).func_closure
with catch_warning() as w:
self.assertWarning(cell0 == cell1, w, expected)
with catch_warning() as w:
self.assertWarning(cell0 < cell1, w, expected)
def assertWarning(self, _, warning, expected_message):
self.assertEqual(str(warning.message), expected_message)
def test_main():
run_unittest(TestPy3KWarnings)
if __name__ == '__main__':
test_main()
from test.test_support import run_unittest, have_unicode
import unittest
import sys
class TestImplementationComparisons(unittest.TestCase):
def test_type_comparisons(self):
self.assertTrue(str < int or str > int)
self.assertTrue(int <= str or int >= str)
self.assertTrue(cmp(int, str) != 0)
self.assertTrue(int is int)
self.assertTrue(str == str)
self.assertTrue(int != str)
def test_cell_comparisons(self):
def f(x):
if x:
y = 1
def g():
return x
def h():
return y
return g, h
g, h = f(0)
g_cell, = g.func_closure
h_cell, = h.func_closure
self.assertTrue(h_cell < g_cell)
self.assertTrue(g_cell >= h_cell)
self.assertEqual(cmp(g_cell, h_cell), 1)
self.assertTrue(g_cell is g_cell)
self.assertTrue(g_cell == g_cell)
self.assertTrue(h_cell == h_cell)
self.assertTrue(g_cell != h_cell)
def test_main():
run_unittest(TestImplementationComparisons)
if __name__ == '__main__':
test_main()
...@@ -54,6 +54,12 @@ cell_dealloc(PyCellObject *op) ...@@ -54,6 +54,12 @@ cell_dealloc(PyCellObject *op)
static int static int
cell_compare(PyCellObject *a, PyCellObject *b) cell_compare(PyCellObject *a, PyCellObject *b)
{ {
/* Py3K warning for comparisons */
if (Py_Py3kWarningFlag && PyErr_Warn(PyExc_DeprecationWarning,
"cell comparisons not supported in 3.x.") < 0) {
return NULL;
}
if (a->ob_ref == NULL) { if (a->ob_ref == NULL) {
if (b->ob_ref == NULL) if (b->ob_ref == NULL)
return 0; return 0;
......
...@@ -1776,8 +1776,14 @@ dict_richcompare(PyObject *v, PyObject *w, int op) ...@@ -1776,8 +1776,14 @@ dict_richcompare(PyObject *v, PyObject *w, int op)
return NULL; return NULL;
res = (cmp == (op == Py_EQ)) ? Py_True : Py_False; res = (cmp == (op == Py_EQ)) ? Py_True : Py_False;
} }
else else {
/* Py3K warning if comparison isn't == or != */
if (Py_Py3kWarningFlag && PyErr_Warn(PyExc_DeprecationWarning,
"dict inequality comparisons not supported in 3.x.") < 0) {
return NULL;
}
res = Py_NotImplemented; res = Py_NotImplemented;
}
Py_INCREF(res); Py_INCREF(res);
return res; return res;
} }
......
...@@ -863,8 +863,18 @@ try_3way_to_rich_compare(PyObject *v, PyObject *w, int op) ...@@ -863,8 +863,18 @@ try_3way_to_rich_compare(PyObject *v, PyObject *w, int op)
int c; int c;
c = try_3way_compare(v, w); c = try_3way_compare(v, w);
if (c >= 2) if (c >= 2) {
/* Py3K warning if types are not equal and comparison isn't == or != */
if (Py_Py3kWarningFlag &&
v->ob_type != w->ob_type && op != Py_EQ && op != Py_NE &&
PyErr_Warn(PyExc_DeprecationWarning,
"comparing unequal types not supported in 3.x.") < 0) {
return NULL;
}
c = default_3way_compare(v, w); c = default_3way_compare(v, w);
}
if (c <= -2) if (c <= -2)
return NULL; return NULL;
return convert_3way_to_object(op, c); return convert_3way_to_object(op, c);
......
...@@ -593,6 +593,48 @@ type_compare(PyObject *v, PyObject *w) ...@@ -593,6 +593,48 @@ type_compare(PyObject *v, PyObject *w)
return (vv < ww) ? -1 : (vv > ww) ? 1 : 0; return (vv < ww) ? -1 : (vv > ww) ? 1 : 0;
} }
static PyObject*
type_richcompare(PyObject *v, PyObject *w, int op)
{
PyObject *result;
Py_uintptr_t vv, ww;
int c;
/* Make sure both arguments are types. */
if (!PyType_Check(v) || !PyType_Check(w)) {
result = Py_NotImplemented;
goto out;
}
/* Py3K warning if comparison isn't == or != */
if (Py_Py3kWarningFlag && op != Py_EQ && op != Py_NE &&
PyErr_Warn(PyExc_DeprecationWarning,
"type inequality comparisons not supported in 3.x.") < 0) {
return NULL;
}
/* Compare addresses */
vv = (Py_uintptr_t)v;
ww = (Py_uintptr_t)w;
switch (op) {
case Py_LT: c = vv < ww; break;
case Py_LE: c = vv <= ww; break;
case Py_EQ: c = vv == ww; break;
case Py_NE: c = vv != ww; break;
case Py_GT: c = vv > ww; break;
case Py_GE: c = vv >= ww; break;
default:
result = Py_NotImplemented;
goto out;
}
result = c ? Py_True : Py_False;
/* incref and return */
out:
Py_INCREF(result);
return result;
}
static PyObject * static PyObject *
type_repr(PyTypeObject *type) type_repr(PyTypeObject *type)
{ {
...@@ -2666,7 +2708,7 @@ PyTypeObject PyType_Type = { ...@@ -2666,7 +2708,7 @@ PyTypeObject PyType_Type = {
type_doc, /* tp_doc */ type_doc, /* tp_doc */
(traverseproc)type_traverse, /* tp_traverse */ (traverseproc)type_traverse, /* tp_traverse */
(inquiry)type_clear, /* tp_clear */ (inquiry)type_clear, /* tp_clear */
0, /* tp_richcompare */ type_richcompare, /* tp_richcompare */
offsetof(PyTypeObject, tp_weaklist), /* tp_weaklistoffset */ offsetof(PyTypeObject, tp_weaklist), /* tp_weaklistoffset */
0, /* tp_iter */ 0, /* tp_iter */
0, /* tp_iternext */ 0, /* tp_iternext */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment