mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	Issue19995: passing a non-int to %o, %c, %x, or %X now raises an exception
This commit is contained in:
		
							parent
							
								
									8e5d0caf92
								
							
						
					
					
						commit
						38d872ee5d
					
				
					 5 changed files with 10 additions and 43 deletions
				
			
		|  | @ -1178,7 +1178,6 @@ def test_formatting(self): | |||
|         self.checkraises(TypeError, 'abc', '__mod__') | ||||
|         self.checkraises(TypeError, '%(foo)s', '__mod__', 42) | ||||
|         self.checkraises(TypeError, '%s%s', '__mod__', (42,)) | ||||
|         with self.assertWarns(DeprecationWarning): | ||||
|         self.checkraises(TypeError, '%c', '__mod__', (None,)) | ||||
|         self.checkraises(ValueError, '%(foo', '__mod__', {}) | ||||
|         self.checkraises(TypeError, '%(foo)s %(bar)s', '__mod__', ('foo', 42)) | ||||
|  |  | |||
|  | @ -142,8 +142,6 @@ def test_format(self): | |||
|         testformat("%#+027.23X", big, "+0X0001234567890ABCDEF12345") | ||||
|         # same, except no 0 flag | ||||
|         testformat("%#+27.23X", big, " +0X001234567890ABCDEF12345") | ||||
|         with self.assertWarns(DeprecationWarning): | ||||
|             testformat("%x", float(big), "123456_______________", 6) | ||||
|         big = 0o12345670123456701234567012345670  # 32 octal digits | ||||
|         testformat("%o", big, "12345670123456701234567012345670") | ||||
|         testformat("%o", -big, "-12345670123456701234567012345670") | ||||
|  | @ -183,8 +181,6 @@ def test_format(self): | |||
|         testformat("%034.33o", big, "0012345670123456701234567012345670") | ||||
|         # base marker shouldn't change that | ||||
|         testformat("%0#34.33o", big, "0o012345670123456701234567012345670") | ||||
|         with self.assertWarns(DeprecationWarning): | ||||
|             testformat("%o", float(big), "123456__________________________", 6) | ||||
|         # Some small ints, in both Python int and flavors). | ||||
|         testformat("%d", 42, "42") | ||||
|         testformat("%d", -42, "-42") | ||||
|  | @ -195,8 +191,6 @@ def test_format(self): | |||
|         testformat("%#x", 1, "0x1") | ||||
|         testformat("%#X", 1, "0X1") | ||||
|         testformat("%#X", 1, "0X1") | ||||
|         with self.assertWarns(DeprecationWarning): | ||||
|             testformat("%#x", 1.0, "0x1") | ||||
|         testformat("%#o", 1, "0o1") | ||||
|         testformat("%#o", 1, "0o1") | ||||
|         testformat("%#o", 0, "0o0") | ||||
|  | @ -213,14 +207,10 @@ def test_format(self): | |||
|         testformat("%x", -0x42, "-42") | ||||
|         testformat("%x", 0x42, "42") | ||||
|         testformat("%x", -0x42, "-42") | ||||
|         with self.assertWarns(DeprecationWarning): | ||||
|             testformat("%x", float(0x42), "42") | ||||
|         testformat("%o", 0o42, "42") | ||||
|         testformat("%o", -0o42, "-42") | ||||
|         testformat("%o", 0o42, "42") | ||||
|         testformat("%o", -0o42, "-42") | ||||
|         with self.assertWarns(DeprecationWarning): | ||||
|             testformat("%o", float(0o42), "42") | ||||
|         testformat("%r", "\u0378", "'\\u0378'")  # non printable | ||||
|         testformat("%a", "\u0378", "'\\u0378'")  # non printable | ||||
|         testformat("%r", "\u0374", "'\u0374'")   # printable | ||||
|  |  | |||
|  | @ -1149,11 +1149,11 @@ def __int__(self): | |||
|         self.assertEqual('%X' % letter_m, '6D') | ||||
|         self.assertEqual('%o' % letter_m, '155') | ||||
|         self.assertEqual('%c' % letter_m, 'm') | ||||
|         self.assertWarns(DeprecationWarning, '%x'.__mod__, pi), | ||||
|         self.assertWarns(DeprecationWarning, '%x'.__mod__, 3.14), | ||||
|         self.assertWarns(DeprecationWarning, '%X'.__mod__, 2.11), | ||||
|         self.assertWarns(DeprecationWarning, '%o'.__mod__, 1.79), | ||||
|         self.assertWarns(DeprecationWarning, '%c'.__mod__, pi), | ||||
|         self.assertRaises(TypeError, '%x'.__mod__, pi), | ||||
|         self.assertRaises(TypeError, '%x'.__mod__, 3.14), | ||||
|         self.assertRaises(TypeError, '%X'.__mod__, 2.11), | ||||
|         self.assertRaises(TypeError, '%o'.__mod__, 1.79), | ||||
|         self.assertRaises(TypeError, '%c'.__mod__, pi), | ||||
| 
 | ||||
