summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2001-09-10 20:52:51 (GMT)
committerTim Peters <tim.peters@gmail.com>2001-09-10 20:52:51 (GMT)
commit64b5ce3a69569b203a39f74c5c03348ba0a67583 (patch)
tree87f71bc6ef25a7b7e11087afb1d7827bbcc4d474 /Objects
parent8b4e43e768f3f49513f6f32f20ecb6478c1ad840 (diff)
downloadcpython-64b5ce3a69569b203a39f74c5c03348ba0a67583.zip
cpython-64b5ce3a69569b203a39f74c5c03348ba0a67583.tar.gz
cpython-64b5ce3a69569b203a39f74c5c03348ba0a67583.tar.bz2
SF bug #460020: bug or feature: unicode() and subclasses.
Given an immutable type M, and an instance I of a subclass of M, the constructor call M(I) was just returning I as-is; but it should return a new instance of M. This fixes it for M in {int, long}. Strings, floats and tuples remain to be done. Added new macros PyInt_CheckExact and PyLong_CheckExact, to more easily distinguish between "is" and "is a" (i.e., only an int passes PyInt_CheckExact, while any sublass of int passes PyInt_Check). Added private API function _PyLong_Copy.
Diffstat (limited to 'Objects')
-rw-r--r--Objects/abstract.c11
-rw-r--r--Objects/longobject.c21
2 files changed, 29 insertions, 3 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c
index 5361b1d..2bd0fcc 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -4,6 +4,7 @@
#include "Python.h"
#include <ctype.h>
#include "structmember.h" /* we need the offsetof() macro from there */
+#include "longintrepr.h"
#define NEW_STYLE_NUMBER(o) PyType_HasFeature((o)->ob_type, \
Py_TPFLAGS_CHECKTYPES)
@@ -818,10 +819,14 @@ PyNumber_Int(PyObject *o)
if (o == NULL)
return null_error();
- if (PyInt_Check(o)) {
+ if (PyInt_CheckExact(o)) {
Py_INCREF(o);
return o;
}
+ if (PyInt_Check(o)) {
+ PyIntObject *io = (PyIntObject*)o;
+ return PyInt_FromLong(io->ob_ival);
+ }
if (PyString_Check(o))
return int_from_string(PyString_AS_STRING(o),
PyString_GET_SIZE(o));
@@ -868,10 +873,12 @@ PyNumber_Long(PyObject *o)
if (o == NULL)
return null_error();
- if (PyLong_Check(o)) {
+ if (PyLong_CheckExact(o)) {
Py_INCREF(o);
return o;
}
+ if (PyLong_Check(o))
+ return _PyLong_Copy((PyLongObject *)o);
if (PyString_Check(o))
/* need to do extra error checking that PyLong_FromString()
* doesn't do. In particular long('9.5') must raise an
diff --git a/Objects/longobject.c b/Objects/longobject.c
index c7608aa..b9271e6 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -51,6 +51,25 @@ _PyLong_New(int size)
return PyObject_NEW_VAR(PyLongObject, &PyLong_Type, size);
}
+PyObject *
+_PyLong_Copy(PyLongObject *src)
+{
+ PyLongObject *result;
+ int i;
+
+ assert(src != NULL);
+ i = src->ob_size;
+ if (i < 0)
+ i = -(i);
+ result = _PyLong_New(i);
+ if (result != NULL) {
+ result->ob_size = i;
+ while (--i >= 0)
+ result->ob_digit[i] = src->ob_digit[i];
+ }
+ return (PyObject *)result;
+}
+
/* Create a new long int object from a C long int */
PyObject *
@@ -2205,7 +2224,7 @@ long_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
tmp = (PyLongObject *)long_new(&PyLong_Type, args, kwds);
if (tmp == NULL)
return NULL;
- assert(PyLong_Check(tmp));
+ assert(PyLong_CheckExact(tmp));
n = tmp->ob_size;
if (n < 0)
n = -n;