Commit 2147dfae authored by Stefan Behnel's avatar Stefan Behnel

directly call into CPython's Unicode writers to format float/int values,...

directly call into CPython's Unicode writers to format float/int values, rather than going all the way through PyObject_Format() and its method lookups
parent dbdd8b14
......@@ -3114,12 +3114,15 @@ class FormattedValueNode(ExprNode):
fn = self.find_conversion_func(conversion_char)
assert fn is not None, "invalid conversion character found: '%s'" % conversion_char
value_result = '%s(%s)' % (fn, value_result)
code.globalstate.use_utility_code(UtilityCode.load_cached("PyObjectFormatAndDecref", "StringTools.c"))
code.globalstate.use_utility_code(
UtilityCode.load_cached("PyObjectFormatAndDecref", "StringTools.c"))
format_func += 'AndDecref'
elif not self.format_spec:
code.globalstate.use_utility_code(UtilityCode.load_cached("PyObjectFormatSimple", "StringTools.c"))
elif self.format_spec:
code.globalstate.use_utility_code(
UtilityCode.load_cached("PyObjectFormat", "StringTools.c"))
else:
format_func = 'PyObject_Format'
code.globalstate.use_utility_code(
UtilityCode.load_cached("PyObjectFormatSimple", "StringTools.c"))
code.putln("%s = %s(%s, %s); %s" % (
self.result(),
......
......@@ -45,6 +45,8 @@
#define CYTHON_USE_PYLIST_INTERNALS 0
#undef CYTHON_USE_UNICODE_INTERNALS
#define CYTHON_USE_UNICODE_INTERNALS 0
#undef CYTHON_USE_UNICODE_WRITER
#define CYTHON_USE_UNICODE_WRITER 0
#undef CYTHON_USE_PYLONG_INTERNALS
#define CYTHON_USE_PYLONG_INTERNALS 0
#undef CYTHON_AVOID_BORROWED_REFS
......@@ -71,6 +73,8 @@
#ifndef CYTHON_USE_UNICODE_INTERNALS
#define CYTHON_USE_UNICODE_INTERNALS 1
#endif
#undef CYTHON_USE_UNICODE_WRITER
#define CYTHON_USE_UNICODE_WRITER 0
#undef CYTHON_USE_PYLONG_INTERNALS
#define CYTHON_USE_PYLONG_INTERNALS 0
#ifndef CYTHON_AVOID_BORROWED_REFS
......@@ -111,6 +115,12 @@
#ifndef CYTHON_USE_UNICODE_INTERNALS
#define CYTHON_USE_UNICODE_INTERNALS 1
#endif
#if PY_VERSION_HEX < 0x030300F0
#undef CYTHON_USE_UNICODE_WRITER
#define CYTHON_USE_UNICODE_WRITER 0
#elif !defined(CYTHON_USE_UNICODE_WRITER)
#define CYTHON_USE_UNICODE_WRITER 1
#endif
#ifndef CYTHON_AVOID_BORROWED_REFS
#define CYTHON_AVOID_BORROWED_REFS 0
#endif
......
......@@ -974,6 +974,48 @@ static CYTHON_INLINE int __Pyx_PyByteArray_Append(PyObject* bytearray, int value
}
//////////////////// PyObjectFormat.proto ////////////////////
#if CYTHON_USE_UNICODE_WRITER
static PyObject* __Pyx_PyObject_Format(PyObject* s, PyObject* f);
#else
#define __Pyx_PyObject_Format(s, f) PyObject_Format(s, f)
#endif
//////////////////// PyObjectFormat ////////////////////
#if CYTHON_USE_UNICODE_WRITER
static PyObject* __Pyx_PyObject_Format(PyObject* obj, PyObject* format_spec) {
int ret;
_PyUnicodeWriter writer;
if (likely(PyFloat_CheckExact(obj))) {
// copied from CPython 3.5 "float__format__()" in floatobject.c
_PyUnicodeWriter_Init(&writer);
ret = _PyFloat_FormatAdvancedWriter(
&writer,
obj,
format_spec, 0, PyUnicode_GET_LENGTH(format_spec));
} else if (likely(PyLong_CheckExact(obj))) {
// copied from CPython 3.5 "long__format__()" in longobject.c
_PyUnicodeWriter_Init(&writer);
ret = _PyLong_FormatAdvancedWriter(
&writer,
obj,
format_spec, 0, PyUnicode_GET_LENGTH(format_spec));
} else {
return PyObject_Format(obj, format_spec);
}
if (unlikely(ret == -1)) {
_PyUnicodeWriter_Dealloc(&writer);
return NULL;
}
return _PyUnicodeWriter_Finish(&writer);
}
#endif
//////////////////// PyObjectFormatSimple.proto ////////////////////
#if CYTHON_COMPILING_IN_PYPY
......
......@@ -254,9 +254,9 @@ def format_strings(str s, unicode u):
return a, b, c, d, e, f, g
def format_str(str s1, str s2):
def format_pystr(str s1, str s2):
"""
>>> a, b, c, d = format_str('abc', 'xyz')
>>> a, b, c, d = format_pystr('abc', 'xyz')
>>> print(a)
abcxyz
>>> print(b)
......@@ -275,3 +275,49 @@ def format_str(str s1, str s2):
d = f"s{s1}u{s2}"
assert isinstance(d, unicode), type(d)
return a, b, c, d
def raw_fstring(value):
"""
>>> print(raw_fstring('abc'))
abc\\x61
"""
return fr'{value}\x61'
def format_repr(value):
"""
>>> a, b = format_repr('abc')
>>> print('x{value!r}x'.format(value='abc'))
x'abc'x
>>> print('x{value!r:6}x'.format(value='abc'))
x'abc' x
>>> print(a)
x'abc'x
>>> print(b)
x'abc' x
"""
a = f'x{value!r}x'
assert isinstance(a, unicode), type(a)
b = f'x{value!r:6}x'
assert isinstance(b, unicode), type(b)
return a, b
def format_str(value):
"""
>>> a, b = format_str('abc')
>>> print('x{value!s}x'.format(value='abc'))
xabcx
>>> print('x{value!s:6}x'.format(value='abc'))
xabc x
>>> print(a)
xabcx
>>> print(b)
xabc x
"""
a = f'x{value!s}x'
assert isinstance(a, unicode), type(a)
b = f'x{value!s:6}x'
assert isinstance(b, unicode), type(b)
return a, b
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