Skip to content

Commit f41efa1

Browse files
committed
[GR-66026] Reimplement long_to_decimal_string_internal without _PyLong_New
PullRequest: graalpython/3873
2 parents 3bea818 + 0eb26ae commit f41efa1

File tree

2 files changed

+62
-6
lines changed

2 files changed

+62
-6
lines changed

graalpython/com.oracle.graal.python.cext/src/longobject.c

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1427,6 +1427,66 @@ long_to_decimal_string_internal(PyObject *aa,
14271427
_PyBytesWriter *bytes_writer,
14281428
char **bytes_str)
14291429
{
1430+
// GraalPy change: different implementation
1431+
PyObject *str;
1432+
1433+
// writer or bytes_writer can be used, but not both at the same time.
1434+
assert(writer == NULL || bytes_writer == NULL);
1435+
1436+
if (aa == NULL || !PyLong_Check(aa)) {
1437+
PyErr_BadInternalCall();
1438+
return -1;
1439+
}
1440+
1441+
str = PyObject_Repr(aa);
1442+
if (str == NULL) {
1443+
goto error;
1444+
}
1445+
if (!PyUnicode_Check(str)) {
1446+
PyErr_SetString(PyExc_TypeError,
1447+
"long.repr did not return a str");
1448+
goto error;
1449+
}
1450+
if (writer) {
1451+
Py_ssize_t size = PyUnicode_GET_LENGTH(str);
1452+
if (_PyUnicodeWriter_Prepare(writer, size, '9') == -1) {
1453+
goto error;
1454+
}
1455+
if (_PyUnicodeWriter_WriteStr(writer, str) < 0) {
1456+
goto error;
1457+
}
1458+
goto success;
1459+
}
1460+
else if (bytes_writer) {
1461+
Py_ssize_t size = PyUnicode_GET_LENGTH(str);
1462+
const void *data = PyUnicode_DATA(str);
1463+
int kind = PyUnicode_KIND(str);
1464+
*bytes_str = _PyBytesWriter_Prepare(bytes_writer, *bytes_str, size);
1465+
if (*bytes_str == NULL) {
1466+
goto error;
1467+
}
1468+
char *p = *bytes_str;
1469+
for (Py_ssize_t i=0; i < size; i++) {
1470+
Py_UCS4 ch = PyUnicode_READ(kind, data, i);
1471+
*p++ = (char) ch;
1472+
}
1473+
(*bytes_str) = p;
1474+
goto success;
1475+
}
1476+
else {
1477+
*p_output = Py_NewRef(str);
1478+
goto success;
1479+
}
1480+
1481+
error:
1482+
Py_XDECREF(str);
1483+
return -1;
1484+
1485+
success:
1486+
Py_DECREF(str);
1487+
return 0;
1488+
1489+
#if 0
14301490
PyLongObject *scratch, *a;
14311491
PyObject *str = NULL;
14321492
Py_ssize_t size, strlen, size_a, i, j;
@@ -1450,7 +1510,6 @@ long_to_decimal_string_internal(PyObject *aa,
14501510
14511511
explanation in https://github.com/python/cpython/pull/96537
14521512
*/
1453-
#if 0 // GraalPy change: interp->long_state not supported yet
14541513
if (size_a >= 10 * _PY_LONG_MAX_STR_DIGITS_THRESHOLD
14551514
/ (3 * PyLong_SHIFT) + 2) {
14561515
PyInterpreterState *interp = _PyInterpreterState_GET();
@@ -1462,7 +1521,6 @@ long_to_decimal_string_internal(PyObject *aa,
14621521
return -1;
14631522
}
14641523
}
1465-
#endif // GraalPy change
14661524

14671525
#if WITH_PYLONG_MODULE
14681526
if (size_a > 1000) {
@@ -1516,12 +1574,10 @@ long_to_decimal_string_internal(PyObject *aa,
15161574
hi /= _PyLong_DECIMAL_BASE;
15171575
}
15181576
/* check for keyboard interrupt */
1519-
#if 0 // GraalPy change
15201577
SIGCHECK({
15211578
Py_DECREF(scratch);
15221579
return -1;
15231580
});
1524-
#endif // GraalPy change
15251581
}
15261582
/* pout should have at least one digit, so that the case when a = 0
15271583
works correctly */
@@ -1536,7 +1592,6 @@ long_to_decimal_string_internal(PyObject *aa,
15361592
tenpow *= 10;
15371593
strlen++;
15381594
}
1539-
#if 0 // GraalPy change: interp->long_state not supported yet
15401595
if (strlen > _PY_LONG_MAX_STR_DIGITS_THRESHOLD) {
15411596
PyInterpreterState *interp = _PyInterpreterState_GET();
15421597
int max_str_digits = interp->long_state.max_str_digits;
@@ -1548,7 +1603,6 @@ long_to_decimal_string_internal(PyObject *aa,
15481603
return -1;
15491604
}
15501605
}
1551-
#endif // GraalPy change
15521606
if (writer) {
15531607
if (_PyUnicodeWriter_Prepare(writer, strlen, '9') == -1) {
15541608
Py_DECREF(scratch);
@@ -1651,6 +1705,7 @@ long_to_decimal_string_internal(PyObject *aa,
16511705
*p_output = (PyObject *)str;
16521706
}
16531707
return 0;
1708+
#endif // GraalPy change
16541709
}
16551710

16561711
static PyObject *

graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_unicode.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,7 @@ class TestPyUnicode(CPyExtTestCase):
674674
("%s, %r", ("hello", "world")),
675675
("nothing else", tuple()),
676676
(UnicodeSubclass("%s, %r"), ("hello", "world")),
677+
("%d.%d", (42, 123)),
677678
),
678679
resultspec="O",
679680
argspec='OO',

0 commit comments

Comments
 (0)