Commit 8fdadfd8 authored by Marius Wachtler's avatar Marius Wachtler

Implement long.__int__()

parent 9cd8624a
...@@ -750,7 +750,7 @@ extern "C" Box* intOct(BoxedInt* self) { ...@@ -750,7 +750,7 @@ extern "C" Box* intOct(BoxedInt* self) {
return new BoxedString(std::string(buf, len)); return new BoxedString(std::string(buf, len));
} }
BoxedInt* _intNew(Box* val) { Box* _intNew(Box* val) {
if (isSubclass(val->cls, int_cls)) { if (isSubclass(val->cls, int_cls)) {
BoxedInt* n = static_cast<BoxedInt*>(val); BoxedInt* n = static_cast<BoxedInt*>(val);
if (val->cls == int_cls) if (val->cls == int_cls)
...@@ -776,10 +776,10 @@ BoxedInt* _intNew(Box* val) { ...@@ -776,10 +776,10 @@ BoxedInt* _intNew(Box* val) {
raiseExcHelper(TypeError, ""); raiseExcHelper(TypeError, "");
} }
if (!isSubclass(r->cls, int_cls)) { if (!isSubclass(r->cls, int_cls) && !isSubclass(r->cls, long_cls)) {
raiseExcHelper(TypeError, "__int__ returned non-int (type %s)", r->cls->tp_name); raiseExcHelper(TypeError, "__int__ returned non-int (type %s)", r->cls->tp_name);
} }
return static_cast<BoxedInt*>(r); return r;
} }
} }
...@@ -795,8 +795,13 @@ extern "C" Box* intNew(Box* _cls, Box* val) { ...@@ -795,8 +795,13 @@ extern "C" Box* intNew(Box* _cls, Box* val) {
if (cls == int_cls) if (cls == int_cls)
return _intNew(val); return _intNew(val);
BoxedInt* n = _intNew(val); BoxedInt* n = (BoxedInt*)_intNew(val);
if (n->cls == long_cls) {
if (cls == int_cls)
return n;
raiseExcHelper(OverflowError, "Python int too large to convert to C long", getNameOfClass(cls),
getNameOfClass(cls));
}
return new (cls) BoxedInt(n->n); return new (cls) BoxedInt(n->n);
} }
......
...@@ -405,6 +405,19 @@ extern "C" Box* longNew(Box* _cls, Box* val, Box* _base) { ...@@ -405,6 +405,19 @@ extern "C" Box* longNew(Box* _cls, Box* val, Box* _base) {
return rtn; return rtn;
} }
Box* longInt(Box* v) {
if (!isSubclass(v->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__int__' requires a 'long' object but received a '%s'", getTypeName(v));
int overflow = 0;
long n = PyLong_AsLongAndOverflow(v, &overflow);
static_assert(sizeof(BoxedInt::n) == sizeof(long), "");
if (overflow)
return v;
else
return new BoxedInt(n);
}
Box* longRepr(BoxedLong* v) { Box* longRepr(BoxedLong* v) {
if (!isSubclass(v->cls, long_cls)) if (!isSubclass(v->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__repr__' requires a 'long' object but received a '%s'", getTypeName(v)); raiseExcHelper(TypeError, "descriptor '__repr__' requires a 'long' object but received a '%s'", getTypeName(v));
...@@ -930,6 +943,7 @@ void setupLong() { ...@@ -930,6 +943,7 @@ void setupLong() {
long_cls->giveAttr("__lshift__", new BoxedFunction(boxRTFunction((void*)longLshift, UNKNOWN, 2))); long_cls->giveAttr("__lshift__", new BoxedFunction(boxRTFunction((void*)longLshift, UNKNOWN, 2)));
long_cls->giveAttr("__rshift__", new BoxedFunction(boxRTFunction((void*)longRshift, UNKNOWN, 2))); long_cls->giveAttr("__rshift__", new BoxedFunction(boxRTFunction((void*)longRshift, UNKNOWN, 2)));
long_cls->giveAttr("__int__", new BoxedFunction(boxRTFunction((void*)longInt, UNKNOWN, 1)));
long_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)longRepr, STR, 1))); long_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)longRepr, STR, 1)));
long_cls->giveAttr("__str__", new BoxedFunction(boxRTFunction((void*)longStr, STR, 1))); long_cls->giveAttr("__str__", new BoxedFunction(boxRTFunction((void*)longStr, STR, 1)));
......
...@@ -47,3 +47,16 @@ x = I(D(C())) ...@@ -47,3 +47,16 @@ x = I(D(C()))
print type(x) print type(x)
print type(int(C())) print type(int(C()))
print type(int(2**100))
print type(int(2L))
print type(int.__new__(int, 2**100))
print type(int.__new__(int, 2L))
try:
print type(int.__new__(C, 2**100))
except OverflowError, e:
print e
class L(object):
def __int__(self):
return 1L
print type(int(L()))
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment