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) { ...@@ -755,7 +755,10 @@ extern "C" Box* intOct(BoxedInt* self) {
BoxedInt* _intNew(Box* val) { BoxedInt* _intNew(Box* val) {
if (isSubclass(val->cls, int_cls)) { 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) { } else if (val->cls == str_cls) {
BoxedString* s = static_cast<BoxedString*>(val); BoxedString* s = static_cast<BoxedString*>(val);
......
...@@ -290,20 +290,8 @@ extern "C" PyObject* PyLong_FromUnsignedLongLong(unsigned long long ival) { ...@@ -290,20 +290,8 @@ extern "C" PyObject* PyLong_FromUnsignedLongLong(unsigned long long ival) {
return rtn; return rtn;
} }
extern "C" Box* longNew(Box* _cls, Box* val, Box* _base) { BoxedLong* _longNew(Box* val, Box* _base) {
if (!isSubclass(_cls->cls, type_cls)) BoxedLong* rtn = new BoxedLong(long_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);
if (_base) { if (_base) {
if (!isSubclass(_base->cls, int_cls)) if (!isSubclass(_base->cls, int_cls))
raiseExcHelper(TypeError, "an integer is required"); raiseExcHelper(TypeError, "an integer is required");
...@@ -326,7 +314,14 @@ extern "C" Box* longNew(Box* _cls, Box* val, Box* _base) { ...@@ -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); int r = mpz_init_set_str(rtn->n, s->s.c_str(), base);
RELEASE_ASSERT(r == 0, ""); RELEASE_ASSERT(r == 0, "");
} else { } 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); mpz_init_set_si(rtn->n, static_cast<BoxedInt*>(val)->n);
} else if (val->cls == str_cls) { } else if (val->cls == str_cls) {
const std::string& s = static_cast<BoxedString*>(val)->s; const std::string& s = static_cast<BoxedString*>(val)->s;
...@@ -348,13 +343,35 @@ extern "C" Box* longNew(Box* _cls, Box* val, Box* _base) { ...@@ -348,13 +343,35 @@ extern "C" Box* longNew(Box* _cls, Box* val, Box* _base) {
} else if (!isSubclass(r->cls, long_cls)) { } else if (!isSubclass(r->cls, long_cls)) {
raiseExcHelper(TypeError, "__long__ returned non-long (type %s)", r->cls->tp_name); raiseExcHelper(TypeError, "__long__ returned non-long (type %s)", r->cls->tp_name);
} else { } else {
mpz_init_set(rtn->n, static_cast<BoxedLong*>(r)->n); return static_cast<BoxedLong*>(r);
} }
} }
} }
return rtn; 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) { 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'", raiseExcHelper(TypeError, "descriptor '__repr__' requires a 'long' object but received a '%s'",
......
...@@ -3458,7 +3458,7 @@ Box* typeCallInternal(BoxedFunction* f, CallRewriteArgs* rewrite_args, ArgPassSp ...@@ -3458,7 +3458,7 @@ Box* typeCallInternal(BoxedFunction* f, CallRewriteArgs* rewrite_args, ArgPassSp
allowable_news.push_back(object_new); 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); auto new_obj = typeLookup(allowed_cls, _new_str, NULL);
gc::registerPermanentRoot(new_obj); gc::registerPermanentRoot(new_obj);
allowable_news.push_back(new_obj); allowable_news.push_back(new_obj);
......
...@@ -34,3 +34,5 @@ class F2(float): ...@@ -34,3 +34,5 @@ class F2(float):
pass pass
print type(F2(D(F()))) print type(F2(D(F())))
print type(float(F()))
...@@ -48,3 +48,35 @@ print long("100", 26) ...@@ -48,3 +48,35 @@ print long("100", 26)
print type(hash(1L)) print type(hash(1L))
print hash(1L) == hash(2L) 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