[Python-checkins] r86170 - in python/branches/py3k: Doc/library/stdtypes.rst Lib/test/test_unicode.py Misc/NEWS Objects/stringlib/string_format.h Objects/unicodeobject.c

eric.smith python-checkins at python.org
Thu Nov 4 18:06:58 CET 2010


Author: eric.smith
Date: Thu Nov 4 18:06:58 2010
New Revision: 86170
Log:
Issue #6081: Add str.format_map. str.format_map(mapping) is similar to str.format(**mapping), except mapping does not get converted to a dict.
Modified:
 python/branches/py3k/Doc/library/stdtypes.rst
 python/branches/py3k/Lib/test/test_unicode.py
 python/branches/py3k/Misc/NEWS
 python/branches/py3k/Objects/stringlib/string_format.h
 python/branches/py3k/Objects/unicodeobject.c
Modified: python/branches/py3k/Doc/library/stdtypes.rst
==============================================================================
--- python/branches/py3k/Doc/library/stdtypes.rst	(original)
+++ python/branches/py3k/Doc/library/stdtypes.rst	Thu Nov 4 18:06:58 2010
@@ -1038,6 +1038,14 @@
 that can be specified in format strings.
 
 
+.. method:: str.format_map(mapping)
+
+ Similar to ``str.forrmat(**mapping)``, except that ``mapping`` is
+ used directly and not copied to a :class:`dict` . This is useful
+ if for example ``mapping`` is a dict subclass.
+
+ .. versionadded:: 3.2
+
 .. method:: str.index(sub[, start[, end]])
 
 Like :meth:`find`, but raise :exc:`ValueError` when the substring is not found.
Modified: python/branches/py3k/Lib/test/test_unicode.py
==============================================================================
--- python/branches/py3k/Lib/test/test_unicode.py	(original)
+++ python/branches/py3k/Lib/test/test_unicode.py	Thu Nov 4 18:06:58 2010
@@ -695,6 +695,84 @@
 self.assertRaises(ValueError, format, '', '#')
 self.assertRaises(ValueError, format, '', '#20')
 
+ def test_format_map(self):
+ self.assertEqual(''.format_map({}), '')
+ self.assertEqual('a'.format_map({}), 'a')
+ self.assertEqual('ab'.format_map({}), 'ab')
+ self.assertEqual('a{{'.format_map({}), 'a{')
+ self.assertEqual('a}}'.format_map({}), 'a}')
+ self.assertEqual('{{b'.format_map({}), '{b')
+ self.assertEqual('}}b'.format_map({}), '}b')
+ self.assertEqual('a{{b'.format_map({}), 'a{b')
+
+ # using mappings
+ class Mapping(dict):
+ def __missing__(self, key):
+ return key
+ self.assertEqual('{hello}'.format_map(Mapping()), 'hello')
+ self.assertEqual('{a} {world}'.format_map(Mapping(a='hello')), 'hello world')
+
+ class InternalMapping:
+ def __init__(self):
+ self.mapping = {'a': 'hello'}
+ def __getitem__(self, key):
+ return self.mapping[key]
+ self.assertEqual('{a}'.format_map(InternalMapping()), 'hello')
+
+
+ # classes we'll use for testing
+ class C:
+ def __init__(self, x=100):
+ self._x = x
+ def __format__(self, spec):
+ return spec
+
+ class D:
+ def __init__(self, x):
+ self.x = x
+ def __format__(self, spec):
+ return str(self.x)
+
+ # class with __str__, but no __format__
+ class E:
+ def __init__(self, x):
+ self.x = x
+ def __str__(self):
+ return 'E(' + self.x + ')'
+
+ # class with __repr__, but no __format__ or __str__
+ class F:
+ def __init__(self, x):
+ self.x = x
+ def __repr__(self):
+ return 'F(' + self.x + ')'
+
+ # class with __format__ that forwards to string, for some format_spec's
+ class G:
+ def __init__(self, x):
+ self.x = x
+ def __str__(self):
+ return "string is " + self.x
+ def __format__(self, format_spec):
+ if format_spec == 'd':
+ return 'G(' + self.x + ')'
+ return object.__format__(self, format_spec)
+
+ # class that returns a bad type from __format__
+ class H:
+ def __format__(self, format_spec):
+ return 1.0
+
+ self.assertEqual('{foo._x}'.format_map({'foo': C(20)}), '20')
+
+ # test various errors
+ self.assertRaises(TypeError, '{'.format_map)
+ self.assertRaises(TypeError, '}'.format_map)
+ self.assertRaises(TypeError, 'a{'.format_map)
+ self.assertRaises(TypeError, 'a}'.format_map)
+ self.assertRaises(TypeError, '{a'.format_map)
+ self.assertRaises(TypeError, '}a'.format_map)
+
 def test_format_auto_numbering(self):
 class C:
 def __init__(self, x=100):
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Thu Nov 4 18:06:58 2010
@@ -10,6 +10,8 @@
 Core and Builtins
 -----------------
 
+- Issue #6081: Add str.format_map, similar to str.format(**mapping).
+
 - If FileIO.__init__ fails, close the file descriptor.
 
 - Issue #10221: dict.pop(k) now has a key error message that includes the
Modified: python/branches/py3k/Objects/stringlib/string_format.h
==============================================================================
--- python/branches/py3k/Objects/stringlib/string_format.h	(original)
+++ python/branches/py3k/Objects/stringlib/string_format.h	Thu Nov 4 18:06:58 2010
@@ -499,7 +499,11 @@
 PyObject *key = SubString_new_object(&first);
 if (key == NULL)
 goto error;
- if ((kwargs == NULL) || (obj = PyDict_GetItem(kwargs, key)) == NULL) {
+
+ /* Use PyObject_GetItem instead of PyDict_GetItem because this
+ code is no longer just used with kwargs. It might be passed
+ a non-dict when called through format_map. */
+ if ((kwargs == NULL) || (obj = PyObject_GetItem(kwargs, key)) == NULL) {
 PyErr_SetObject(PyExc_KeyError, key);
 Py_DECREF(key);
 goto error;
@@ -1039,6 +1043,11 @@
 return build_string(&input, args, kwargs, recursion_depth, &auto_number);
 }
 
+static PyObject *
+do_string_format_map(PyObject *self, PyObject *obj)
+{
+ return do_string_format(self, NULL, obj);
+}
 
 
 /************************************************************************/
Modified: python/branches/py3k/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k/Objects/unicodeobject.c	(original)
+++ python/branches/py3k/Objects/unicodeobject.c	Thu Nov 4 18:06:58 2010
@@ -9028,6 +9028,11 @@
 \n\
 ");
 
+PyDoc_STRVAR(format_map__doc__,
+ "S.format_map(mapping) -> str\n\
+\n\
+");
+
 static PyObject *
 unicode__format__(PyObject* self, PyObject* args)
 {
@@ -9109,6 +9114,7 @@
 {"isprintable", (PyCFunction) unicode_isprintable, METH_NOARGS, isprintable__doc__},
 {"zfill", (PyCFunction) unicode_zfill, METH_VARARGS, zfill__doc__},
 {"format", (PyCFunction) do_string_format, METH_VARARGS | METH_KEYWORDS, format__doc__},
+ {"format_map", (PyCFunction) do_string_format_map, METH_O, format_map__doc__},
 {"__format__", (PyCFunction) unicode__format__, METH_VARARGS, p_format__doc__},
 {"maketrans", (PyCFunction) unicode_maketrans,
 METH_VARARGS | METH_STATIC, maketrans__doc__},


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /