Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 4 additions & 10 deletions gmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ MPZ_to_str(MPZ_Object *u, int base, int options)
static MPZ_Object *
MPZ_from_str(PyObject *obj, int base)
{
const char *str = PyUnicode_AsUTF8(obj);
const char *str = PyUnicode_AsUTF8AndSize(obj, NULL);

if (!str) {
return NULL; /* LCOV_EXCL_LINE */
Expand All @@ -157,6 +157,7 @@ MPZ_from_str(PyObject *obj, int base)
}
else if (ret == ZZ_BUF) {
/* LCOV_EXCL_START */
Py_DECREF(res);
PyErr_SetString(PyExc_OverflowError,
"too many digits in integer");
return NULL;
Expand Down Expand Up @@ -438,15 +439,8 @@ new_impl(PyTypeObject *Py_UNUSED(type), PyObject *arg, PyObject *base_arg)
}
str:
if (PyUnicode_Check(arg)) {
PyObject *asciistr = gmp_PyUnicode_TransformDecimalAndSpaceToASCII(arg);

if (!asciistr) {
return NULL; /* LCOV_EXCL_LINE */
}

PyObject *res = (PyObject *)MPZ_from_str(asciistr, base);
PyObject *res = (PyObject *)MPZ_from_str(arg, base);

Py_DECREF(asciistr);
return res;
}
else if (PyByteArray_Check(arg) || PyBytes_Check(arg)) {
Expand Down Expand Up @@ -1644,7 +1638,7 @@ The signed argument indicates whether two’s complement is used."},

PyDoc_STRVAR(mpz_doc,
"mpz(number=0, /)\nmpz(string, /, base=10)\n\n\
Convert a number or a string to an integer. If numeric argument is not\n\
Convert a number or an ASCII string to an integer. If numeric argument is not\n\
an int subclass, return mpz(int(number)).\n\n\
If argument is not a number or if base is given, then it must be a string,\n\
bytes, or bytearray instance representing an integer literal in the\n\
Expand Down
9 changes: 4 additions & 5 deletions tests/test_mpz.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,16 +270,13 @@ def test_mpz_interface():
with pytest.raises(ValueError, match="invalid literal"):
mpz(" ")
with pytest.raises(ValueError, match="invalid literal"):
mpz("ыыы")
mpz("qqq")
assert mpz() == mpz(0) == 0
assert mpz(" -123") == -123
assert mpz("123 ") == 123
assert mpz(" -123 ") == -123
assert mpz("+123") == 123
assert mpz("١٢٣٤") == 1234 # unicode decimal digits
assert mpz("١23") == 123
assert mpz("\t123") == 123
assert mpz("\xa0123") == 123
assert mpz("-010") == -10
assert mpz("-10") == -10
assert mpz("0b_10", 0) == 2
Expand Down Expand Up @@ -950,12 +947,14 @@ def test_from_bytes_interface():
@example(1<<116)
@example(646541478744828163276576707651635923929979156076518566789121)
@example((0xfffffffffffff8<<(242*4)) + (1<<970))
@example(0xa<<10000)
def test_to_float(x):
mx = mpz(x)
try:
fx = float(x)
except OverflowError:
pytest.raises(OverflowError, lambda: float(mx))
with pytest.raises(OverflowError):
float(mx)
else:
assert str(float(mx)) == str(fx)

Expand Down
44 changes: 0 additions & 44 deletions utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,47 +61,3 @@ gmp_parse_pyargs(const gmp_pyargs *fnargs, Py_ssize_t argidx[],
}
return 0;
}

/* copied from CPython internals */
PyObject *
gmp_PyUnicode_TransformDecimalAndSpaceToASCII(PyObject *unicode)
{
assert(PyUnicode_Check(unicode));
if (PyUnicode_IS_ASCII(unicode)) {
return Py_NewRef(unicode);
}

Py_ssize_t len = PyUnicode_GetLength(unicode);
PyObject *result = PyUnicode_New(len, 127);

if (result == NULL) {
return NULL; /* LCOV_EXCL_LINE */
}

Py_UCS1 *out = PyUnicode_1BYTE_DATA(result);
int kind = (int)PyUnicode_KIND(unicode); /* oracle/graalpython#580 */
const void *data = PyUnicode_DATA(unicode);

for (Py_ssize_t i = 0; i < len; ++i) {
Py_UCS4 ch = PyUnicode_READ(kind, data, i);

if (ch < 127) {
out[i] = (Py_UCS1)ch;
}
else if (Py_UNICODE_ISSPACE(ch)) {
out[i] = ' ';
}
else {
int decimal = Py_UNICODE_TODECIMAL(ch);

if (decimal < 0) {
out[i] = '?';
out[i + 1] = '\0';
break;
}
assert(decimal < 127);
out[i] = '0' + (Py_UCS1)decimal;
}
}
return result;
}
2 changes: 0 additions & 2 deletions utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,4 @@ int gmp_parse_pyargs(const gmp_pyargs *fnargs, Py_ssize_t argidx[],
PyObject *const *args, Py_ssize_t nargs,
PyObject *kwnames);

PyObject * gmp_PyUnicode_TransformDecimalAndSpaceToASCII(PyObject *unicode);

#endif /* UTILS_H */