Commit 49f841ce authored by Boxiang Sun's avatar Boxiang Sun

improve the _intNew funciton, to handle more edge cases, improve the trunc error message

parent 02d07167
...@@ -1932,12 +1932,7 @@ extern "C" PyObject* _PyNumber_ConvertIntegralToInt(PyObject* integral, const ch ...@@ -1932,12 +1932,7 @@ extern "C" PyObject* _PyNumber_ConvertIntegralToInt(PyObject* integral, const ch
non_integral_error: non_integral_error:
if (PyInstance_Check(integral)) { if (PyInstance_Check(integral)) {
fatalOrError(PyExc_NotImplementedError, "unimplemented"); type_name = static_cast<BoxedInstance*>(integral)->inst_cls->name->data();
return nullptr;
/* cpython has this:
type_name = PyString_AS_STRING(((PyInstanceObject *)integral)
->in_class->cl_name);
*/
} else { } else {
type_name = integral->cls->tp_name; type_name = integral->cls->tp_name;
} }
......
...@@ -320,8 +320,8 @@ extern "C" Box* div_i64_i64(i64 lhs, i64 rhs) { ...@@ -320,8 +320,8 @@ extern "C" Box* div_i64_i64(i64 lhs, i64 rhs) {
#if PYSTON_INT_MIN < -PYSTON_INT_MAX #if PYSTON_INT_MIN < -PYSTON_INT_MAX
static_assert(PYSTON_INT_MIN == -PYSTON_INT_MAX - 1, ""); static_assert(PYSTON_INT_MIN == -PYSTON_INT_MAX - 1, "");
if (lhs == PYSTON_INT_MIN && rhs == -1) { if (lhs == PYSTON_INT_MIN) {
return longDiv(boxLong(lhs), boxLong(rhs)); return longInt(longDiv(boxLong(lhs), boxLong(rhs)));
} }
#endif #endif
...@@ -828,6 +828,14 @@ extern "C" Box* intHash(BoxedInt* self) { ...@@ -828,6 +828,14 @@ extern "C" Box* intHash(BoxedInt* self) {
return boxInt(self->n); return boxInt(self->n);
} }
extern "C" Box* intBin(BoxedInt* self) {
if (!PyInt_Check(self))
raiseExcHelper(TypeError, "descriptor '__bin__' requires a 'int' object but received a '%s'",
getTypeName(self));
return _PyInt_Format(reinterpret_cast<PyIntObject*>(self), 2, 0);
}
extern "C" Box* intHex(BoxedInt* self) { extern "C" Box* intHex(BoxedInt* self) {
if (!PyInt_Check(self)) if (!PyInt_Check(self))
raiseExcHelper(TypeError, "descriptor '__hex__' requires a 'int' object but received a '%s'", raiseExcHelper(TypeError, "descriptor '__hex__' requires a 'int' object but received a '%s'",
...@@ -886,12 +894,30 @@ extern "C" Box* intIndex(BoxedInt* v) { ...@@ -886,12 +894,30 @@ extern "C" Box* intIndex(BoxedInt* v) {
template <ExceptionStyle S> static Box* _intNew(Box* val, Box* base) noexcept(S == CAPI) { template <ExceptionStyle S> static Box* _intNew(Box* val, Box* base) noexcept(S == CAPI) {
if (val->cls == int_cls) { if (val->cls == int_cls) {
RELEASE_ASSERT(!base, ""); if (base) {
if (S == CAPI) {
PyErr_Format(TypeError, "int() missing string argument");
return NULL;
} else
raiseExcHelper(TypeError, "int() missing string argument");
}
BoxedInt* n = static_cast<BoxedInt*>(val); BoxedInt* n = static_cast<BoxedInt*>(val);
if (val->cls == int_cls) if (val->cls == int_cls)
return n; return n;
return new BoxedInt(n->n); return new BoxedInt(n->n);
} else if (PyString_Check(val)) { }
if (!base) {
Box* r = PyNumber_Int(val);
if (!r) {
if (S == CAPI) {
return NULL;
} else
throwCAPIException();
}
return r;
}
if (PyString_Check(val)) {
int base_n; int base_n;
if (!base) if (!base)
base_n = 10; base_n = 10;
...@@ -899,10 +925,19 @@ template <ExceptionStyle S> static Box* _intNew(Box* val, Box* base) noexcept(S ...@@ -899,10 +925,19 @@ template <ExceptionStyle S> static Box* _intNew(Box* val, Box* base) noexcept(S
RELEASE_ASSERT(base->cls == int_cls, ""); RELEASE_ASSERT(base->cls == int_cls, "");
base_n = static_cast<BoxedInt*>(base)->n; base_n = static_cast<BoxedInt*>(base)->n;
} }
BoxedString* s = static_cast<BoxedString*>(val); BoxedString* s = static_cast<BoxedString*>(val);
RELEASE_ASSERT(s->size() == strlen(s->data()), ""); if (s->size() != strlen(s->data())) {
Box* srepr = PyObject_Repr(val);
if (S == CAPI) {
PyErr_Format(PyExc_ValueError, "invalid literal for int() with base %d: %s", base_n,
PyString_AS_STRING(srepr));
return NULL;
} else {
raiseExcHelper(ValueError, "invalid literal for int() with base %d: %s", base_n,
PyString_AS_STRING(srepr));
}
}
Box* r = PyInt_FromString(s->data(), NULL, base_n); Box* r = PyInt_FromString(s->data(), NULL, base_n);
if (!r) { if (!r) {
if (S == CAPI) if (S == CAPI)
...@@ -958,7 +993,8 @@ template <ExceptionStyle S> static Box* _intNew(Box* val, Box* base) noexcept(S ...@@ -958,7 +993,8 @@ template <ExceptionStyle S> static Box* _intNew(Box* val, Box* base) noexcept(S
} }
return PyLong_FromDouble(wholepart); return PyLong_FromDouble(wholepart);
} else { } else {
RELEASE_ASSERT(!base, ""); if (base)
raiseExcHelper(TypeError, "TypeError: int() can't convert non-string with explicit base");
static BoxedString* int_str = internStringImmortal("__int__"); static BoxedString* int_str = internStringImmortal("__int__");
Box* r = callattrInternal<S>(val, int_str, CLASS_ONLY, NULL, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL); Box* r = callattrInternal<S>(val, int_str, CLASS_ONLY, NULL, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
...@@ -1168,6 +1204,7 @@ void setupInt() { ...@@ -1168,6 +1204,7 @@ void setupInt() {
int_cls->tp_hash = (hashfunc)int_hash; int_cls->tp_hash = (hashfunc)int_hash;
int_cls->giveAttr("__divmod__", new BoxedFunction(boxRTFunction((void*)intDivmod, UNKNOWN, 2))); int_cls->giveAttr("__divmod__", new BoxedFunction(boxRTFunction((void*)intDivmod, UNKNOWN, 2)));
int_cls->giveAttr("__bin__", new BoxedFunction(boxRTFunction((void*)intBin, STR, 1)));
int_cls->giveAttr("__hex__", new BoxedFunction(boxRTFunction((void*)intHex, STR, 1))); int_cls->giveAttr("__hex__", new BoxedFunction(boxRTFunction((void*)intHex, STR, 1)));
int_cls->giveAttr("__oct__", new BoxedFunction(boxRTFunction((void*)intOct, STR, 1))); int_cls->giveAttr("__oct__", new BoxedFunction(boxRTFunction((void*)intOct, STR, 1)));
......
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