Commit 84b0c7be authored by Marius Wachtler's avatar Marius Wachtler Committed by GitHub

Merge pull request #1311 from aisk/pyobject_format

enable `PyObject_Format` in `from_cpython/Objects/abstract.c`
parents 10911d65 6b0f785a
......@@ -736,8 +736,6 @@ PyBuffer_Release(Py_buffer *view)
view->obj = NULL;
}
// pyston change: comment this out
#if 0
PyObject *
PyObject_Format(PyObject* obj, PyObject *format_spec)
{
......@@ -894,7 +892,6 @@ done:
Py_XDECREF(empty);
return result;
}
#endif
/* Operations on numbers */
......
......@@ -63,152 +63,6 @@ int Py_Py3kWarningFlag;
BoxedClass* capifunc_cls;
}
extern "C" PyObject* PyObject_Format(PyObject* obj, PyObject* format_spec) noexcept {
PyObject* empty = NULL;
PyObject* result = NULL;
#ifdef Py_USING_UNICODE
int spec_is_unicode;
int result_is_unicode;
#endif
/* If no format_spec is provided, use an empty string */
if (format_spec == NULL) {
empty = PyString_FromStringAndSize(NULL, 0);
format_spec = empty;
}
/* Check the format_spec type, and make sure it's str or unicode */
#ifdef Py_USING_UNICODE
if (PyUnicode_Check(format_spec))
spec_is_unicode = 1;
else if (PyString_Check(format_spec))
spec_is_unicode = 0;
else {
#else
if (!PyString_Check(format_spec)) {
#endif
PyErr_Format(PyExc_TypeError, "format expects arg 2 to be string "
"or unicode, not %.100s",
Py_TYPE(format_spec)->tp_name);
goto done;
}
/* Check for a __format__ method and call it. */
if (PyInstance_Check(obj)) {
/* We're an instance of a classic class */
PyObject* bound_method = PyObject_GetAttrString(obj, "__format__");
if (bound_method != NULL) {
result = PyObject_CallFunctionObjArgs(bound_method, format_spec, NULL);
Py_DECREF(bound_method);
} else {
PyObject* self_as_str = NULL;
PyObject* format_method = NULL;
Py_ssize_t format_len;
PyErr_Clear();
/* Per the PEP, convert to str (or unicode,
depending on the type of the format
specifier). For new-style classes, this
logic is done by object.__format__(). */
#ifdef Py_USING_UNICODE
if (spec_is_unicode) {
format_len = PyUnicode_GET_SIZE(format_spec);
self_as_str = PyObject_Unicode(obj);
} else
#endif
{
format_len = PyString_GET_SIZE(format_spec);
self_as_str = PyObject_Str(obj);
}
if (self_as_str == NULL)
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_GetAttrString(self_as_str, "__format__");
if (format_method == NULL) {
goto done1;
}
result = PyObject_CallFunctionObjArgs(format_method, format_spec, NULL);
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 */
static PyObject* format_cache = NULL;
/* Find the (unbound!) __format__ method (a borrowed
reference) */
PyObject* method = _PyObject_LookupSpecial(obj, "__format__", &format_cache);
if (method == NULL) {
if (!PyErr_Occurred())
PyErr_Format(PyExc_TypeError, "Type %.100s doesn't define __format__", Py_TYPE(obj)->tp_name);
goto done;
}
/* And call it. */
result = PyObject_CallFunctionObjArgs(method, format_spec, NULL);
Py_DECREF(method);
}
if (result == NULL)
goto done;
/* Check the result type, and make sure it's str or unicode */
#ifdef Py_USING_UNICODE
if (PyUnicode_Check(result))
result_is_unicode = 1;
else if (PyString_Check(result))
result_is_unicode = 0;
else {
#else
if (!PyString_Check(result)) {
#endif
PyErr_Format(PyExc_TypeError, "%.100s.__format__ must return string or "
"unicode, not %.100s",
Py_TYPE(obj)->tp_name, Py_TYPE(result)->tp_name);
Py_DECREF(result);
result = NULL;
goto done;
}
/* Convert to unicode, if needed. Required if spec is unicode
and result is str */
#ifdef Py_USING_UNICODE
if (spec_is_unicode && !result_is_unicode) {
PyObject* tmp = PyObject_Unicode(result);
/* This logic works whether or not tmp is NULL */
Py_DECREF(result);
result = tmp;
}
#endif
done:
Py_XDECREF(empty);
return result;
}
extern "C" PyObject* PyObject_GetAttr(PyObject* o, PyObject* attr) noexcept {
if (!PyString_Check(attr)) {
if (PyUnicode_Check(attr)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment