mirror of https://github.com/python/cpython
gh-117709: Add vectorcall support for str() with positional-only arguments (#117746)
Fall back to tp_call() for cases when arguments are passed by name. Co-authored-by: Donghee Na <donghee.na@python.org> Co-authored-by: Victor Stinner <vstinner@python.org>
This commit is contained in:
parent
671cb22094
commit
044dc496e0
|
@ -2651,6 +2651,24 @@ class StrTest(string_tests.StringLikeTest,
|
||||||
proc = assert_python_failure('-X', 'dev', '-c', code)
|
proc = assert_python_failure('-X', 'dev', '-c', code)
|
||||||
self.assertEqual(proc.rc, 10, proc)
|
self.assertEqual(proc.rc, 10, proc)
|
||||||
|
|
||||||
|
def test_str_invalid_call(self):
|
||||||
|
check = lambda *a, **kw: self.assertRaises(TypeError, str, *a, **kw)
|
||||||
|
|
||||||
|
# too many args
|
||||||
|
check(1, "", "", 1)
|
||||||
|
|
||||||
|
# no such kw arg
|
||||||
|
check(test=1)
|
||||||
|
|
||||||
|
# 'encoding' must be str
|
||||||
|
check(1, encoding=1)
|
||||||
|
check(1, 1)
|
||||||
|
|
||||||
|
# 'errors' must be str
|
||||||
|
check(1, errors=1)
|
||||||
|
check(1, "", errors=1)
|
||||||
|
check(1, 1, 1)
|
||||||
|
|
||||||
|
|
||||||
class StringModuleTest(unittest.TestCase):
|
class StringModuleTest(unittest.TestCase):
|
||||||
def test_formatter_parser(self):
|
def test_formatter_parser(self):
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
Speed up calls to :func:`str` with positional-only argument,
|
||||||
|
by using the :pep:`590` ``vectorcall`` calling convention.
|
||||||
|
Patch by Erlend Aasland.
|
|
@ -14617,6 +14617,56 @@ unicode_new_impl(PyTypeObject *type, PyObject *x, const char *encoding,
|
||||||
return unicode;
|
return unicode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
arg_as_utf8(PyObject *obj, const char *name)
|
||||||
|
{
|
||||||
|
if (!PyUnicode_Check(obj)) {
|
||||||
|
PyErr_Format(PyExc_TypeError,
|
||||||
|
"str() argument '%s' must be str, not %T",
|
||||||
|
name, obj);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return _PyUnicode_AsUTF8NoNUL(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
unicode_vectorcall(PyObject *type, PyObject *const *args,
|
||||||
|
size_t nargsf, PyObject *kwnames)
|
||||||
|
{
|
||||||
|
assert(Py_Is(_PyType_CAST(type), &PyUnicode_Type));
|
||||||
|
|
||||||
|
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
|
||||||
|
if (kwnames != NULL && PyTuple_GET_SIZE(kwnames) != 0) {
|
||||||
|
// Fallback to unicode_new()
|
||||||
|
PyObject *tuple = _PyTuple_FromArray(args, nargs);
|
||||||
|
if (tuple == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
PyObject *dict = _PyStack_AsDict(args + nargs, kwnames);
|
||||||
|
if (dict == NULL) {
|
||||||
|
Py_DECREF(tuple);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
PyObject *ret = unicode_new(_PyType_CAST(type), tuple, dict);
|
||||||
|
Py_DECREF(tuple);
|
||||||
|
Py_DECREF(dict);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (!_PyArg_CheckPositional("str", nargs, 0, 3)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (nargs == 0) {
|
||||||
|
return unicode_get_empty();
|
||||||
|
}
|
||||||
|
PyObject *object = args[0];
|
||||||
|
if (nargs == 1) {
|
||||||
|
return PyObject_Str(object);
|
||||||
|
}
|
||||||
|
const char *encoding = arg_as_utf8(args[1], "encoding");
|
||||||
|
const char *errors = (nargs == 3) ? arg_as_utf8(args[2], "errors") : NULL;
|
||||||
|
return PyUnicode_FromEncodedObject(object, encoding, errors);
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
unicode_subtype_new(PyTypeObject *type, PyObject *unicode)
|
unicode_subtype_new(PyTypeObject *type, PyObject *unicode)
|
||||||
{
|
{
|
||||||
|
@ -14758,6 +14808,7 @@ PyTypeObject PyUnicode_Type = {
|
||||||
0, /* tp_alloc */
|
0, /* tp_alloc */
|
||||||
unicode_new, /* tp_new */
|
unicode_new, /* tp_new */
|
||||||
PyObject_Del, /* tp_free */
|
PyObject_Del, /* tp_free */
|
||||||
|
.tp_vectorcall = unicode_vectorcall,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Initialize the Unicode implementation */
|
/* Initialize the Unicode implementation */
|
||||||
|
|
Loading…
Reference in New Issue