Skip to content

Commit 51bbf6a

Browse files
committed
Implement support for __str__ and __repr__ special methods in classes.
1 parent 75488d5 commit 51bbf6a

3 files changed

Lines changed: 61 additions & 0 deletions

File tree

py/objtype.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,21 @@ STATIC mp_obj_t mp_obj_class_lookup(const mp_obj_type_t *type, qstr attr) {
7878
}
7979

8080
STATIC void class_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
81+
mp_obj_class_t *self = self_in;
82+
qstr meth = (kind == PRINT_STR) ? MP_QSTR___str__ : MP_QSTR___repr__;
83+
mp_obj_t member = mp_obj_class_lookup(self->base.type, meth);
84+
if (member == MP_OBJ_NULL && kind == PRINT_STR) {
85+
// If there's no __str__, fall back to __repr__
86+
member = mp_obj_class_lookup(self->base.type, MP_QSTR___repr__);
87+
}
88+
89+
if (member != MP_OBJ_NULL) {
90+
mp_obj_t r = rt_call_function_1(member, self_in);
91+
mp_obj_print_helper(print, env, r, PRINT_STR);
92+
return;
93+
}
94+
95+
// TODO: CPython prints fully-qualified type name
8196
print(env, "<%s object at %p>", mp_obj_get_type_str(self_in), self_in);
8297
}
8398

py/qstrdefs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ Q(__getitem__)
2121
Q(__setitem__)
2222
Q(__add__)
2323
Q(__sub__)
24+
Q(__repr__)
25+
Q(__str__)
2426

2527
Q(micropython)
2628
Q(byte_code)

tests/basics/class_str.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
class C1:
2+
def __init__(self, value):
3+
self.value = value
4+
5+
def __str__(self):
6+
return "str<C1 {}>".format(self.value)
7+
8+
class C2:
9+
def __init__(self, value):
10+
self.value = value
11+
12+
def __repr__(self):
13+
return "repr<C2 {}>".format(self.value)
14+
15+
class C3:
16+
def __init__(self, value):
17+
self.value = value
18+
19+
def __str__(self):
20+
return "str<C3 {}>".format(self.value)
21+
22+
def __repr__(self):
23+
return "repr<C3 {}>".format(self.value)
24+
25+
c1 = C1(1)
26+
print(c1)
27+
28+
c2 = C2(2)
29+
print(c2)
30+
31+
s11 = str(c1)
32+
print(s11)
33+
# This will use builtin repr(), which uses id(), which is of course different
34+
# between CPython and MicroPython
35+
s12 = repr(c1)
36+
print("C1 object at" in s12)
37+
38+
s21 = str(c2)
39+
print(s21)
40+
s22 = repr(c2)
41+
print(s22)
42+
43+
c3 = C3(1)
44+
print(c3)

0 commit comments

Comments
 (0)