Commit fbb60a45 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Apply the same fixes to long and run into the same issue

parent e4ce4826
......@@ -755,7 +755,10 @@ extern "C" Box* intOct(BoxedInt* self) {
BoxedInt* _intNew(Box* val) {
if (isSubclass(val->cls, int_cls)) {
return new BoxedInt(int_cls, static_cast<BoxedInt*>(val)->n);
BoxedInt* n = static_cast<BoxedInt*>(val);
if (val->cls == int_cls)
return n;
return new BoxedInt(int_cls, n->n);
} else if (val->cls == str_cls) {
BoxedString* s = static_cast<BoxedString*>(val);
......
......@@ -290,20 +290,8 @@ extern "C" PyObject* PyLong_FromUnsignedLongLong(unsigned long long ival) {
return rtn;
}
extern "C" Box* longNew(Box* _cls, Box* val, Box* _base) {
if (!isSubclass(_cls->cls, type_cls))
raiseExcHelper(TypeError, "long.__new__(X): X is not a type object (%s)", getTypeName(_cls)->c_str());
BoxedClass* cls = static_cast<BoxedClass*>(_cls);
if (!isSubclass(cls, long_cls))
raiseExcHelper(TypeError, "long.__new__(%s): %s is not a subtype of long", getNameOfClass(cls)->c_str(),
getNameOfClass(cls)->c_str());
assert(cls->tp_basicsize >= sizeof(BoxedInt));
void* mem = gc_alloc(cls->tp_basicsize, gc::GCKind::PYTHON);
BoxedLong* rtn = ::new (mem) BoxedLong(cls);
initUserAttrs(rtn, cls);
BoxedLong* _longNew(Box* val, Box* _base) {
BoxedLong* rtn = new BoxedLong(long_cls);
if (_base) {
if (!isSubclass(_base->cls, int_cls))
raiseExcHelper(TypeError, "an integer is required");
......@@ -326,7 +314,14 @@ extern "C" Box* longNew(Box* _cls, Box* val, Box* _base) {
int r = mpz_init_set_str(rtn->n, s->s.c_str(), base);
RELEASE_ASSERT(r == 0, "");
} else {
if (isSubclass(val->cls, int_cls)) {
if (isSubclass(val->cls, long_cls)) {
BoxedLong* l = static_cast<BoxedLong*>(val);
if (val->cls == long_cls)
return l;
BoxedLong* rtn = new BoxedLong(long_cls);
mpz_init_set(rtn->n, l->n);
return rtn;
} else if (isSubclass(val->cls, int_cls)) {
mpz_init_set_si(rtn->n, static_cast<BoxedInt*>(val)->n);
} else if (val->cls == str_cls) {
const std::string& s = static_cast<BoxedString*>(val)->s;
......@@ -348,13 +343,35 @@ extern "C" Box* longNew(Box* _cls, Box* val, Box* _base) {
} else if (!isSubclass(r->cls, long_cls)) {
raiseExcHelper(TypeError, "__long__ returned non-long (type %s)", r->cls->tp_name);
} else {
mpz_init_set(rtn->n, static_cast<BoxedLong*>(r)->n);
return static_cast<BoxedLong*>(r);
}
}
}
return rtn;
}
extern "C" Box* longNew(Box* _cls, Box* val, Box* _base) {
if (!isSubclass(_cls->cls, type_cls))
raiseExcHelper(TypeError, "long.__new__(X): X is not a type object (%s)", getTypeName(_cls)->c_str());
BoxedClass* cls = static_cast<BoxedClass*>(_cls);
if (!isSubclass(cls, long_cls))
raiseExcHelper(TypeError, "long.__new__(%s): %s is not a subtype of long", getNameOfClass(cls)->c_str(),
getNameOfClass(cls)->c_str());
BoxedLong* l = _longNew(val, _base);
if (cls == long_cls)
return l;
assert(cls->tp_basicsize >= sizeof(BoxedInt));
void* mem = gc_alloc(cls->tp_basicsize, gc::GCKind::PYTHON);
BoxedLong* rtn = ::new (mem) BoxedLong(cls);
initUserAttrs(rtn, cls);
mpz_init_set(rtn->n, l->n);
return rtn;
}
Box* longRepr(BoxedLong* v) {
if (!isSubclass(v->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__repr__' requires a 'long' object but received a '%s'",
......
......@@ -3458,7 +3458,7 @@ Box* typeCallInternal(BoxedFunction* f, CallRewriteArgs* rewrite_args, ArgPassSp
allowable_news.push_back(object_new);
for (BoxedClass* allowed_cls : { xrange_cls, long_cls }) {
for (BoxedClass* allowed_cls : { xrange_cls }) {
auto new_obj = typeLookup(allowed_cls, _new_str, NULL);
gc::registerPermanentRoot(new_obj);
allowable_news.push_back(new_obj);
......
......@@ -34,3 +34,5 @@ class F2(float):
pass
print type(F2(D(F())))
print type(float(F()))
......@@ -48,3 +48,35 @@ print long("100", 26)
print type(hash(1L))
print hash(1L) == hash(2L)
# Testing long.__new__:
class C(long):
def __init__(self, *args):
print "C.__init__, %d args" % len(args)
class D(object):
def __init__(self, n):
self.n = n
def __long__(self):
return self.n
for a in (False, True, 2, 3L, D(4), D(C(5)), D(False)):
i = long.__new__(C, a)
print type(i), i, type(long(a))
try:
long.__new__(C, D(1.0))
except TypeError, e:
print e
class I(long):
pass
x = long(D(C()))
print type(x)
x = I(D(C()))
print type(x)
print type(long(C()))
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