Commit 6e2c8463 authored by Marius Wachtler's avatar Marius Wachtler

Fix repr() of oldstyle class infinite recursion. add _PyErr_BadInternalCall...

Fix repr() of oldstyle class infinite recursion. add _PyErr_BadInternalCall and PyCFunction_GetFlags
parent ec323fca
...@@ -56,7 +56,7 @@ BoxedClass* capifunc_cls; ...@@ -56,7 +56,7 @@ BoxedClass* capifunc_cls;
} }
extern "C" void _PyErr_BadInternalCall(const char* filename, int lineno) noexcept { extern "C" void _PyErr_BadInternalCall(const char* filename, int lineno) noexcept {
Py_FatalError("unimplemented"); PyErr_Format(PyExc_SystemError, "%s:%d: bad argument to internal function", filename, lineno);
} }
extern "C" PyObject* PyObject_Format(PyObject* obj, PyObject* format_spec) noexcept { extern "C" PyObject* PyObject_Format(PyObject* obj, PyObject* format_spec) noexcept {
...@@ -1388,6 +1388,14 @@ extern "C" PyObject* PyCFunction_GetSelf(PyObject* op) noexcept { ...@@ -1388,6 +1388,14 @@ extern "C" PyObject* PyCFunction_GetSelf(PyObject* op) noexcept {
return static_cast<BoxedCApiFunction*>(op)->passthrough; return static_cast<BoxedCApiFunction*>(op)->passthrough;
} }
extern "C" int PyCFunction_GetFlags(PyObject* op) noexcept {
if (!PyCFunction_Check(op)) {
PyErr_BadInternalCall();
return -1;
}
return static_cast<BoxedCApiFunction*>(op)->method_def->ml_flags;
}
extern "C" int _PyEval_SliceIndex(PyObject* v, Py_ssize_t* pi) noexcept { extern "C" int _PyEval_SliceIndex(PyObject* v, Py_ssize_t* pi) noexcept {
if (v != NULL) { if (v != NULL) {
Py_ssize_t x; Py_ssize_t x;
......
...@@ -267,6 +267,27 @@ Box* classobjStr(Box* _obj) { ...@@ -267,6 +267,27 @@ Box* classobjStr(Box* _obj) {
return boxStringTwine(llvm::Twine(static_cast<BoxedString*>(_mod)->s()) + "." + cls->name->s()); return boxStringTwine(llvm::Twine(static_cast<BoxedString*>(_mod)->s()) + "." + cls->name->s());
} }
Box* classobjRepr(Box* _obj) {
if (!isSubclass(_obj->cls, classobj_cls)) {
raiseExcHelper(TypeError, "descriptor '__repr__' requires a 'classobj' object but received an '%s'",
getTypeName(_obj));
}
BoxedClassobj* cls = static_cast<BoxedClassobj*>(_obj);
static BoxedString* module_str = internStringImmortal("__module__");
Box* mod = cls->getattr(module_str);
const char* name;
if (cls->name == NULL || !PyString_Check(cls->name))
name = "?";
else
name = PyString_AsString(cls->name);
if (mod == NULL || !PyString_Check(mod))
return PyString_FromFormat("<class ?.%s at %p>", name, cls);
else
return PyString_FromFormat("<class %s.%s at %p>", PyString_AsString(mod), name, cls);
}
// Analogous to CPython's instance_getattr2 // Analogous to CPython's instance_getattr2
static Box* instanceGetattributeSimple(BoxedInstance* inst, BoxedString* attr_str, static Box* instanceGetattributeSimple(BoxedInstance* inst, BoxedString* attr_str,
...@@ -1512,6 +1533,7 @@ void setupClassobj() { ...@@ -1512,6 +1533,7 @@ void setupClassobj() {
new BoxedFunction(boxRTFunction((void*)classobjGetattribute, UNKNOWN, 2))); new BoxedFunction(boxRTFunction((void*)classobjGetattribute, UNKNOWN, 2)));
classobj_cls->giveAttr("__setattr__", new BoxedFunction(boxRTFunction((void*)classobjSetattr, UNKNOWN, 3))); classobj_cls->giveAttr("__setattr__", new BoxedFunction(boxRTFunction((void*)classobjSetattr, UNKNOWN, 3)));
classobj_cls->giveAttr("__str__", new BoxedFunction(boxRTFunction((void*)classobjStr, STR, 1))); classobj_cls->giveAttr("__str__", new BoxedFunction(boxRTFunction((void*)classobjStr, STR, 1)));
classobj_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)classobjRepr, STR, 1)));
classobj_cls->giveAttr("__dict__", dict_descr); classobj_cls->giveAttr("__dict__", dict_descr);
classobj_cls->freeze(); classobj_cls->freeze();
......
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