Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 02098fa

Browse files
committed
Get rid of all METH_OLDARGS & PyArg_Parse.
Fix floating point exception if mpz.powm(10, 1, 0) (modulus == 0). Add a test.
1 parent 496563a commit 02098fa

2 files changed

Lines changed: 125 additions & 43 deletions

File tree

Lib/test/test_mpz.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
2+
import mpz
3+
from test_support import vereq
4+
5+
def check_conversion(num):
6+
mpz_num = mpz.mpz(num)
7+
vereq(int(mpz_num), num)
8+
vereq(long(mpz_num), num)
9+
vereq(str(mpz_num), 'mpz(%s)' % `int(num)`)
10+
11+
check_conversion(10)
12+
check_conversion(10L)
13+
# FIXME: should check strings, but I'm not sure it works, this seems odd:
14+
# mpz.mpz('10') == mpz(12337)
15+
16+
vereq(mpz.divm(100, 200, 3), 2)
17+
vereq(mpz.divm(100L, 200, 3), 2)
18+
vereq(mpz.divm(100, 200L, 3), 2)
19+
vereq(mpz.divm(100L, 200L, 3), 2)
20+
21+
vereq(mpz.gcd(100, 200), 100)
22+
vereq(mpz.gcd(100L, 200), 100)
23+
vereq(mpz.gcd(100, 200L), 100)
24+
vereq(mpz.gcd(100L, 200L), 100)
25+
26+
vereq(mpz.gcdext(100, 200), (100, 1, 0))
27+
vereq(mpz.gcdext(100L, 200), (100, 1, 0))
28+
vereq(mpz.gcdext(100, 200L), (100, 1, 0))
29+
vereq(mpz.gcdext(100L, 200L), (100, 1, 0))
30+
31+
vereq(mpz.powm(100, 0, 3), 1)
32+
vereq(mpz.powm(100L, 0, 3), 1)
33+
vereq(mpz.powm(100, 0L, 3), 1)
34+
vereq(mpz.powm(100L, 0L, 3), 1)
35+
36+
vereq(mpz.powm(101, 5, 3333), 1616)
37+
vereq(mpz.powm(101L, 5, 3333), 1616)
38+
vereq(mpz.powm(101, 5L, 3333), 1616)
39+
vereq(mpz.powm(101L, 5L, 3333), 1616)
40+
41+
vereq(mpz.sqrt(100), 10)
42+
vereq(mpz.sqrt(100L), 10)
43+
vereq(mpz.sqrt(200), 14)
44+
vereq(mpz.sqrt(200L), 14)
45+
46+
vereq(mpz.sqrtrem(100), (10, 0))
47+
vereq(mpz.sqrtrem(100L), (10, 0))
48+
vereq(mpz.sqrtrem(200), (14, 4))
49+
vereq(mpz.sqrtrem(200L), (14, 4))
50+
51+
try: mpz.mpz(10.)
52+
except TypeError: pass
53+
else: raise TestFailed, 'mpz(10.) should raise a TypeError'
54+
55+
try: mpz.powm(10.)
56+
except TypeError: pass
57+
else: raise TestFailed, 'powm(10.) should raise a TypeError'
58+
59+
try: mpz.powm(100, 1, 0)
60+
except ValueError: pass
61+
else: raise TestFailed, 'powm(100, 1, 0) should raise a ValueError'
62+
63+
try: mpz.divm(10, 10)
64+
except TypeError: pass
65+
else: raise TestFailed, 'divm(10, 10) should raise a TypeError'
66+
67+
try: mpz.divm(10, 10, 10.)
68+
except TypeError: pass
69+
else: raise TestFailed, 'divm(10, 10, 10.) should raise a TypeError'
70+
71+
try: mpz.gcd(10)
72+
except TypeError: pass
73+
else: raise TestFailed, 'gcd(10) should raise a TypeError'
74+
75+
try: mpz.gcd(10, 10.)
76+
except TypeError: pass
77+
else: raise TestFailed, 'gcd(10, 10.) should raise a TypeError'
78+
79+
try: mpz.gcdext(10)
80+
except TypeError: pass
81+
else: raise TestFailed, 'gcdext(10) should raise a TypeError'
82+
83+
try: mpz.gcdext(10, 10.)
84+
except TypeError: pass
85+
else: raise TestFailed, 'gcdext(10, 10.) should raise a TypeError'
86+
87+
try: mpz.mpz(-10).binary()
88+
except ValueError: pass
89+
else: raise TestFailed, 'mpz(-10).binary() should raise a ValueError'
90+

Modules/mpzmodule.c

