mirror of
https://github.com/python/cpython.git
synced 2025-11-03 03:22:27 +00:00
Get rid of all METH_OLDARGS & PyArg_Parse.
Fix floating point exception if mpz.powm(10, 1, 0) (modulus == 0). Add a test.
This commit is contained in:
parent
496563a514
commit
02098fa56b
2 changed files with 125 additions and 43 deletions
90
Lib/test/test_mpz.py
Normal file
90
Lib/test/test_mpz.py
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
|
||||||
|
import mpz
|
||||||
|
from test_support import vereq
|
||||||
|
|
||||||
|
def check_conversion(num):
|
||||||
|
mpz_num = mpz.mpz(num)
|
||||||
|
vereq(int(mpz_num), num)
|
||||||
|
vereq(long(mpz_num), num)
|
||||||
|
vereq(str(mpz_num), 'mpz(%s)' % `int(num)`)
|
||||||
|
|
||||||
|
check_conversion(10)
|
||||||
|
check_conversion(10L)
|
||||||
|
# FIXME: should check strings, but I'm not sure it works, this seems odd:
|
||||||
|
# mpz.mpz('10') == mpz(12337)
|
||||||
|
|
||||||
|
vereq(mpz.divm(100, 200, 3), 2)
|
||||||
|
vereq(mpz.divm(100L, 200, 3), 2)
|
||||||
|
vereq(mpz.divm(100, 200L, 3), 2)
|
||||||
|
vereq(mpz.divm(100L, 200L, 3), 2)
|
||||||
|
|
||||||
|
vereq(mpz.gcd(100, 200), 100)
|
||||||
|
vereq(mpz.gcd(100L, 200), 100)
|
||||||
|
vereq(mpz.gcd(100, 200L), 100)
|
||||||
|
vereq(mpz.gcd(100L, 200L), 100)
|
||||||
|
|
||||||
|
vereq(mpz.gcdext(100, 200), (100, 1, 0))
|
||||||
|
vereq(mpz.gcdext(100L, 200), (100, 1, 0))
|
||||||
|
vereq(mpz.gcdext(100, 200L), (100, 1, 0))
|
||||||
|
vereq(mpz.gcdext(100L, 200L), (100, 1, 0))
|
||||||
|
|
||||||
|
vereq(mpz.powm(100, 0, 3), 1)
|
||||||
|
vereq(mpz.powm(100L, 0, 3), 1)
|
||||||
|
vereq(mpz.powm(100, 0L, 3), 1)
|
||||||
|
vereq(mpz.powm(100L, 0L, 3), 1)
|
||||||
|
|
||||||
|
vereq(mpz.powm(101, 5, 3333), 1616)
|
||||||
|
vereq(mpz.powm(101L, 5, 3333), 1616)
|
||||||
|
vereq(mpz.powm(101, 5L, 3333), 1616)
|
||||||
|
vereq(mpz.powm(101L, 5L, 3333), 1616)
|
||||||
|
|
||||||
|
vereq(mpz.sqrt(100), 10)
|
||||||
|
vereq(mpz.sqrt(100L), 10)
|
||||||
|
vereq(mpz.sqrt(200), 14)
|
||||||
|
vereq(mpz.sqrt(200L), 14)
|
||||||
|
|
||||||
|
vereq(mpz.sqrtrem(100), (10, 0))
|
||||||
|
vereq(mpz.sqrtrem(100L), (10, 0))
|
||||||
|
vereq(mpz.sqrtrem(200), (14, 4))
|
||||||
|
vereq(mpz.sqrtrem(200L), (14, 4))
|
||||||
|
|
||||||
|
try: mpz.mpz(10.)
|
||||||
|
except TypeError: pass
|
||||||
|
else: raise TestFailed, 'mpz(10.) should raise a TypeError'
|
||||||
|
|
||||||
|
try: mpz.powm(10.)
|
||||||
|
except TypeError: pass
|
||||||
|
else: raise TestFailed, 'powm(10.) should raise a TypeError'
|
||||||
|
|
||||||
|
try: mpz.powm(100, 1, 0)
|
||||||
|
except ValueError: pass
|
||||||
|
else: raise TestFailed, 'powm(100, 1, 0) should raise a ValueError'
|
||||||
|
|
||||||
|
try: mpz.divm(10, 10)
|
||||||
|
except TypeError: pass
|
||||||
|
else: raise TestFailed, 'divm(10, 10) should raise a TypeError'
|
||||||
|
|
||||||
|
try: mpz.divm(10, 10, 10.)
|
||||||
|
except TypeError: pass
|
||||||
|
else: raise TestFailed, 'divm(10, 10, 10.) should raise a TypeError'
|
||||||
|
|
||||||
|
try: mpz.gcd(10)
|
||||||
|
except TypeError: pass
|
||||||
|
else: raise TestFailed, 'gcd(10) should raise a TypeError'
|
||||||
|
|
||||||
|
try: mpz.gcd(10, 10.)
|
||||||
|
except TypeError: pass
|
||||||
|
else: raise TestFailed, 'gcd(10, 10.) should raise a TypeError'
|
||||||
|
|
||||||
|
try: mpz.gcdext(10)
|
||||||
|
except TypeError: pass
|
||||||
|
else: raise TestFailed, 'gcdext(10) should raise a TypeError'
|
||||||
|
|
||||||
|
try: mpz.gcdext(10, 10.)
|
||||||
|
except TypeError: pass
|
||||||
|
else: raise TestFailed, 'gcdext(10, 10.) should raise a TypeError'
|
||||||
|
|
||||||
|
try: mpz.mpz(-10).binary()
|
||||||
|
except ValueError: pass
|
||||||
|
else: raise TestFailed, 'mpz(-10).binary() should raise a ValueError'
|
||||||
|
|
||||||
|
|
@ -835,25 +835,17 @@ static PyObject *
|
||||||
MPZ_mpz(PyObject *self, PyObject *args)
|
MPZ_mpz(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
mpzobject *mpzp;
|
mpzobject *mpzp;
|
||||||
PyObject *objp;
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef MPZ_DEBUG
|
#ifdef MPZ_DEBUG
|
||||||
fputs("MPZ_mpz() called...\n", stderr);
|
fputs("MPZ_mpz() called...\n", stderr);
|
||||||
#endif /* def MPZ_DEBUG */
|
#endif /* def MPZ_DEBUG */
|
||||||
|
|
||||||
if (!PyArg_Parse(args, "O", &objp))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* at least we know it's some object */
|
/* at least we know it's some object */
|
||||||
/* note DON't Py_DECREF args NEITHER objp */
|
/* note DON't Py_DECREF args */
|
||||||
|
|
||||||
if (PyInt_Check(objp)) {
|
|
||||||
long lval;
|
|
||||||
|
|
||||||
if (!PyArg_Parse(objp, "l", &lval))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
|
if (PyInt_Check(args)) {
|
||||||
|
long lval = PyInt_AS_LONG(args);
|
||||||
if (lval == (long)0) {
|
if (lval == (long)0) {
|
||||||
Py_INCREF(mpz_value_zero);
|
Py_INCREF(mpz_value_zero);
|
||||||
mpzp = mpz_value_zero;
|
mpzp = mpz_value_zero;
|
||||||
|
|
@ -866,7 +858,7 @@ MPZ_mpz(PyObject *self, PyObject *args)
|
||||||
return NULL;
|
return NULL;
|
||||||
else mpz_set_si(&mpzp->mpz, lval);
|
else mpz_set_si(&mpzp->mpz, lval);
|
||||||
}
|
}
|
||||||
else if (PyLong_Check(objp)) {
|
else if (PyLong_Check(args)) {
|
||||||
MP_INT mplongdigit;
|
MP_INT mplongdigit;
|
||||||
int i;
|
int i;
|
||||||
unsigned char isnegative;
|
unsigned char isnegative;
|
||||||
|
|
@ -880,13 +872,13 @@ MPZ_mpz(PyObject *self, PyObject *args)
|
||||||
|
|
||||||
/* how we're gonna handle this? */
|
/* how we're gonna handle this? */
|
||||||
if ((isnegative =
|
if ((isnegative =
|
||||||
((i = ((PyLongObject *)objp)->ob_size) < 0) ))
|
((i = ((PyLongObject *)args)->ob_size) < 0) ))
|
||||||
i = -i;
|
i = -i;
|
||||||
|
|
||||||
while (i--) {
|
while (i--) {
|
||||||
mpz_set_ui(&mplongdigit,
|
mpz_set_ui(&mplongdigit,
|
||||||
(unsigned long)
|
(unsigned long)
|
||||||
((PyLongObject *)objp)->ob_digit[i]);
|
((PyLongObject *)args)->ob_digit[i]);
|
||||||
mpz_mul_2exp(&mplongdigit,&mplongdigit,
|
mpz_mul_2exp(&mplongdigit,&mplongdigit,
|
||||||
(unsigned long int)i * SHIFT);
|
(unsigned long int)i * SHIFT);
|
||||||
mpz_ior(&mpzp->mpz, &mpzp->mpz, &mplongdigit);
|
mpz_ior(&mpzp->mpz, &mpzp->mpz, &mplongdigit);
|
||||||
|
|
@ -898,9 +890,9 @@ MPZ_mpz(PyObject *self, PyObject *args)
|
||||||
/* get rid of allocation for tmp variable */
|
/* get rid of allocation for tmp variable */
|
||||||
mpz_clear(&mplongdigit);
|
mpz_clear(&mplongdigit);
|
||||||
}
|
}
|
||||||
else if (PyString_Check(objp)) {
|
else if (PyString_Check(args)) {
|
||||||
unsigned char *cp = (unsigned char *)PyString_AS_STRING(objp);
|
unsigned char *cp = (unsigned char *)PyString_AS_STRING(args);
|
||||||
int len = PyString_GET_SIZE(objp);
|
int len = PyString_GET_SIZE(args);
|
||||||
MP_INT mplongdigit;
|
MP_INT mplongdigit;
|
||||||
|
|
||||||
if ((mpzp = newmpzobject()) == NULL)
|
if ((mpzp = newmpzobject()) == NULL)
|
||||||
|
|
@ -923,9 +915,9 @@ MPZ_mpz(PyObject *self, PyObject *args)
|
||||||
/* get rid of allocation for tmp variable */
|
/* get rid of allocation for tmp variable */
|
||||||
mpz_clear(&mplongdigit);
|
mpz_clear(&mplongdigit);
|
||||||
}
|
}
|
||||||
else if (is_mpzobject(objp)) {
|
else if (is_mpzobject(args)) {
|
||||||
Py_INCREF(objp);
|
Py_INCREF(args);
|
||||||
mpzp = (mpzobject *)objp;
|
mpzp = (mpzobject *)args;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
|
@ -973,7 +965,7 @@ MPZ_powm(PyObject *self, PyObject *args)
|
||||||
int tstres;
|
int tstres;
|
||||||
|
|
||||||
|
|
||||||
if (!PyArg_Parse(args, "(OOO)", &base, &exp, &mod))
|
if (!PyArg_ParseTuple(args, "OOO", &base, &exp, &mod))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if ((mpzbase = mpz_mpzcoerce(base)) == NULL
|
if ((mpzbase = mpz_mpzcoerce(base)) == NULL
|
||||||
|
|
@ -991,6 +983,14 @@ MPZ_powm(PyObject *self, PyObject *args)
|
||||||
return (PyObject *)mpz_value_one;
|
return (PyObject *)mpz_value_one;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mpz_cmp_ui(&mpzmod->mpz, 0) == 0) {
|
||||||
|
Py_DECREF(mpzbase);
|
||||||
|
Py_DECREF(mpzexp);
|
||||||
|
Py_DECREF(mpzmod);
|
||||||
|
PyErr_SetString(PyExc_ValueError, "modulus cannot be 0");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (tstres < 0) {
|
if (tstres < 0) {
|
||||||
MP_INT absexp;
|
MP_INT absexp;
|
||||||
/* negative exp */
|
/* negative exp */
|
||||||
|
|
@ -1023,7 +1023,7 @@ MPZ_gcd(PyObject *self, PyObject *args)
|
||||||
mpzobject *z;
|
mpzobject *z;
|
||||||
|
|
||||||
|
|
||||||
if (!PyArg_Parse(args, "(OO)", &op1, &op2))
|
if (!PyArg_ParseTuple(args, "OO", &op1, &op2))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
|
if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
|
||||||
|
|
@ -1052,7 +1052,7 @@ MPZ_gcdext(PyObject *self, PyObject *args)
|
||||||
mpzobject *g = NULL, *s = NULL, *t = NULL;
|
mpzobject *g = NULL, *s = NULL, *t = NULL;
|
||||||
|
|
||||||
|
|
||||||
if (!PyArg_Parse(args, "(OO)", &op1, &op2))
|
if (!PyArg_ParseTuple(args, "OO", &op1, &op2))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
|
if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
|
||||||
|
|
@ -1086,15 +1086,11 @@ MPZ_gcdext(PyObject *self, PyObject *args)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
MPZ_sqrt(PyObject *self, PyObject *args)
|
MPZ_sqrt(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
PyObject *op;
|
|
||||||
mpzobject *mpzop = NULL;
|
mpzobject *mpzop = NULL;
|
||||||
mpzobject *z;
|
mpzobject *z;
|
||||||
|
|
||||||
|
|
||||||
if (!PyArg_Parse(args, "O", &op))
|
if ((mpzop = mpz_mpzcoerce(args)) == NULL
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if ((mpzop = mpz_mpzcoerce(op)) == NULL
|
|
||||||
|| (z = newmpzobject()) == NULL) {
|
|| (z = newmpzobject()) == NULL) {
|
||||||
Py_XDECREF(mpzop);
|
Py_XDECREF(mpzop);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -1111,15 +1107,11 @@ MPZ_sqrt(PyObject *self, PyObject *args)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
MPZ_sqrtrem(PyObject *self, PyObject *args)
|
MPZ_sqrtrem(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
PyObject *op, *z = NULL;
|
PyObject *z = NULL;
|
||||||
mpzobject *mpzop = NULL;
|
mpzobject *mpzop = NULL;
|
||||||
mpzobject *root = NULL, *rem = NULL;
|
mpzobject *root = NULL, *rem = NULL;
|
||||||
|
|
||||||
|
if ((mpzop = mpz_mpzcoerce(args)) == NULL
|
||||||
if (!PyArg_Parse(args, "O", &op))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if ((mpzop = mpz_mpzcoerce(op)) == NULL
|
|
||||||
|| (z = PyTuple_New(2)) == NULL
|
|| (z = PyTuple_New(2)) == NULL
|
||||||
|| (root = newmpzobject()) == NULL
|
|| (root = newmpzobject()) == NULL
|
||||||
|| (rem = newmpzobject()) == NULL) {
|
|| (rem = newmpzobject()) == NULL) {
|
||||||
|
|
@ -1212,7 +1204,7 @@ MPZ_divm(PyObject *self, PyObject *args)
|
||||||
mpzobject *z = NULL;
|
mpzobject *z = NULL;
|
||||||
|
|
||||||
|
|
||||||
if (!PyArg_Parse(args, "(OOO)", &num, &den, &mod))
|
if (!PyArg_ParseTuple(args, "OOO", &num, &den, &mod))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if ((mpznum = mpz_mpzcoerce(num)) == NULL
|
if ((mpznum = mpz_mpzcoerce(num)) == NULL
|
||||||
|
|
@ -1550,17 +1542,17 @@ static PyTypeObject MPZtype = {
|
||||||
|
|
||||||
static PyMethodDef mpz_functions[] = {
|
static PyMethodDef mpz_functions[] = {
|
||||||
#if 0
|
#if 0
|
||||||
{initialiser_name, MPZ_mpz, METH_OLDARGS},
|
{initialiser_name, MPZ_mpz, METH_O},
|
||||||
#else /* 0 */
|
#else /* 0 */
|
||||||
/* until guido ``fixes'' struct PyMethodDef */
|
/* until guido ``fixes'' struct PyMethodDef */
|
||||||
{(char *)initialiser_name, MPZ_mpz, METH_OLDARGS},
|
{(char *)initialiser_name, MPZ_mpz, METH_O},
|
||||||
#endif /* 0 else */
|
#endif /* 0 else */
|
||||||
{"powm", MPZ_powm, METH_OLDARGS},
|
{"powm", MPZ_powm, METH_VARARGS},
|
||||||
{"gcd", MPZ_gcd, METH_OLDARGS},
|
{"gcd", MPZ_gcd, METH_VARARGS},
|
||||||
{"gcdext", MPZ_gcdext, METH_OLDARGS},
|
{"gcdext", MPZ_gcdext, METH_VARARGS},
|
||||||
{"sqrt", MPZ_sqrt, METH_OLDARGS},
|
{"sqrt", MPZ_sqrt, METH_O},
|
||||||
{"sqrtrem", MPZ_sqrtrem, METH_OLDARGS},
|
{"sqrtrem", MPZ_sqrtrem, METH_O},
|
||||||
{"divm", MPZ_divm, METH_OLDARGS},
|
{"divm", MPZ_divm, METH_VARARGS},
|
||||||
{NULL, NULL} /* Sentinel */
|
{NULL, NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue