From 51bbf6a006901fd3877c6abe3d5d67de74401310 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sun, 16 Mar 2014 15:16:54 +0200 Subject: [PATCH] Implement support for __str__ and __repr__ special methods in classes. --- py/objtype.c | 15 +++++++++++++ py/qstrdefs.h | 2 ++ tests/basics/class_str.py | 44 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 tests/basics/class_str.py diff --git a/py/objtype.c b/py/objtype.c index 9eb228ce3f..6480a99f6c 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -78,6 +78,21 @@ STATIC mp_obj_t mp_obj_class_lookup(const mp_obj_type_t *type, qstr attr) { } STATIC void class_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { + mp_obj_class_t *self = self_in; + qstr meth = (kind == PRINT_STR) ? MP_QSTR___str__ : MP_QSTR___repr__; + mp_obj_t member = mp_obj_class_lookup(self->base.type, meth); + if (member == MP_OBJ_NULL && kind == PRINT_STR) { + // If there's no __str__, fall back to __repr__ + member = mp_obj_class_lookup(self->base.type, MP_QSTR___repr__); + } + + if (member != MP_OBJ_NULL) { + mp_obj_t r = rt_call_function_1(member, self_in); + mp_obj_print_helper(print, env, r, PRINT_STR); + return; + } + + // TODO: CPython prints fully-qualified type name print(env, "<%s object at %p>", mp_obj_get_type_str(self_in), self_in); } diff --git a/py/qstrdefs.h b/py/qstrdefs.h index 2678526cda..8f6cc1167f 100644 --- a/py/qstrdefs.h +++ b/py/qstrdefs.h @@ -21,6 +21,8 @@ Q(__getitem__) Q(__setitem__) Q(__add__) Q(__sub__) +Q(__repr__) +Q(__str__) Q(micropython) Q(byte_code) diff --git a/tests/basics/class_str.py b/tests/basics/class_str.py new file mode 100644 index 0000000000..46dae2b5e6 --- /dev/null +++ b/tests/basics/class_str.py @@ -0,0 +1,44 @@ +class C1: + def __init__(self, value): + self.value = value + + def __str__(self): + return "str".format(self.value) + +class C2: + def __init__(self, value): + self.value = value + + def __repr__(self): + return "repr".format(self.value) + +class C3: + def __init__(self, value): + self.value = value + + def __str__(self): + return "str".format(self.value) + + def __repr__(self): + return "repr".format(self.value) + +c1 = C1(1) +print(c1) + +c2 = C2(2) +print(c2) + +s11 = str(c1) +print(s11) +# This will use builtin repr(), which uses id(), which is of course different +# between CPython and MicroPython +s12 = repr(c1) +print("C1 object at" in s12) + +s21 = str(c2) +print(s21) +s22 = repr(c2) +print(s22) + +c3 = C3(1) +print(c3)