Lines changed: 35 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -835,25 +835,17 @@ static PyObject *
835835
MPZ_mpz(PyObject *self, PyObject *args)
836836
{
837837
mpzobject *mpzp;
838-
PyObject *objp;
839838

840839

841840
#ifdef MPZ_DEBUG
842841
fputs("MPZ_mpz() called...\n", stderr);
843842
#endif /* def MPZ_DEBUG */
844843

845-
if (!PyArg_Parse(args, "O", &objp))
846-
return NULL;
847-
848844
/* at least we know it's some object */
849-
/* note DON't Py_DECREF args NEITHER objp */
850-
851-
if (PyInt_Check(objp)) {
852-
long lval;
853-
854-
if (!PyArg_Parse(objp, "l", &lval))
855-
return NULL;
845+
/* note DON't Py_DECREF args */
856846

847+
if (PyInt_Check(args)) {
848+
long lval = PyInt_AS_LONG(args);
857849
if (lval == (long)0) {
858850
Py_INCREF(mpz_value_zero);
859851
mpzp = mpz_value_zero;
@@ -866,7 +858,7 @@ MPZ_mpz(PyObject *self, PyObject *args)
866858
return NULL;
867859
else mpz_set_si(&mpzp->mpz, lval);
868860
}
869-
else if (PyLong_Check(objp)) {
861+
else if (PyLong_Check(args)) {
870862
MP_INT mplongdigit;
871863
int i;
872864
unsigned char isnegative;
@@ -880,13 +872,13 @@ MPZ_mpz(PyObject *self, PyObject *args)
880872

881873
/* how we're gonna handle this? */
882874
if ((isnegative =
883-
((i = ((PyLongObject *)objp)->ob_size) < 0) ))
875+
((i = ((PyLongObject *)args)->ob_size) < 0) ))
884876
i = -i;
885877

886878
while (i--) {
887879
mpz_set_ui(&mplongdigit,
888880
(unsigned long)
889-
((PyLongObject *)objp)->ob_digit[i]);
881+
((PyLongObject *)args)->ob_digit[i]);
890882
mpz_mul_2exp(&mplongdigit,&mplongdigit,
891883
(unsigned long int)i * SHIFT);
892884
mpz_ior(&mpzp->mpz, &mpzp->mpz, &mplongdigit);
@@ -898,9 +890,9 @@ MPZ_mpz(PyObject *self, PyObject *args)
898890
/* get rid of allocation for tmp variable */
899891
mpz_clear(&mplongdigit);
900892
}
901-
else if (PyString_Check(objp)) {
902-
unsigned char *cp = (unsigned char *)PyString_AS_STRING(objp);
903-
int len = PyString_GET_SIZE(objp);
893+
else if (PyString_Check(args)) {
894+
unsigned char *cp = (unsigned char *)PyString_AS_STRING(args);
895+
int len = PyString_GET_SIZE(args);
904896
MP_INT mplongdigit;
905897

906898
if ((mpzp = newmpzobject()) == NULL)
@@ -923,9 +915,9 @@ MPZ_mpz(PyObject *self, PyObject *args)
923915
/* get rid of allocation for tmp variable */
924916
mpz_clear(&mplongdigit);
925917
}
926-
else if (is_mpzobject(objp)) {
927-
Py_INCREF(objp);
928-
mpzp = (mpzobject *)objp;
918+
else if (is_mpzobject(args)) {
919+
Py_INCREF(args);
920+
mpzp = (mpzobject *)args;
929921
}
930922
else {
931923
PyErr_SetString(PyExc_TypeError,
@@ -973,7 +965,7 @@ MPZ_powm(PyObject *self, PyObject *args)
973965
int tstres;
974966

975967

976-
if (!PyArg_Parse(args, "(OOO)", &base, &exp, &mod))
968+
if (!PyArg_ParseTuple(args, "OOO", &base, &exp, &mod))
977969
return NULL;
978970

979971
if ((mpzbase = mpz_mpzcoerce(base)) == NULL
@@ -991,6 +983,14 @@ MPZ_powm(PyObject *self, PyObject *args)
991983
return (PyObject *)mpz_value_one;
992984
}
993985

986+
if (mpz_cmp_ui(&mpzmod->mpz, 0) == 0) {
987+
Py_DECREF(mpzbase);
988+
Py_DECREF(mpzexp);
989+
Py_DECREF(mpzmod);
990+
PyErr_SetString(PyExc_ValueError, "modulus cannot be 0");
991+
return NULL;
992+
}
993+
994994
if (tstres < 0) {
995995
MP_INT absexp;
996996
/* negative exp */
@@ -1023,7 +1023,7 @@ MPZ_gcd(PyObject *self, PyObject *args)
10231023
mpzobject *z;
10241024

10251025

1026-
if (!PyArg_Parse(args, "(OO)", &op1, &op2))
1026+
if (!PyArg_ParseTuple(args, "OO", &op1, &op2))
10271027
return NULL;
10281028

10291029
if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
@@ -1052,7 +1052,7 @@ MPZ_gcdext(PyObject *self, PyObject *args)
10521052
mpzobject *g = NULL, *s = NULL, *t = NULL;
10531053

10541054

1055-
if (!PyArg_Parse(args, "(OO)", &op1, &op2))
1055+
if (!PyArg_ParseTuple(args, "OO", &op1, &op2))
10561056
return NULL;
10571057

10581058
if ((mpzop1 = mpz_mpzcoerce(op1)) == NULL
@@ -1086,15 +1086,11 @@ MPZ_gcdext(PyObject *self, PyObject *args)
10861086
static PyObject *
10871087
MPZ_sqrt(PyObject *self, PyObject *args)
10881088
{
1089-
PyObject *op;
10901089
mpzobject *mpzop = NULL;
10911090
mpzobject *z;
10921091

10931092

1094-
if (!PyArg_Parse(args, "O", &op))
1095-
return NULL;
1096-
1097-
if ((mpzop = mpz_mpzcoerce(op)) == NULL
1093+
if ((mpzop = mpz_mpzcoerce(args)) == NULL
10981094
|| (z = newmpzobject()) == NULL) {
10991095
Py_XDECREF(mpzop);
11001096
return NULL;
@@ -1111,15 +1107,11 @@ MPZ_sqrt(PyObject *self, PyObject *args)
11111107
static PyObject *
11121108
MPZ_sqrtrem(PyObject *self, PyObject *args)
11131109
{
1114-
PyObject *op, *z = NULL;
1110+
PyObject *z = NULL;
11151111
mpzobject *mpzop = NULL;
11161112
mpzobject *root = NULL, *rem = NULL;
11171113

1118-
1119-
if (!PyArg_Parse(args, "O", &op))
1120-
return NULL;
1121-
1122-
if ((mpzop = mpz_mpzcoerce(op)) == NULL
1114+
if ((mpzop = mpz_mpzcoerce(args)) == NULL
11231115
|| (z = PyTuple_New(2)) == NULL
11241116
|| (root = newmpzobject()) == NULL
11251117
|| (rem = newmpzobject()) == NULL) {
@@ -1212,7 +1204,7 @@ MPZ_divm(PyObject *self, PyObject *args)
12121204
mpzobject *z = NULL;
12131205

12141206

1215-
if (!PyArg_Parse(args, "(OOO)", &num, &den, &mod))
1207+
if (!PyArg_ParseTuple(args, "OOO", &num, &den, &mod))
12161208
return NULL;
12171209

12181210
if ((mpznum = mpz_mpzcoerce(num)) == NULL
@@ -1550,17 +1542,17 @@ static PyTypeObject MPZtype = {
15501542

15511543
static PyMethodDef mpz_functions[] = {
15521544
#if 0
1553-
{initialiser_name, MPZ_mpz, METH_OLDARGS},
1545+
{initialiser_name, MPZ_mpz, METH_O},
15541546
#else /* 0 */
15551547
/* until guido ``fixes'' struct PyMethodDef */
1556-
{(char *)initialiser_name, MPZ_mpz, METH_OLDARGS},
1548+
{(char *)initialiser_name, MPZ_mpz, METH_O},
15571549
#endif /* 0 else */
1558-
{"powm", MPZ_powm, METH_OLDARGS},
1559-
{"gcd", MPZ_gcd, METH_OLDARGS},
1560-
{"gcdext", MPZ_gcdext, METH_OLDARGS},
1561-
{"sqrt", MPZ_sqrt, METH_OLDARGS},
1562-
{"sqrtrem", MPZ_sqrtrem, METH_OLDARGS},
1563-
{"divm", MPZ_divm, METH_OLDARGS},
1550+
{"powm", MPZ_powm, METH_VARARGS},
1551+
{"gcd", MPZ_gcd, METH_VARARGS},
1552+
{"gcdext", MPZ_gcdext, METH_VARARGS},
1553+
{"sqrt", MPZ_sqrt, METH_O},
1554+
{"sqrtrem", MPZ_sqrtrem, METH_O},
1555+
{"divm", MPZ_divm, METH_VARARGS},
15641556
{NULL, NULL} /* Sentinel */
15651557
};
15661558

0 commit comments

Comments
 (0)