mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 21:51:50 +00:00 
			
		
		
		
	Added test cases for string.Formatter subclassing.
Made format_spec parameter to builtin format optional, defaults to empty string. Added test cases.
This commit is contained in:
		
							parent
							
								
									231ff0ec11
								
							
						
					
					
						commit
						81936699c8
					
				
					 3 changed files with 76 additions and 20 deletions
				
			
		|  | @ -532,15 +532,22 @@ def __format__(self, format_spec): | |||
|         self.assertEqual(format(3, ''), '3') | ||||
|         self.assertEqual(format(A(3), 'spec'), '3spec') | ||||
| 
 | ||||
|         def empty_format_spec(value): | ||||
|             # test that: | ||||
|             #  format(x, '') == str(x) | ||||
|             #  format(x) == str(x) | ||||
|             self.assertEqual(format(value, ""), str(value)) | ||||
|             self.assertEqual(format(value), str(value)) | ||||
| 
 | ||||
|         # for builtin types, format(x, "") == str(x) | ||||
|         self.assertEqual(format(17**13, ""), str(17**13)) | ||||
|         self.assertEqual(format(1.0, ""), str(1.0)) | ||||
|         self.assertEqual(format(3.1415e104, ""), str(3.1415e104)) | ||||
|         self.assertEqual(format(-3.1415e104, ""), str(-3.1415e104)) | ||||
|         self.assertEqual(format(3.1415e-104, ""), str(3.1415e-104)) | ||||
|         self.assertEqual(format(-3.1415e-104, ""), str(-3.1415e-104)) | ||||
|         self.assertEqual(format(object, ""), str(object)) | ||||
|         self.assertEqual(format(None, ""), str(None)) | ||||
|         empty_format_spec(17**13) | ||||
|         empty_format_spec(1.0) | ||||
|         empty_format_spec(3.1415e104) | ||||
|         empty_format_spec(-3.1415e104) | ||||
|         empty_format_spec(3.1415e-104) | ||||
|         empty_format_spec(-3.1415e-104) | ||||
|         empty_format_spec(object) | ||||
|         empty_format_spec(None) | ||||
| 
 | ||||
|         # TypeError because self.__format__ returns the wrong type | ||||
|         self.assertRaises(TypeError, format, H(), "") | ||||
|  |  | |||
|  | @ -23,6 +23,7 @@ def test_formatter(self): | |||
|         self.assertEqual(fmt.format("foo{1}{0}-{1}", "bar", 6), "foo6bar-6") | ||||
|         self.assertEqual(fmt.format("-{arg!r}-", arg='test'), "-'test'-") | ||||
| 
 | ||||
|         # override get_value ############################################ | ||||
|         class NamespaceFormatter(string.Formatter): | ||||
|             def __init__(self, namespace={}): | ||||
|                 string.Formatter.__init__(self) | ||||
|  | @ -42,6 +43,43 @@ def get_value(self, key, args, kwds): | |||
|         self.assertEqual(fmt.format("{greeting}, world!"), 'hello, world!') | ||||
| 
 | ||||
| 
 | ||||
|         # override format_field ######################################### | ||||
|         class CallFormatter(string.Formatter): | ||||
|             def format_field(self, value, format_spec): | ||||
|                 return format(value(), format_spec) | ||||
| 
 | ||||
|         fmt = CallFormatter() | ||||
|         self.assertEqual(fmt.format('*{0}*', lambda : 'result'), '*result*') | ||||
| 
 | ||||
| 
 | ||||
|         # override convert_field ######################################## | ||||
|         class XFormatter(string.Formatter): | ||||
|             def convert_field(self, value, conversion): | ||||
|                 if conversion == 'x': | ||||
|                     return None | ||||
|                 return super(XFormatter, self).convert_field(value, conversion) | ||||
| 
 | ||||
|         fmt = XFormatter() | ||||
|         self.assertEqual(fmt.format("{0!r}:{0!x}", 'foo', 'foo'), "'foo':None") | ||||
| 
 | ||||
| 
 | ||||
