Commit 01ff3e39 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Support some cases of passing a base to int()

parent cb70ba7f
...@@ -45,7 +45,7 @@ PyAPI_FUNC(bool) _PyInt_Check(PyObject*) PYSTON_NOEXCEPT; ...@@ -45,7 +45,7 @@ PyAPI_FUNC(bool) _PyInt_Check(PyObject*) PYSTON_NOEXCEPT;
#endif #endif
#define PyInt_CheckExact(op) (Py_TYPE(op) == &PyInt_Type) #define PyInt_CheckExact(op) (Py_TYPE(op) == &PyInt_Type)
PyAPI_FUNC(PyObject *) PyInt_FromString(char*, char**, int) PYSTON_NOEXCEPT; PyAPI_FUNC(PyObject *) PyInt_FromString(const char*, char**, int) PYSTON_NOEXCEPT;
#ifdef Py_USING_UNICODE #ifdef Py_USING_UNICODE
PyAPI_FUNC(PyObject *) PyInt_FromUnicode(Py_UNICODE*, Py_ssize_t, int) PYSTON_NOEXCEPT; PyAPI_FUNC(PyObject *) PyInt_FromUnicode(Py_UNICODE*, Py_ssize_t, int) PYSTON_NOEXCEPT;
#endif #endif
......
...@@ -69,7 +69,7 @@ PyAPI_FUNC(unsigned PY_LONG_LONG) PyLong_AsUnsignedLongLongMask(PyObject *) PYST ...@@ -69,7 +69,7 @@ PyAPI_FUNC(unsigned PY_LONG_LONG) PyLong_AsUnsignedLongLongMask(PyObject *) PYST
PyAPI_FUNC(PY_LONG_LONG) PyLong_AsLongLongAndOverflow(PyObject *, int *) PYSTON_NOEXCEPT; PyAPI_FUNC(PY_LONG_LONG) PyLong_AsLongLongAndOverflow(PyObject *, int *) PYSTON_NOEXCEPT;
#endif /* HAVE_LONG_LONG */ #endif /* HAVE_LONG_LONG */
PyAPI_FUNC(PyObject *) PyLong_FromString(char *, char **, int) PYSTON_NOEXCEPT; PyAPI_FUNC(PyObject *) PyLong_FromString(const char *, char **, int) PYSTON_NOEXCEPT;
#ifdef Py_USING_UNICODE #ifdef Py_USING_UNICODE
PyAPI_FUNC(PyObject *) PyLong_FromUnicode(Py_UNICODE*, Py_ssize_t, int) PYSTON_NOEXCEPT; PyAPI_FUNC(PyObject *) PyLong_FromUnicode(Py_UNICODE*, Py_ssize_t, int) PYSTON_NOEXCEPT;
#endif #endif
......
...@@ -82,7 +82,7 @@ extern "C" int _PyInt_AsInt(PyObject* obj) noexcept { ...@@ -82,7 +82,7 @@ extern "C" int _PyInt_AsInt(PyObject* obj) noexcept {
return (int)result; return (int)result;
} }
extern "C" PyObject* PyInt_FromString(char* s, char** pend, int base) noexcept { extern "C" PyObject* PyInt_FromString(const char* s, char** pend, int base) noexcept {
char* end; char* end;
long x; long x;
Py_ssize_t slen; Py_ssize_t slen;
...@@ -813,30 +813,50 @@ extern "C" Box* intOct(BoxedInt* self) { ...@@ -813,30 +813,50 @@ extern "C" Box* intOct(BoxedInt* self) {
return new BoxedString(std::string(buf, len)); return new BoxedString(std::string(buf, len));
} }
Box* _intNew(Box* val) { static Box* _intNew(Box* val, Box* base) {
if (isSubclass(val->cls, int_cls)) { if (isSubclass(val->cls, int_cls)) {
RELEASE_ASSERT(!base, "");
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 (val->cls == str_cls) { } else if (val->cls == str_cls) {
int base_n;
if (!base)
base_n = 10;
else {
RELEASE_ASSERT(base->cls == int_cls, "");
base_n = static_cast<BoxedInt*>(base)->n;
}
BoxedString* s = static_cast<BoxedString*>(val); BoxedString* s = static_cast<BoxedString*>(val);
// TODO: use PyInt_FromString here RELEASE_ASSERT(s->s.size() == strlen(s->s.c_str()), "");
std::istringstream ss(s->s); Box* r = PyInt_FromString(s->s.c_str(), NULL, base_n);
int64_t n; if (!r)
ss >> n; throwCAPIException();
return new BoxedInt(n); assert(r);
return r;
} else if (val->cls == unicode_cls) { } else if (val->cls == unicode_cls) {
Box* r = PyInt_FromUnicode(PyUnicode_AS_UNICODE(val), PyUnicode_GET_SIZE(val), 10); int base_n;
if (!base)
base_n = 10;
else {
RELEASE_ASSERT(base->cls == int_cls, "");
base_n = static_cast<BoxedInt*>(base)->n;
}
Box* r = PyInt_FromUnicode(PyUnicode_AS_UNICODE(val), PyUnicode_GET_SIZE(val), base_n);
if (!r) if (!r)
throwCAPIException(); throwCAPIException();
assert(r); assert(r);
return r; return r;
} else if (val->cls == float_cls) { } else if (val->cls == float_cls) {
RELEASE_ASSERT(!base, "");
double d = static_cast<BoxedFloat*>(val)->d; double d = static_cast<BoxedFloat*>(val)->d;
return new BoxedInt(d); return new BoxedInt(d);
} else { } else {
RELEASE_ASSERT(!base, "");
static const std::string int_str("__int__"); static const std::string int_str("__int__");
Box* r = callattr(val, &int_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = true }), Box* r = callattr(val, &int_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = true }),
ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL); ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
...@@ -853,7 +873,7 @@ Box* _intNew(Box* val) { ...@@ -853,7 +873,7 @@ Box* _intNew(Box* val) {
} }
} }
extern "C" Box* intNew(Box* _cls, Box* val) { extern "C" Box* intNew(Box* _cls, Box* val, Box* base) {
if (!isSubclass(_cls->cls, type_cls)) if (!isSubclass(_cls->cls, type_cls))
raiseExcHelper(TypeError, "int.__new__(X): X is not a type object (%s)", getTypeName(_cls)); raiseExcHelper(TypeError, "int.__new__(X): X is not a type object (%s)", getTypeName(_cls));
...@@ -863,9 +883,9 @@ extern "C" Box* intNew(Box* _cls, Box* val) { ...@@ -863,9 +883,9 @@ extern "C" Box* intNew(Box* _cls, Box* val) {
getNameOfClass(cls)); getNameOfClass(cls));
if (cls == int_cls) if (cls == int_cls)
return _intNew(val); return _intNew(val, base);
BoxedInt* n = (BoxedInt*)_intNew(val); BoxedInt* n = (BoxedInt*)_intNew(val, base);
if (n->cls == long_cls) { if (n->cls == long_cls) {
if (cls == int_cls) if (cls == int_cls)
return n; return n;
...@@ -951,8 +971,8 @@ void setupInt() { ...@@ -951,8 +971,8 @@ void setupInt() {
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)));
int_cls->giveAttr("__new__", int_cls->giveAttr(
new BoxedFunction(boxRTFunction((void*)intNew, UNKNOWN, 2, 1, false, false), { boxInt(0) })); "__new__", new BoxedFunction(boxRTFunction((void*)intNew, UNKNOWN, 3, 2, false, false), { boxInt(0), NULL }));
int_cls->giveAttr("__init__", int_cls->giveAttr("__init__",
new BoxedFunction(boxRTFunction((void*)intInit, NONE, 2, 1, true, false), { boxInt(0) })); new BoxedFunction(boxRTFunction((void*)intInit, NONE, 2, 1, true, false), { boxInt(0) }));
......
...@@ -90,7 +90,7 @@ extern "C" PY_LONG_LONG PyLong_AsLongLong(PyObject* vv) noexcept { ...@@ -90,7 +90,7 @@ extern "C" PY_LONG_LONG PyLong_AsLongLong(PyObject* vv) noexcept {
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
} }
extern "C" PyObject* PyLong_FromString(char* str, char** pend, int base) noexcept { extern "C" PyObject* PyLong_FromString(const char* str, char** pend, int base) noexcept {
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
} }
......
...@@ -62,3 +62,13 @@ class L(object): ...@@ -62,3 +62,13 @@ class L(object):
print type(int(L())) print type(int(L()))
print int(u'123') print int(u'123')
for b in range(26):
try:
print int('123', b)
except ValueError as e:
print e
try:
print int(u'123', b)
except ValueError as e:
print e
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