diff options
author | Eric Smith <eric@trueblade.com> | 2010-04-02 12:30:56 (GMT) |
---|---|---|
committer | Eric Smith <eric@trueblade.com> | 2010-04-02 12:30:56 (GMT) |
commit | d44b2fc87c2d9bd9e390eb54d50306959d80ba87 (patch) | |
tree | b5eb61ba3a600821c69f87bf1b73562a698f8a18 /Objects | |
parent | 3b958e3b575dec4691419dc6488bb7be86afb409 (diff) | |
download | cpython-d44b2fc87c2d9bd9e390eb54d50306959d80ba87.zip cpython-d44b2fc87c2d9bd9e390eb54d50306959d80ba87.tar.gz cpython-d44b2fc87c2d9bd9e390eb54d50306959d80ba87.tar.bz2 |
Issue 7994: Make object.__format__ with a non-empty format string a PendingDecprecationWarning. Still need to remove uses of this from various tests.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/abstract.c | 47 | ||||
-rw-r--r-- | Objects/typeobject.c | 29 |
2 files changed, 62 insertions, 14 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c index 8d6f023..0b541ee 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -777,8 +777,9 @@ PyObject_Format(PyObject* obj, PyObject *format_spec) NULL); Py_DECREF(bound_method); } else { - PyObject *self_as_str; - PyObject *format_method; + PyObject *self_as_str = NULL; + PyObject *format_method = NULL; + Py_ssize_t format_len; PyErr_Clear(); /* Per the PEP, convert to str (or unicode, @@ -786,29 +787,53 @@ PyObject_Format(PyObject* obj, PyObject *format_spec) specifier). For new-style classes, this logic is done by object.__format__(). */ #ifdef Py_USING_UNICODE - if (spec_is_unicode) + if (spec_is_unicode) { + format_len = PyUnicode_GET_SIZE(format_spec); self_as_str = PyObject_Unicode(obj); - else + } else #endif + { + format_len = PyString_GET_SIZE(format_spec); self_as_str = PyObject_Str(obj); + } if (self_as_str == NULL) - goto done; + goto done1; + + if (format_len > 0) { + /* See the almost identical code in + typeobject.c for new-style + classes. */ + if (PyErr_WarnEx( + PyExc_PendingDeprecationWarning, + "object.__format__ with a non-empty " + "format string is deprecated", 1) + < 0) { + goto done1; + } + /* Eventually this will become an + error: + PyErr_Format(PyExc_TypeError, + "non-empty format string passed to " + "object.__format__"); + goto done1; + */ + } /* Then call str.__format__ on that result */ format_method = PyObject_GetAttr(self_as_str, str__format__); if (format_method == NULL) { - Py_DECREF(self_as_str); - goto done; + goto done1; } - result = PyObject_CallFunctionObjArgs(format_method, + result = PyObject_CallFunctionObjArgs(format_method, format_spec, NULL); - Py_DECREF(self_as_str); - Py_DECREF(format_method); +done1: + Py_XDECREF(self_as_str); + Py_XDECREF(format_method); if (result == NULL) goto done; - } + } } else { /* Not an instance of a classic class, use the code from py3k */ diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 28df7f2..e4176e2 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3414,31 +3414,54 @@ object_format(PyObject *self, PyObject *args) PyObject *self_as_str = NULL; PyObject *result = NULL; PyObject *format_meth = NULL; + Py_ssize_t format_len; if (!PyArg_ParseTuple(args, "O:__format__", &format_spec)) return NULL; #ifdef Py_USING_UNICODE if (PyUnicode_Check(format_spec)) { + format_len = PyUnicode_GET_SIZE(format_spec); self_as_str = PyObject_Unicode(self); } else if (PyString_Check(format_spec)) { #else if (PyString_Check(format_spec)) { #endif + format_len = PyString_GET_SIZE(format_spec); self_as_str = PyObject_Str(self); } else { - PyErr_SetString(PyExc_TypeError, "argument to __format__ must be unicode or str"); + PyErr_SetString(PyExc_TypeError, + "argument to __format__ must be unicode or str"); return NULL; } if (self_as_str != NULL) { + /* Issue 7994: If we're converting to a string, we + should reject format specifications */ + if (format_len > 0) { + if (PyErr_WarnEx(PyExc_PendingDeprecationWarning, + "object.__format__ with a non-empty format " + "string is deprecated", 1) < 0) { + goto done; + } + /* Eventually this will become an error: + PyErr_Format(PyExc_TypeError, + "non-empty format string passed to object.__format__"); + goto done; + */ + } + /* find the format function */ - format_meth = PyObject_GetAttrString(self_as_str, "__format__"); + format_meth = PyObject_GetAttrString(self_as_str, + "__format__"); if (format_meth != NULL) { /* and call it */ - result = PyObject_CallFunctionObjArgs(format_meth, format_spec, NULL); + result = PyObject_CallFunctionObjArgs(format_meth, + format_spec, + NULL); } } +done: Py_XDECREF(self_as_str); Py_XDECREF(format_meth); |