|         # override parse ################################################ | ||||
|         class BarFormatter(string.Formatter): | ||||
|             # returns an iterable that contains tuples of the form: | ||||
|             # (literal_text, field_name, format_spec, conversion) | ||||
|             def parse(self, format_string): | ||||
|                 for field in format_string.split('|'): | ||||
|                     if field[0] == '+': | ||||
|                         # it's markup | ||||
|                         field_name, _, format_spec = field[1:].partition(':') | ||||
|                         yield '', field_name, format_spec, None | ||||
|                     else: | ||||
|                         yield field, None, None, None | ||||
| 
 | ||||
|         fmt = BarFormatter() | ||||
|         self.assertEqual(fmt.format('*|+0:^10s|*', 'foo'), '*   foo    *') | ||||
| 
 | ||||
| 
 | ||||
|     def test_maketrans(self): | ||||
|         transtable = '\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`xyzdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377' | ||||
| 
 | ||||
|  |  | |||
|  | @ -280,25 +280,32 @@ builtin_format(PyObject *self, PyObject *args) | |||
| { | ||||
|         static PyObject * format_str = NULL; | ||||
|         PyObject *value; | ||||
|         PyObject *spec; | ||||
|         PyObject *spec = NULL; | ||||
|         PyObject *meth; | ||||
|         PyObject *result; | ||||
|         PyObject *empty = NULL; | ||||
|         PyObject *result = NULL; | ||||
| 
 | ||||
|         /* Initialize cached value */ | ||||
|         if (format_str == NULL) { | ||||
|                 /* Initialize static variable needed by _PyType_Lookup */ | ||||
|                 format_str = PyUnicode_FromString("__format__"); | ||||
|                 if (format_str == NULL) | ||||
|                         return NULL; | ||||
|                         goto done; | ||||
|         } | ||||
| 
 | ||||
|         if (!PyArg_ParseTuple(args, "OO:format", &value, &spec)) | ||||
|                return NULL; | ||||
|         if (!PyArg_ParseTuple(args, "O|O:format", &value, &spec)) | ||||
|                goto done; | ||||
| 
 | ||||
|         /* initialize the default value */ | ||||
|         if (spec == NULL) { | ||||
|             empty = PyUnicode_FromUnicode(NULL, 0); | ||||
|             spec = empty; | ||||
|         } | ||||
| 
 | ||||
|         /* Make sure the type is initialized.  float gets initialized late */ | ||||
|         if (Py_Type(value)->tp_dict == NULL) | ||||
|                 if (PyType_Ready(Py_Type(value)) < 0) | ||||
|                     return NULL; | ||||
|                         goto done; | ||||
| 
 | ||||
|         /* Find the (unbound!) __format__ method (a borrowed reference) */ | ||||
|         meth = _PyType_Lookup(Py_Type(value), format_str); | ||||
|  | @ -306,27 +313,31 @@ builtin_format(PyObject *self, PyObject *args) | |||
|                 PyErr_Format(PyExc_TypeError, | ||||
|                              "Type %.100s doesn't define __format__", | ||||
|                              Py_Type(value)->tp_name); | ||||
|                 return NULL; | ||||
|                 goto done; | ||||
|         } | ||||
| 
 | ||||
|         /* And call it, binding it to the value */ | ||||
|         result = PyObject_CallFunctionObjArgs(meth, value, spec, NULL); | ||||
| 
 | ||||
| 	if (result && !PyUnicode_Check(result)) { | ||||
|         if (result && !PyUnicode_Check(result)) { | ||||
|                 PyErr_SetString(PyExc_TypeError, | ||||
|                                 "__format__ method did not return string"); | ||||
|                 Py_DECREF(result); | ||||
|                 return NULL; | ||||
|                 result = NULL; | ||||
|                 goto done; | ||||
|         } | ||||
| 
 | ||||
| done: | ||||
|         Py_XDECREF(empty); | ||||
|         return result; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| PyDoc_STRVAR(format_doc, | ||||
| "format(value, format_spec) -> string\n\
 | ||||
| "format(value[, format_spec]) -> string\n\
 | ||||
| \n\ | ||||
| Returns value.__format__(format_spec)."); | ||||
| Returns value.__format__(format_spec)\n\ | ||||
| format_spec defaults to \"\""); | ||||
| 
 | ||||
| 
 | ||||
| static PyObject * | ||||
| builtin_chr8(PyObject *self, PyObject *args) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Eric Smith
						Eric Smith