|     def test_formatting_with_enum(self): | ||||
|         # issue18780 | ||||
|  |  | |||
|  | @ -18,6 +18,8 @@ Core and Builtins | |||
| - Issue #20637: Key-sharing now also works for instance dictionaries of | ||||
|   subclasses.  Patch by Peter Ingebretson. | ||||
| 
 | ||||
| - Issue #19995: %c, %o, %x, and %X now raise TypeError on non-integer input. | ||||
| 
 | ||||
| Library | ||||
| ------- | ||||
| 
 | ||||
|  |  | |||
|  | @ -13987,24 +13987,12 @@ mainformatlong(PyObject *v, | |||
|         goto wrongtype; | ||||
| 
 | ||||
|     /* make sure number is a type of integer */ | ||||
|     /* if not, issue deprecation warning for now */ | ||||
|     if (!PyLong_Check(v)) { | ||||
|         if (type == 'o' || type == 'x' || type == 'X') { | ||||
|             iobj = PyNumber_Index(v); | ||||
|             if (iobj == NULL) { | ||||
|                 PyErr_Clear(); | ||||
|                 if (PyErr_WarnEx(PyExc_DeprecationWarning, | ||||
|                                  "automatic int conversions have been deprecated", | ||||
|                                  1)) { | ||||
|                 return -1; | ||||
|             } | ||||
|                 iobj = PyNumber_Long(v); | ||||
|                 if (iobj == NULL ) { | ||||
|                     if (PyErr_ExceptionMatches(PyExc_TypeError)) | ||||
|                         goto wrongtype; | ||||
|                     return -1; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         else { | ||||
|             iobj = PyNumber_Long(v); | ||||
|  | @ -14085,22 +14073,10 @@ formatchar(PyObject *v) | |||
|         PyObject *iobj; | ||||
|         long x; | ||||
|         /* make sure number is a type of integer */ | ||||
|         /* if not, issue deprecation warning for now */ | ||||
|         if (!PyLong_Check(v)) { | ||||
|             iobj = PyNumber_Index(v); | ||||
|             if (iobj == NULL) { | ||||
|                 PyErr_Clear(); | ||||
|                 if (PyErr_WarnEx(PyExc_DeprecationWarning, | ||||
|                                  "automatic int conversions have been deprecated", | ||||
|                                  1)) { | ||||
|                     return -1; | ||||
|                 } | ||||
|                 iobj = PyNumber_Long(v); | ||||
|                 if (iobj == NULL ) { | ||||
|                     if (PyErr_ExceptionMatches(PyExc_TypeError)) | ||||
|                 goto onError; | ||||
|                     return -1; | ||||
|                 } | ||||
|             } | ||||
|             v = iobj; | ||||
|             Py_DECREF(iobj); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Ethan Furman
						Ethan Furman