Commit b5682e5d authored by Boxiang Sun's avatar Boxiang Sun

add tp_new to these class

parent b33228cd
...@@ -46,13 +46,23 @@ Box* boolHash(BoxedBool* v) { ...@@ -46,13 +46,23 @@ Box* boolHash(BoxedBool* v) {
return boxInt(bool_hash(v)); return boxInt(bool_hash(v));
} }
extern "C" Box* boolNew(Box* cls, Box* val) { template <ExceptionStyle S> static Box* boolNew(Box* cls, Box* val) noexcept {
assert(cls == bool_cls); assert(cls == bool_cls);
bool b = nonzero(val); bool b = nonzero(val);
return boxBool(b); return boxBool(b);
} }
static Box* bool_new(BoxedClass* type, Box* args, Box* kwds) noexcept {
PyObject* x = Py_False;
static char* kwlist[3] = { NULL, NULL };
kwlist[0] = const_cast<char*>("x");
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:bool", kwlist, &x))
return NULL;
return boolNew<CAPI>(type, x);
}
extern "C" Box* boolAnd(BoxedBool* lhs, BoxedBool* rhs) { extern "C" Box* boolAnd(BoxedBool* lhs, BoxedBool* rhs) {
if (lhs->cls != bool_cls) if (lhs->cls != bool_cls)
raiseExcHelper(TypeError, "descriptor '__and__' requires a 'bool' object but received a '%s'", raiseExcHelper(TypeError, "descriptor '__and__' requires a 'bool' object but received a '%s'",
...@@ -94,8 +104,10 @@ void setupBool() { ...@@ -94,8 +104,10 @@ void setupBool() {
bool_cls->giveAttr("__repr__", new BoxedFunction(FunctionMetadata::create((void*)boolRepr, STR, 1))); bool_cls->giveAttr("__repr__", new BoxedFunction(FunctionMetadata::create((void*)boolRepr, STR, 1)));
bool_cls->giveAttr("__hash__", new BoxedFunction(FunctionMetadata::create((void*)boolHash, BOXED_INT, 1))); bool_cls->giveAttr("__hash__", new BoxedFunction(FunctionMetadata::create((void*)boolHash, BOXED_INT, 1)));
bool_cls->giveAttr("__new__", auto bool_new_fm
new BoxedFunction(FunctionMetadata::create((void*)boolNew, UNKNOWN, 2, false, false), { None })); = FunctionMetadata::create((void*)boolNew<CXX>, UNKNOWN, 2, false, false, ParamNames({ "", "x" }, "", ""), CXX);
bool_new_fm->addVersion((void*)boolNew<CAPI>, UNKNOWN, CAPI);
bool_cls->giveAttr("__new__", new BoxedFunction(bool_new_fm, { None, NULL }));
bool_cls->giveAttr("__and__", new BoxedFunction(FunctionMetadata::create((void*)boolAnd, BOXED_BOOL, 2))); bool_cls->giveAttr("__and__", new BoxedFunction(FunctionMetadata::create((void*)boolAnd, BOXED_BOOL, 2)));
bool_cls->giveAttr("__or__", new BoxedFunction(FunctionMetadata::create((void*)boolOr, BOXED_BOOL, 2))); bool_cls->giveAttr("__or__", new BoxedFunction(FunctionMetadata::create((void*)boolOr, BOXED_BOOL, 2)));
...@@ -103,6 +115,7 @@ void setupBool() { ...@@ -103,6 +115,7 @@ void setupBool() {
bool_cls->freeze(); bool_cls->freeze();
bool_cls->tp_hash = (hashfunc)bool_hash; bool_cls->tp_hash = (hashfunc)bool_hash;
bool_cls->tp_new = (newfunc)bool_new;
} }
void teardownBool() { void teardownBool() {
......
...@@ -1267,6 +1267,9 @@ void setupComplex() { ...@@ -1267,6 +1267,9 @@ void setupComplex() {
_addFunc("__div__", BOXED_COMPLEX, (void*)complexDivComplex, (void*)complexDivFloat, (void*)complexDivInt, _addFunc("__div__", BOXED_COMPLEX, (void*)complexDivComplex, (void*)complexDivFloat, (void*)complexDivInt,
(void*)complexDiv); (void*)complexDiv);
_addFunc("__truediv__", BOXED_COMPLEX, (void*)complexDivComplex, (void*)complexDivFloat, (void*)complexDivInt,
(void*)complexDiv);
complex_cls->giveAttr("__rsub__", new BoxedFunction(FunctionMetadata::create((void*)complexRSub, UNKNOWN, 2))); complex_cls->giveAttr("__rsub__", new BoxedFunction(FunctionMetadata::create((void*)complexRSub, UNKNOWN, 2)));
complex_cls->giveAttr("__rdiv__", new BoxedFunction(FunctionMetadata::create((void*)complexRDiv, UNKNOWN, 2))); complex_cls->giveAttr("__rdiv__", new BoxedFunction(FunctionMetadata::create((void*)complexRDiv, UNKNOWN, 2)));
complex_cls->giveAttr( complex_cls->giveAttr(
...@@ -1279,8 +1282,6 @@ void setupComplex() { ...@@ -1279,8 +1282,6 @@ void setupComplex() {
complex_cls->giveAttr("__floordiv__", complex_cls->giveAttr("__floordiv__",
new BoxedFunction(FunctionMetadata::create((void*)complexFloordiv, UNKNOWN, 2))); new BoxedFunction(FunctionMetadata::create((void*)complexFloordiv, UNKNOWN, 2)));
complex_cls->giveAttr("__truediv__",
new BoxedFunction(FunctionMetadata::create((void*)complexDivComplex, BOXED_COMPLEX, 2)));
complex_cls->giveAttr("conjugate", complex_cls->giveAttr("conjugate",
new BoxedFunction(FunctionMetadata::create((void*)complexConjugate, BOXED_COMPLEX, 1))); new BoxedFunction(FunctionMetadata::create((void*)complexConjugate, BOXED_COMPLEX, 1)));
complex_cls->giveAttr("__coerce__", new BoxedFunction(FunctionMetadata::create((void*)complexCoerce, UNKNOWN, 2))); complex_cls->giveAttr("__coerce__", new BoxedFunction(FunctionMetadata::create((void*)complexCoerce, UNKNOWN, 2)));
......
...@@ -854,8 +854,14 @@ template <ExceptionStyle S> static BoxedFloat* _floatNew(Box* a) noexcept(S == C ...@@ -854,8 +854,14 @@ template <ExceptionStyle S> static BoxedFloat* _floatNew(Box* a) noexcept(S == C
} else if (PyLong_Check(a)) { } else if (PyLong_Check(a)) {
double a_f = PyLong_AsDouble(a); double a_f = PyLong_AsDouble(a);
if (a_f == -1.0 && PyErr_Occurred()) { if (a_f == -1.0 && PyErr_Occurred()) {
throwCAPIException(); if (S == CAPI)
return NULL;
else
throwCAPIException();
} }
// Make sure that we're not in an error state when we return a non-NULL value.
assert(!PyErr_Occurred());
return new BoxedFloat(a_f); return new BoxedFloat(a_f);
} else if (a->cls == str_cls || a->cls == unicode_cls) { } else if (a->cls == str_cls || a->cls == unicode_cls) {
BoxedFloat* res = (BoxedFloat*)PyFloat_FromString(a, NULL); BoxedFloat* res = (BoxedFloat*)PyFloat_FromString(a, NULL);
...@@ -928,6 +934,22 @@ template <ExceptionStyle S> Box* floatNew(BoxedClass* _cls, Box* a) noexcept(S = ...@@ -928,6 +934,22 @@ template <ExceptionStyle S> Box* floatNew(BoxedClass* _cls, Box* a) noexcept(S =
return new (cls) BoxedFloat(f->d); return new (cls) BoxedFloat(f->d);
} }
// Roughly analogous to CPython's float_new.
// The arguments need to be unpacked from args and kwds.
static Box* float_new(BoxedClass* type, Box* args, Box* kwds) noexcept {
PyObject* x = False;
static char* kwlist[2] = { NULL, NULL };
kwlist[0] = const_cast<char*>("x");
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:float", kwlist, &x))
return NULL;
if (x == NULL)
return floatNew<CAPI>(type, None);
else
return floatNew<CAPI>(type, x);
}
PyObject* float_str_or_repr(double v, int precision, char format_code) { PyObject* float_str_or_repr(double v, int precision, char format_code) {
PyObject* result; PyObject* result;
char* buf = PyOS_double_to_string(v, format_code, precision, Py_DTSF_ADD_DOT_0, NULL); char* buf = PyOS_double_to_string(v, format_code, precision, Py_DTSF_ADD_DOT_0, NULL);
...@@ -1602,9 +1624,10 @@ void setupFloat() { ...@@ -1602,9 +1624,10 @@ void setupFloat() {
_addFunc("__sub__", BOXED_FLOAT, (void*)floatSubFloat, (void*)floatSubInt, (void*)floatSub); _addFunc("__sub__", BOXED_FLOAT, (void*)floatSubFloat, (void*)floatSubInt, (void*)floatSub);
_addFunc("__rsub__", BOXED_FLOAT, (void*)floatRSubFloat, (void*)floatRSubInt, (void*)floatRSub); _addFunc("__rsub__", BOXED_FLOAT, (void*)floatRSubFloat, (void*)floatRSubInt, (void*)floatRSub);
auto float_new = FunctionMetadata::create((void*)floatNew<CXX>, UNKNOWN, 2, false, false, ParamNames::empty(), CXX); auto float_new_fm
float_new->addVersion((void*)floatNew<CAPI>, UNKNOWN, CAPI); = FunctionMetadata::create((void*)floatNew<CXX>, UNKNOWN, 2, false, false, ParamNames::empty(), CXX);
float_cls->giveAttr("__new__", new BoxedFunction(float_new, { boxFloat(0.0) })); float_new_fm->addVersion((void*)floatNew<CAPI>, UNKNOWN, CAPI);
float_cls->giveAttr("__new__", new BoxedFunction(float_new_fm, { boxFloat(0.0) }));
float_cls->giveAttr("__eq__", new BoxedFunction(FunctionMetadata::create((void*)floatEq, UNKNOWN, 2))); float_cls->giveAttr("__eq__", new BoxedFunction(FunctionMetadata::create((void*)floatEq, UNKNOWN, 2)));
float_cls->giveAttr("__ne__", new BoxedFunction(FunctionMetadata::create((void*)floatNe, UNKNOWN, 2))); float_cls->giveAttr("__ne__", new BoxedFunction(FunctionMetadata::create((void*)floatNe, UNKNOWN, 2)));
...@@ -1647,6 +1670,7 @@ void setupFloat() { ...@@ -1647,6 +1670,7 @@ void setupFloat() {
float_cls->tp_str = float_str; float_cls->tp_str = float_str;
float_cls->tp_as_number->nb_power = float_pow; float_cls->tp_as_number->nb_power = float_pow;
float_cls->tp_new = (newfunc)float_new;
} }
void teardownFloat() { void teardownFloat() {
......
...@@ -1046,6 +1046,27 @@ template <ExceptionStyle S> Box* intNew(Box* _cls, Box* val, Box* base) noexcept ...@@ -1046,6 +1046,27 @@ template <ExceptionStyle S> Box* intNew(Box* _cls, Box* val, Box* base) noexcept
return new (cls) BoxedInt(n->n); return new (cls) BoxedInt(n->n);
} }
// Roughly analogous to CPython's int_new.
// The arguments need to be unpacked from args and kwds.
static Box* int_new(BoxedClass* type, Box* args, Box* kwds) noexcept {
PyObject* x = NULL;
int base = -909;
static char* kwlist[3] = { NULL, NULL, NULL };
kwlist[0] = const_cast<char*>("x");
kwlist[1] = const_cast<char*>("base");
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:int", kwlist, &x, &base))
return NULL;
if (x == NULL)
x = None;
if (base == -909)
return intNew<CAPI>(type, x, NULL);
else
return intNew<CAPI>(type, x, boxInt(base));
}
static const unsigned char BitLengthTable[32] static const unsigned char BitLengthTable[32]
= { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 }; = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };
...@@ -1206,10 +1227,10 @@ void setupInt() { ...@@ -1206,10 +1227,10 @@ void setupInt() {
int_cls->giveAttr("__index__", new BoxedFunction(FunctionMetadata::create((void*)intIndex, BOXED_INT, 1))); int_cls->giveAttr("__index__", new BoxedFunction(FunctionMetadata::create((void*)intIndex, BOXED_INT, 1)));
int_cls->giveAttr("__int__", new BoxedFunction(FunctionMetadata::create((void*)intInt, BOXED_INT, 1))); int_cls->giveAttr("__int__", new BoxedFunction(FunctionMetadata::create((void*)intInt, BOXED_INT, 1)));
auto int_new = FunctionMetadata::create((void*)intNew<CXX>, UNKNOWN, 3, false, false, auto int_new_fm = FunctionMetadata::create((void*)intNew<CXX>, UNKNOWN, 3, false, false,
ParamNames({ "", "x", "base" }, "", ""), CXX); ParamNames({ "", "x", "base" }, "", ""), CXX);
int_new->addVersion((void*)intNew<CAPI>, UNKNOWN, CAPI); int_new_fm->addVersion((void*)intNew<CAPI>, UNKNOWN, CAPI);
int_cls->giveAttr("__new__", new BoxedFunction(int_new, { None, NULL })); int_cls->giveAttr("__new__", new BoxedFunction(int_new_fm, { None, NULL }));
int_cls->giveAttr("bit_length", new BoxedFunction(FunctionMetadata::create((void*)intBitLength, BOXED_INT, 1))); int_cls->giveAttr("bit_length", new BoxedFunction(FunctionMetadata::create((void*)intBitLength, BOXED_INT, 1)));
...@@ -1224,6 +1245,7 @@ void setupInt() { ...@@ -1224,6 +1245,7 @@ void setupInt() {
int_cls->freeze(); int_cls->freeze();
int_cls->tp_repr = (reprfunc)int_to_decimal_string; int_cls->tp_repr = (reprfunc)int_to_decimal_string;
int_cls->tp_new = (newfunc)int_new;
} }
void teardownInt() { void teardownInt() {
......
...@@ -766,6 +766,26 @@ template <ExceptionStyle S> Box* longNew(Box* _cls, Box* val, Box* base) noexcep ...@@ -766,6 +766,26 @@ template <ExceptionStyle S> Box* longNew(Box* _cls, Box* val, Box* base) noexcep
return rtn; return rtn;
} }
// For tp_new, unpack the arguments from args and kwds
static Box* long_new(BoxedClass* type, Box* args, Box* kwds) noexcept {
PyObject* x = NULL;
int base = -909;
static char* kwlist[3] = { NULL, NULL, NULL };
kwlist[0] = const_cast<char*>("x");
kwlist[1] = const_cast<char*>("base");
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:long", kwlist, &x, &base))
return NULL;
if (x == NULL)
x = None;
if (base == -909)
return longNew<CAPI>(type, x, NULL);
else
return longNew<CAPI>(type, x, boxInt(base));
}
Box* longInt(Box* v) { Box* longInt(Box* v) {
if (!PyLong_Check(v)) if (!PyLong_Check(v))
raiseExcHelper(TypeError, "descriptor '__int__' requires a 'long' object but received a '%s'", getTypeName(v)); raiseExcHelper(TypeError, "descriptor '__int__' requires a 'long' object but received a '%s'", getTypeName(v));
...@@ -1547,10 +1567,10 @@ void setupLong() { ...@@ -1547,10 +1567,10 @@ void setupLong() {
mp_set_memory_functions(customised_allocation, customised_realloc, customised_free); mp_set_memory_functions(customised_allocation, customised_realloc, customised_free);
_addFuncPow("__pow__", UNKNOWN, (void*)longPowFloat, (void*)longPow); _addFuncPow("__pow__", UNKNOWN, (void*)longPowFloat, (void*)longPow);
auto long_new = FunctionMetadata::create((void*)longNew<CXX>, UNKNOWN, 3, false, false, auto long_new_fm = FunctionMetadata::create((void*)longNew<CXX>, UNKNOWN, 3, false, false,
ParamNames({ "", "x", "base" }, "", ""), CXX); ParamNames({ "", "x", "base" }, "", ""), CXX);
long_new->addVersion((void*)longNew<CAPI>, UNKNOWN, CAPI); long_new_fm->addVersion((void*)longNew<CAPI>, UNKNOWN, CAPI);
long_cls->giveAttr("__new__", new BoxedFunction(long_new, { boxInt(0), NULL })); long_cls->giveAttr("__new__", new BoxedFunction(long_new_fm, { boxInt(0), NULL }));
long_cls->giveAttr("__mul__", new BoxedFunction(FunctionMetadata::create((void*)longMul, UNKNOWN, 2))); long_cls->giveAttr("__mul__", new BoxedFunction(FunctionMetadata::create((void*)longMul, UNKNOWN, 2)));
long_cls->giveAttr("__rmul__", long_cls->getattr(internStringMortal("__mul__"))); long_cls->giveAttr("__rmul__", long_cls->getattr(internStringMortal("__mul__")));
...@@ -1615,5 +1635,6 @@ void setupLong() { ...@@ -1615,5 +1635,6 @@ void setupLong() {
long_cls->freeze(); long_cls->freeze();
long_cls->tp_as_number->nb_power = long_pow; long_cls->tp_as_number->nb_power = long_pow;
long_cls->tp_new = (newfunc)long_new;
} }
} }
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