mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	Add py3k warnings for object, type, cell and dict comparisons. This should resolve issue2342 and partly resolve issue2373.
This commit is contained in:
		
							parent
							
								
									a8b09fd4c3
								
							
						
					
					
						commit
						ae42f33cdf
					
				
					 6 changed files with 166 additions and 3 deletions
				
			
		
							
								
								
									
										60
									
								
								Lib/test/test_py3kwarn.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								Lib/test/test_py3kwarn.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,60 @@ | |||
| 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() | ||||
							
								
								
									
										39
									
								
								Lib/test/test_undocumented_details.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								Lib/test/test_undocumented_details.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,39 @@ | |||
| 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) | |||
| static int | ||||
| 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 (b->ob_ref == NULL) | ||||
| 			return 0; | ||||
|  |  | |||
|  | @ -1776,8 +1776,14 @@ dict_richcompare(PyObject *v, PyObject *w, int op) | |||
| 			return NULL; | ||||
| 		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; | ||||
| 	} | ||||
| 	Py_INCREF(res); | ||||
| 	return res; | ||||
|  } | ||||
|  |  | |||
|  | @ -863,8 +863,18 @@ try_3way_to_rich_compare(PyObject *v, PyObject *w, int op) | |||
| 	int c; | ||||
| 
 | ||||
| 	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); | ||||
| 	} | ||||
| 	if (c <= -2) | ||||
| 		return NULL; | ||||
| 	return convert_3way_to_object(op, c); | ||||
|  |  | |||
|  | @ -593,6 +593,48 @@ type_compare(PyObject *v, PyObject *w) | |||
| 	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 * | ||||
| type_repr(PyTypeObject *type) | ||||
| { | ||||
|  | @ -2666,7 +2708,7 @@ PyTypeObject PyType_Type = { | |||
| 	type_doc,				/* tp_doc */ | ||||
| 	(traverseproc)type_traverse,		/* tp_traverse */ | ||||
| 	(inquiry)type_clear,			/* tp_clear */ | ||||
| 	0,					/* tp_richcompare */ | ||||
| 	type_richcompare,					/* tp_richcompare */ | ||||
| 	offsetof(PyTypeObject, tp_weaklist),	/* tp_weaklistoffset */ | ||||
| 	0,					/* tp_iter */ | ||||
| 	0,					/* tp_iternext */ | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Steven Bethard
						Steven Bethard