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): ...@@ -3114,12 +3114,15 @@ class FormattedValueNode(ExprNode):
fn = self.find_conversion_func(conversion_char) fn = self.find_conversion_func(conversion_char)
assert fn is not None, "invalid conversion character found: '%s'" % conversion_char assert fn is not None, "invalid conversion character found: '%s'" % conversion_char
value_result = '%s(%s)' % (fn, value_result) 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' format_func += 'AndDecref'
elif not self.format_spec: elif self.format_spec:
code.globalstate.use_utility_code(UtilityCode.load_cached("PyObjectFormatSimple", "StringTools.c")) code.globalstate.use_utility_code(
UtilityCode.load_cached("PyObjectFormat", "StringTools.c"))
else: else:
format_func = 'PyObject_Format' code.globalstate.use_utility_code(
UtilityCode.load_cached("PyObjectFormatSimple", "StringTools.c"))
code.putln("%s = %s(%s, %s); %s" % ( code.putln("%s = %s(%s, %s); %s" % (
self.result(), self.result(),
......
...@@ -45,6 +45,8 @@ ...@@ -45,6 +45,8 @@
#define CYTHON_USE_PYLIST_INTERNALS 0 #define CYTHON_USE_PYLIST_INTERNALS 0
#undef CYTHON_USE_UNICODE_INTERNALS #undef CYTHON_USE_UNICODE_INTERNALS
#define CYTHON_USE_UNICODE_INTERNALS 0 #define CYTHON_USE_UNICODE_INTERNALS 0
#undef CYTHON_USE_UNICODE_WRITER
#define CYTHON_USE_UNICODE_WRITER 0
#undef CYTHON_USE_PYLONG_INTERNALS #undef CYTHON_USE_PYLONG_INTERNALS
#define CYTHON_USE_PYLONG_INTERNALS 0 #define CYTHON_USE_PYLONG_INTERNALS 0
#undef CYTHON_AVOID_BORROWED_REFS #undef CYTHON_AVOID_BORROWED_REFS
...@@ -71,6 +73,8 @@ ...@@ -71,6 +73,8 @@
#ifndef CYTHON_USE_UNICODE_INTERNALS #ifndef CYTHON_USE_UNICODE_INTERNALS
#define CYTHON_USE_UNICODE_INTERNALS 1 #define CYTHON_USE_UNICODE_INTERNALS 1
#endif #endif
#undef CYTHON_USE_UNICODE_WRITER
#define CYTHON_USE_UNICODE_WRITER 0
#undef CYTHON_USE_PYLONG_INTERNALS #undef CYTHON_USE_PYLONG_INTERNALS
#define CYTHON_USE_PYLONG_INTERNALS 0 #define CYTHON_USE_PYLONG_INTERNALS 0
#ifndef CYTHON_AVOID_BORROWED_REFS #ifndef CYTHON_AVOID_BORROWED_REFS
...@@ -111,6 +115,12 @@ ...@@ -111,6 +115,12 @@
#ifndef CYTHON_USE_UNICODE_INTERNALS #ifndef CYTHON_USE_UNICODE_INTERNALS
#define CYTHON_USE_UNICODE_INTERNALS 1 #define CYTHON_USE_UNICODE_INTERNALS 1
#endif #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 #ifndef CYTHON_AVOID_BORROWED_REFS
#define CYTHON_AVOID_BORROWED_REFS 0 #define CYTHON_AVOID_BORROWED_REFS 0
#endif #endif
......
...@@ -974,6 +974,48 @@ static CYTHON_INLINE int __Pyx_PyByteArray_Append(PyObject* bytearray, int value ...@@ -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 //////////////////// //////////////////// PyObjectFormatSimple.proto ////////////////////
#if CYTHON_COMPILING_IN_PYPY #if CYTHON_COMPILING_IN_PYPY
......
...@@ -254,9 +254,9 @@ def format_strings(str s, unicode u): ...@@ -254,9 +254,9 @@ def format_strings(str s, unicode u):
return a, b, c, d, e, f, g 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) >>> print(a)
abcxyz abcxyz
>>> print(b) >>> print(b)
...@@ -275,3 +275,49 @@ def format_str(str s1, str s2): ...@@ -275,3 +275,49 @@ def format_str(str s1, str s2):
d = f"s{s1}u{s2}" d = f"s{s1}u{s2}"
assert isinstance(d, unicode), type(d) assert isinstance(d, unicode), type(d)
return a, b, c, 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