Merged the int/long unification branch, by very crude means (sorry Thomas!).

I banged on the code (beyond what's in that branch) to make fewer tests fail;
the only tests that fail now are:
  test_descr -- can't pickle ints?!
  test_pickletools -- ???
  test_socket -- See python.org/sf/1619659
  test_sqlite -- ???
I'll deal with those later.
This commit is contained in:
Guido van Rossum 2007-01-14 03:31:43 +00:00
parent 5b787e8bc2
commit ddefaf31b3
46 changed files with 798 additions and 404 deletions

View file

@ -219,7 +219,7 @@ _set_int(const char *name, int *target, PyObject *src, int dflt)
if (src == NULL)
*target = dflt;
else {
if (!PyInt_Check(src)) {
if (!PyInt_CheckExact(src)) {
PyErr_Format(PyExc_TypeError,
"\"%s\" must be an integer", name);
return -1;
@ -1410,7 +1410,7 @@ csv_field_size_limit(PyObject *module, PyObject *args)
if (!PyArg_UnpackTuple(args, "field_size_limit", 0, 1, &new_limit))
return NULL;
if (new_limit != NULL) {
if (!PyInt_Check(new_limit)) {
if (!PyInt_CheckExact(new_limit)) {
PyErr_Format(PyExc_TypeError,
"limit must be an integer");
return NULL;

View file

@ -991,7 +991,7 @@ ArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return NULL;
proto = PyDict_GetItemString(typedict, "_length_"); /* Borrowed ref */
if (!proto || !PyInt_Check(proto)) {
if (!proto || !PyInt_CheckExact(proto)) {
PyErr_SetString(PyExc_AttributeError,
"class must define a '_length_' attribute, "
"which must be a positive integer");

View file

@ -496,12 +496,6 @@ static int ConvParam(PyObject *obj, int index, struct argument *pa)
return 0;
}
if (PyInt_Check(obj)) {
pa->ffi_type = &ffi_type_sint;
pa->value.i = PyInt_AS_LONG(obj);
return 0;
}
if (PyLong_Check(obj)) {
pa->ffi_type = &ffi_type_sint;
pa->value.i = (long)PyLong_AsUnsignedLong(obj);

View file

@ -193,7 +193,7 @@ PyCursesCheckERR(int code, char *fname)
static int
PyCurses_ConvertToChtype(PyObject *obj, chtype *ch)
{
if (PyInt_Check(obj)) {
if (PyInt_CheckExact(obj)) {
*ch = (chtype) PyInt_AsLong(obj);
} else if(PyString_Check(obj)
&& (PyString_Size(obj) == 1)) {
@ -2364,7 +2364,7 @@ PyCurses_UnCtrl(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args,"O;ch or int",&temp)) return NULL;
if (PyInt_Check(temp))
if (PyInt_CheckExact(temp))
ch = (chtype) PyInt_AsLong(temp);
else if (PyString_Check(temp))
ch = (chtype) *PyString_AsString(temp);
@ -2386,7 +2386,7 @@ PyCurses_UngetCh(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args,"O;ch or int",&temp)) return NULL;
if (PyInt_Check(temp))
if (PyInt_CheckExact(temp))
ch = (int) PyInt_AsLong(temp);
else if (PyString_Check(temp))
ch = (int) *PyString_AsString(temp);

View file

@ -2688,8 +2688,7 @@ _compile(PyObject* self_, PyObject* args)
for (i = 0; i < n; i++) {
PyObject *o = PyList_GET_ITEM(code, i);
unsigned long value = PyInt_Check(o) ? (unsigned long)PyInt_AsLong(o)
: PyLong_AsUnsignedLong(o);
unsigned long value = PyLong_AsUnsignedLong(o);
self->code[i] = (SRE_CODE) value;
if ((unsigned long) self->code[i] != value) {
PyErr_SetString(PyExc_OverflowError,
@ -2763,6 +2762,10 @@ match_getindex(MatchObject* self, PyObject* index)
{
Py_ssize_t i;
if (index == NULL)
/* Default value */
return 0;
if (PyInt_Check(index))
return PyInt_AsSsize_t(index);
@ -2913,7 +2916,7 @@ match_start(MatchObject* self, PyObject* args)
{
Py_ssize_t index;
PyObject* index_ = Py_False; /* zero */
PyObject* index_ = NULL;
if (!PyArg_UnpackTuple(args, "start", 0, 1, &index_))
return NULL;
@ -2936,7 +2939,7 @@ match_end(MatchObject* self, PyObject* args)
{
Py_ssize_t index;
PyObject* index_ = Py_False; /* zero */
PyObject* index_ = NULL;
if (!PyArg_UnpackTuple(args, "end", 0, 1, &index_))
return NULL;
@ -2986,7 +2989,7 @@ match_span(MatchObject* self, PyObject* args)
{
Py_ssize_t index;
PyObject* index_ = Py_False; /* zero */
PyObject* index_ = NULL;
if (!PyArg_UnpackTuple(args, "span", 0, 1, &index_))
return NULL;

View file

@ -118,8 +118,6 @@ get_pylong(PyObject *v)
PyNumberMethods *m;
assert(v != NULL);
if (PyInt_Check(v))
return PyLong_FromLong(PyInt_AS_LONG(v));
if (PyLong_Check(v)) {
Py_INCREF(v);
return v;

View file

@ -718,6 +718,119 @@ test_with_docstring(PyObject *self)
Py_RETURN_NONE;
}
#ifdef HAVE_GETTIMEOFDAY
/* Profiling of integer performance */
void print_delta(int test, struct timeval *s, struct timeval *e)
{
e->tv_sec -= s->tv_sec;
e->tv_usec -= s->tv_usec;
if (e->tv_usec < 0) {
e->tv_sec -=1;
e->tv_usec += 1000000;
}
printf("Test %d: %d.%06ds\n", test, (int)e->tv_sec, e->tv_usec);
}
static PyObject *
profile_int(PyObject *self, PyObject* args)
{
int i, k;
struct timeval start, stop;
PyObject *single, **multiple, *op1, *result;
/* Test 1: Allocate and immediately deallocate
many small integers */
gettimeofday(&start, NULL);
for(k=0; k < 20000; k++)
for(i=0; i < 1000; i++) {
single = PyInt_FromLong(i);
Py_DECREF(single);
}
gettimeofday(&stop, NULL);
print_delta(1, &start, &stop);
/* Test 2: Allocate and immediately deallocate
many large integers */
gettimeofday(&start, NULL);
for(k=0; k < 20000; k++)
for(i=0; i < 1000; i++) {
single = PyInt_FromLong(i+1000000);
Py_DECREF(single);
}
gettimeofday(&stop, NULL);
print_delta(2, &start, &stop);
/* Test 3: Allocate a few integers, then release
them all simultaneously. */
multiple = malloc(sizeof(PyObject*) * 1000);
gettimeofday(&start, NULL);
for(k=0; k < 20000; k++) {
for(i=0; i < 1000; i++) {
multiple[i] = PyInt_FromLong(i+1000000);
}
for(i=0; i < 1000; i++) {
Py_DECREF(multiple[i]);
}
}
gettimeofday(&stop, NULL);
print_delta(3, &start, &stop);
/* Test 4: Allocate many integers, then release
them all simultaneously. */
multiple = malloc(sizeof(PyObject*) * 1000000);
gettimeofday(&start, NULL);
for(k=0; k < 20; k++) {
for(i=0; i < 1000000; i++) {
multiple[i] = PyInt_FromLong(i+1000000);
}
for(i=0; i < 1000000; i++) {
Py_DECREF(multiple[i]);
}
}
gettimeofday(&stop, NULL);
print_delta(4, &start, &stop);
/* Test 5: Allocate many integers < 32000 */
multiple = malloc(sizeof(PyObject*) * 1000000);
gettimeofday(&start, NULL);
for(k=0; k < 10; k++) {
for(i=0; i < 1000000; i++) {
multiple[i] = PyInt_FromLong(i+1000);
}
for(i=0; i < 1000000; i++) {
Py_DECREF(multiple[i]);
}
}
gettimeofday(&stop, NULL);
print_delta(5, &start, &stop);
/* Test 6: Perform small int addition */
op1 = PyInt_FromLong(1);
gettimeofday(&start, NULL);
for(i=0; i < 10000000; i++) {
result = PyNumber_Add(op1, op1);
Py_DECREF(result);
}
gettimeofday(&stop, NULL);
Py_DECREF(op1);
print_delta(6, &start, &stop);
/* Test 7: Perform medium int addition */
op1 = PyInt_FromLong(1000);
gettimeofday(&start, NULL);
for(i=0; i < 10000000; i++) {
result = PyNumber_Add(op1, op1);
Py_DECREF(result);
}
gettimeofday(&stop, NULL);
Py_DECREF(op1);
print_delta(7, &start, &stop);
Py_INCREF(Py_None);
return Py_None;
}
#endif
static PyMethodDef TestMethods[] = {
{"raise_exception", raise_exception, METH_VARARGS},
{"test_config", (PyCFunction)test_config, METH_NOARGS},
@ -755,6 +868,9 @@ static PyMethodDef TestMethods[] = {
#endif
#ifdef WITH_THREAD
{"_test_thread_state", test_thread_state, METH_VARARGS},
#endif
#ifdef HAVE_GETTIMEOFDAY
{"profile_int", profile_int, METH_NOARGS},
#endif
{NULL, NULL} /* sentinel */
};

View file

@ -913,7 +913,7 @@ AsObj(PyObject *value)
PyString_GET_SIZE(value));
else if (PyBool_Check(value))
return Tcl_NewBooleanObj(PyObject_IsTrue(value));
else if (PyInt_Check(value))
else if (PyInt_CheckExact(value))
return Tcl_NewLongObj(PyInt_AS_LONG(value));
else if (PyFloat_Check(value))
return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));

View file

@ -711,7 +711,9 @@ get(Picklerobject *self, PyObject *id)
PyErr_SetString(PicklingError, "no int where int expected in memo");
return -1;
}
c_value = PyInt_AS_LONG((PyIntObject*)value);
c_value = PyInt_AsLong(value);
if (c_value == -1 && PyErr_Occurred())
return -1;
if (!self->bin) {
s[0] = GET;
@ -958,7 +960,7 @@ save_bool(Picklerobject *self, PyObject *args)
{
static const char *buf[2] = {FALSE, TRUE};
static char len[2] = {sizeof(FALSE)-1, sizeof(TRUE)-1};
long l = PyInt_AS_LONG((PyIntObject *)args);
long l = args == Py_True;
if (self->proto >= 2) {
char opcode = l ? NEWTRUE : NEWFALSE;
@ -971,10 +973,9 @@ save_bool(Picklerobject *self, PyObject *args)
}
static int
save_int(Picklerobject *self, PyObject *args)
save_int(Picklerobject *self, long l)
{
char c_str[32];
long l = PyInt_AS_LONG((PyIntObject *)args);
int len = 0;
if (!self->bin
@ -1027,9 +1028,16 @@ save_long(Picklerobject *self, PyObject *args)
Py_ssize_t size;
int res = -1;
PyObject *repr = NULL;
int val = PyInt_AsLong(args);
static char l = LONG;
if (val == -1 && PyErr_Occurred()) {
/* out of range for int pickling */
PyErr_Clear();
}
else
return save_int(self, val);
if (self->proto >= 2) {
/* Linear-time pickling. */
size_t nbits;
@ -2183,13 +2191,6 @@ save(Picklerobject *self, PyObject *args, int pers_save)
goto finally;
}
break;
case 'i':
if (type == &PyInt_Type) {
res = save_int(self, args);
goto finally;
}
break;
case 'l':
if (type == &PyLong_Type) {
res = save_long(self, args);
@ -2486,7 +2487,9 @@ Pickle_getvalue(Picklerobject *self, PyObject *args)
rsize += PyString_GET_SIZE(k);
else if (PyInt_Check(k)) { /* put */
ik = PyInt_AS_LONG((PyIntObject*)k);
ik = PyInt_AsLong(k);
if (ik == -1 && PyErr_Occurred())
goto err;
if (ik >= lm || ik == 0) {
PyErr_SetString(PicklingError,
"Invalid get data");
@ -2506,7 +2509,9 @@ Pickle_getvalue(Picklerobject *self, PyObject *args)
}
else { /* put */
ik = PyInt_AS_LONG((PyIntObject *)k);
ik = PyInt_AsLong(k);
if (ik == -1 && PyErr_Occurred())
goto err;
if (ik >= lm || ik == 0) {
PyErr_SetString(PicklingError,
"Invalid get data");
@ -2535,8 +2540,9 @@ Pickle_getvalue(Picklerobject *self, PyObject *args)
}
else if (PyTuple_Check(k)) { /* get */
ik = PyInt_AS_LONG((PyIntObject *)
PyTuple_GET_ITEM(k, 0));
ik = PyLong_AsLong(PyTuple_GET_ITEM(k, 0));
if (ik == -1 && PyErr_Occurred())
goto err;
if (ik < 256) {
*s++ = BINGET;
*s++ = (int)(ik & 0xff);
@ -2551,7 +2557,9 @@ Pickle_getvalue(Picklerobject *self, PyObject *args)
}
else { /* put */
ik = PyInt_AS_LONG((PyIntObject*)k);
ik = PyLong_AsLong(k);
if (ik == -1 && PyErr_Occurred())
goto err;
if (have_get[ik]) { /* with matching get */
if (ik < 256) {

View file

@ -1314,6 +1314,9 @@ mbstreamreader_read(MultibyteStreamReaderObject *self, PyObject *args)
return NULL;
}
if (size == -1 && PyErr_Occurred())
return NULL;
return mbstreamreader_iread(self, "read", size);
}
@ -1335,6 +1338,9 @@ mbstreamreader_readline(MultibyteStreamReaderObject *self, PyObject *args)
return NULL;
}
if (size == -1 && PyErr_Occurred())
return NULL;
return mbstreamreader_iread(self, "readline", size);
}
@ -1356,6 +1362,9 @@ mbstreamreader_readlines(MultibyteStreamReaderObject *self, PyObject *args)
return NULL;
}
if (sizehint == -1 && PyErr_Occurred())
return NULL;
r = mbstreamreader_iread(self, "read", sizehint);
if (r == NULL)
return NULL;

View file

@ -1844,10 +1844,7 @@ accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
* lose a little info.
*/
assert(PyInt_Check(factor) || PyLong_Check(factor));
if (PyInt_Check(factor))
dnum = (double)PyInt_AsLong(factor);
else
dnum = PyLong_AsDouble(factor);
dnum = PyLong_AsDouble(factor);
dnum *= fracpart;
fracpart = modf(dnum, &intpart);
@ -3800,7 +3797,7 @@ datetime_strptime(PyObject *cls, PyObject *args)
Py_DECREF(obj);
return NULL;
}
if (PyInt_Check(p))
if (PyInt_CheckExact(p))
ia[i] = PyInt_AsLong(p);
else
good_timetuple = 0;

View file

@ -107,9 +107,11 @@ dl_call(dlobject *xp, PyObject *args)
}
for (i = 1; i < n; i++) {
PyObject *v = PyTuple_GetItem(args, i);
if (PyInt_Check(v))
if (PyInt_Check(v)) {
alist[i-1] = PyInt_AsLong(v);
else if (PyString_Check(v))
if (alist[i-1] == -1 && PyErr_Occurred())
return NULL;
} else if (PyString_Check(v))
alist[i-1] = (long)PyString_AsString(v);
else if (v == Py_None)
alist[i-1] = (long) ((char *)NULL);

View file

@ -5437,32 +5437,21 @@ posix_setgroups(PyObject *self, PyObject *groups)
elem = PySequence_GetItem(groups, i);
if (!elem)
return NULL;
if (!PyInt_Check(elem)) {
if (!PyLong_Check(elem)) {
PyErr_SetString(PyExc_TypeError,
"groups must be integers");
if (!PyLong_Check(elem)) {
PyErr_SetString(PyExc_TypeError,
"groups must be integers");
Py_DECREF(elem);
return NULL;
} else {
unsigned long x = PyLong_AsUnsignedLong(elem);
if (PyErr_Occurred()) {
PyErr_SetString(PyExc_TypeError,
"group id too big");
Py_DECREF(elem);
return NULL;
} else {
unsigned long x = PyLong_AsUnsignedLong(elem);
if (PyErr_Occurred()) {
PyErr_SetString(PyExc_TypeError,
"group id too big");
Py_DECREF(elem);
return NULL;
}
grouplist[i] = x;
/* read back the value to see if it fitted in gid_t */
if (grouplist[i] != x) {
PyErr_SetString(PyExc_TypeError,
"group id too big");
Py_DECREF(elem);
return NULL;
}
}
} else {
long x = PyInt_AsLong(elem);
grouplist[i] = x;
/* read back the value to see if it fitted in gid_t */
if (grouplist[i] != x) {
PyErr_SetString(PyExc_TypeError,
"group id too big");

View file

@ -3483,12 +3483,7 @@ socket_ntohl(PyObject *self, PyObject *arg)
{
unsigned long x;
if (PyInt_Check(arg)) {
x = PyInt_AS_LONG(arg);
if (x == (unsigned long) -1 && PyErr_Occurred())
return NULL;
}
else if (PyLong_Check(arg)) {
if (PyLong_Check(arg)) {
x = PyLong_AsUnsignedLong(arg);
if (x == (unsigned long) -1 && PyErr_Occurred())
return NULL;
@ -3542,12 +3537,7 @@ socket_htonl(PyObject *self, PyObject *arg)
{
unsigned long x;
if (PyInt_Check(arg)) {
x = PyInt_AS_LONG(arg);
if (x == (unsigned long) -1 && PyErr_Occurred())
return NULL;
}
else if (PyLong_Check(arg)) {
if (PyLong_Check(arg)) {
x = PyLong_AsUnsignedLong(arg);
if (x == (unsigned long) -1 && PyErr_Occurred())
return NULL;
@ -3827,7 +3817,7 @@ socket_getaddrinfo(PyObject *self, PyObject *args)
"getaddrinfo() argument 1 must be string or None");
return NULL;
}
if (PyInt_Check(pobj)) {
if (PyInt_CheckExact(pobj)) {
PyOS_snprintf(pbuf, sizeof(pbuf), "%ld", PyInt_AsLong(pobj));
pptr = pbuf;
} else if (PyString_Check(pobj)) {

View file

@ -357,7 +357,7 @@ gettmarg(PyObject *args, struct tm *p)
if (y < 1900) {
PyObject *accept = PyDict_GetItemString(moddict,
"accept2dyear");
if (accept == NULL || !PyInt_Check(accept) ||
if (accept == NULL || !PyInt_CheckExact(accept) ||
PyInt_AsLong(accept) == 0) {
PyErr_SetString(PyExc_ValueError,
"year >= 1900 required");