Commit e6ebbb72 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Add object.__str__ and object.__repr__

Before, the default behavior (falling back to __repr__ if __str__ doesn't
exist, and giving a default representation if __repr__ doesn't exist) was
provided by the repr() and str() functions.
parent 95ef55eb
......@@ -1094,17 +1094,10 @@ extern "C" BoxedString* str(Box* obj) {
if (obj->cls != str_cls) {
Box* str = getclsattr_internal(obj, "__str__", NULL);
if (str == NULL)
str = getclsattr_internal(obj, "__repr__", NULL);
if (str == NULL) {
char buf[80];
snprintf(buf, 80, "<%s object at %p>", getTypeName(obj)->c_str(), obj);
return boxStrConstant(buf);
} else {
obj = runtimeCallInternal0(str, NULL, ArgPassSpec(0));
}
assert(str); // TODO clean the rest of this up now that this assert is true
obj = runtimeCallInternal0(str, NULL, ArgPassSpec(0));
}
if (obj->cls != str_cls) {
fprintf(stderr, "__str__ did not return a string!\n");
abort();
......@@ -1117,19 +1110,8 @@ extern "C" Box* repr(Box* obj) {
slowpath_repr.log();
Box* repr = getclsattr_internal(obj, "__repr__", NULL);
if (repr == NULL) {
ASSERT(isUserDefined(obj->cls), "%s", getTypeName(obj)->c_str());
char buf[80];
if (obj->cls == type_cls) {
snprintf(buf, 80, "<type '%s'>", getNameOfClass(static_cast<BoxedClass*>(obj))->c_str());
} else {
snprintf(buf, 80, "<%s object at %p>", getTypeName(obj)->c_str(), obj);
}
return boxStrConstant(buf);
} else {
obj = runtimeCall0(repr, ArgPassSpec(0));
}
assert(repr);
obj = runtimeCall0(repr, ArgPassSpec(0));
if (obj->cls != str_cls) {
raiseExcHelper(TypeError, "__repr__ did not return a string!");
......
......@@ -487,6 +487,21 @@ Box* objectInit(Box* b, BoxedTuple* args) {
return None;
}
Box* objectRepr(Box* obj) {
char buf[80];
if (obj->cls == type_cls) {
snprintf(buf, 80, "<type '%s'>", getNameOfClass(static_cast<BoxedClass*>(obj))->c_str());
} else {
snprintf(buf, 80, "<%s object at %p>", getTypeName(obj)->c_str(), obj);
}
return boxStrConstant(buf);
}
Box* objectStr(Box* obj) {
static const std::string repr_str("__repr__");
return callattrInternal(obj, &repr_str, CLASS_ONLY, NULL, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
}
bool TRACK_ALLOCATIONS = false;
void setupRuntime() {
root_hcls = HiddenClass::makeRoot();
......@@ -556,6 +571,8 @@ void setupRuntime() {
object_cls->giveAttr("__name__", boxStrConstant("object"));
object_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)objectNew, UNKNOWN, 1, 0, true, false)));
object_cls->giveAttr("__init__", new BoxedFunction(boxRTFunction((void*)objectInit, UNKNOWN, 1, 0, true, false)));
object_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)objectRepr, UNKNOWN, 1, 0, false, false)));
object_cls->giveAttr("__str__", new BoxedFunction(boxRTFunction((void*)objectStr, UNKNOWN, 1, 0, false, false)));
object_cls->freeze();
auto typeCallObj = boxRTFunction((void*)typeCall, UNKNOWN, 1, 0, true, false);
......
class C(object):
def __repr__(self):
print "repr"
return 1
c = C()
print "C object" in object.__repr__(c)
print object.__str__(c)
print c.__repr__()
print c.__str__()
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