8000 Re-add passing native methods the subclass instance · tannewt/circuitpython@63079c7 · GitHub
[go: up one dir, main page]

Skip to content

Commit 63079c7

Browse files
committed
Re-add passing native methods the subclass instance
Fixes micropython#8488
1 parent 53bc6d4 commit 63079c7

File tree

5 files changed

+41
-13
lines changed

5 files changed

+41
-13
lines changed

ports/unix/native_base_class.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,24 @@ MP_PROPERTY_GETSET(native_base_class_test_obj,
5555
(mp_obj_t)&native_base_class_get_test_obj,
5656
(mp_obj_t)&native_base_class_set_test_obj);
5757

58+
STATIC mp_obj_t native_base_class_obj_print_subclass_attr(mp_obj_t self_in, mp_obj_t attr_name_obj) {
59+
if (!mp_obj_is_str(attr_name_obj)) {
60+
mp_raise_TypeError(NULL);
61+
}
62+
qstr attr_name = mp_obj_str_get_qstr(attr_name_obj);
63+
mp_obj_t value = mp_load_attr(self_in, attr_name);
64+
mp_printf(&mp_plat_print, "native base class .%q set to: ", attr_name);
65+
mp_obj_print_helper(&mp_plat_print, value, PRINT_REPR);
66+
mp_printf(&mp_plat_print, "\n");
67+
return mp_const_none;
68+
}
69+
MP_DEFINE_CONST_FUN_OBJ_2(native_base_class_print_subclass_attr_obj, native_base_class_obj_print_subclass_attr);
70+
5871
STATIC const mp_rom_map_elem_t native_base_class_locals_dict_table[] = {
5972
{ MP_ROM_QSTR(MP_QSTR_test), MP_ROM_PTR(&native_base_class_test_obj) },
73+
74+
{ MP_ROM_QSTR(MP_QSTR_print_subclass_attr), MP_ROM_PTR(&native_base_class_print_subclass_attr_obj) },
75+
6076
};
6177
STATIC MP_DEFINE_CONST_DICT(native_base_class_locals_dict, native_base_class_locals_dict_table);
6278

py/objstringio.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,26 @@ STATIC void check_stringio_is_open(const mp_obj_stringio_t *o) {
4545
#define check_stringio_is_open(o)
4646
#endif
4747

48+
STATIC mp_obj_stringio_t *native_obj(mp_obj_t o_in) {
49+
mp_obj_stringio_t *native = mp_obj_cast_to_native_base(o_in, &mp_type_stringio);
50+
51+
#if MICROPY_PY_IO_BYTESIO
52+
if (native == MP_OBJ_NULL) {
53+
native = mp_obj_cast_to_native_base(o_in, &mp_type_bytesio);
54+
}
55+
#endif
56+
return native;
57+
}
58+
4859
STATIC void stringio_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
4960
(void)kind;
50-
mp_obj_stringio_t *self = MP_OBJ_TO_PTR(self_in);
61+
mp_obj_stringio_t *self = native_obj(self_in);
5162
mp_printf(print, self->base.type == &mp_type_stringio ? "<io.StringIO 0x%x>" : "<io.BytesIO 0x%x>", self);
5263
}
5364

5465
STATIC mp_uint_t stringio_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) {
5566
(void)errcode;
56-
mp_obj_stringio_t *o = MP_OBJ_TO_PTR(o_in);
67+
mp_obj_stringio_t *o = native_obj(o_in);
5768
check_stringio_is_open(o);
5869
if (o->vstr->len <= o->pos) { // read to EOF, or seeked to EOF or beyond
5970
return 0;
@@ -77,7 +88,7 @@ STATIC void stringio_copy_on_write(mp_obj_stringio_t *o) {
7788

7889
STATIC mp_uint_t stringio_write(mp_obj_t o_in, const void *buf, mp_uint_t size, int *errcode) {
7990
(void)errcode;
80-
mp_obj_stringio_t *o = MP_OBJ_TO_PTR(o_in);
91+
mp_obj_stringio_t *o = native_obj(o_in);
8192
check_stringio_is_open(o);
8293

8394
if (o->vstr->fixed_buf) {
@@ -111,7 +122,7 @@ STATIC mp_uint_t stringio_write(mp_obj_t o_in, const void *buf, mp_uint_t size,
111122

112123
STATIC mp_uint_t stringio_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, int *errcode) {
113124
(void)errcode;
114-
mp_obj_stringio_t *o = MP_OBJ_TO_PTR(o_in);
125+
mp_obj_stringio_t *o = native_obj(o_in);
115126
switch (request) {
116127
case MP_STREAM_SEEK: {
117128
struct mp_stream_seek_t *s = (struct mp_stream_seek_t *)arg;
@@ -163,7 +174,7 @@ STATIC mp_uint_t stringio_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg,
163174
#define STREAM_TO_CONTENT_TYPE(o) (((o)->base.type == &mp_type_stringio) ? &mp_type_str : &mp_type_bytes)
164175

165176
STATIC mp_obj_t stringio_getvalue(mp_obj_t self_in) {
166-
mp_obj_stringio_t *self = MP_OBJ_TO_PTR(self_in);
177+
mp_obj_stringio_t *self = native_obj(self_in);
167178
check_stringio_is_open(self);
168179
// TODO: Try to avoid copying string
169180
return mp_obj_new_str_of_type(STREAM_TO_CONTENT_TYPE(self), (byte *)self->vstr->buf, self->vstr->len);

py/objtype.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -199,14 +199,9 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_t
199199
return;
200200
} else {
201201
mp_obj_instance_t *obj = lookup->obj;
202-
mp_obj_t obj_obj;
203-
if (obj != NULL && mp_obj_is_native_type(type) && type != &mp_type_object /* object is not a real type */) {
204-
// If we're dealing with native base class, then it applies to native sub-object
205-
obj_obj = obj->subobj[0];
206-
} else {
207-
obj_obj = MP_OBJ_FROM_PTR(obj);
208-
}
209-
mp_convert_member_lookup(obj_obj, type, elem->value, lookup->dest);
202+
// CIRCUITPY-CHANGE: Pass object directly. MP passes the native object.
203+
// This allows native code to lookup and call functions on Python subclasses.
204+
mp_convert_member_lookup(obj, type, elem->value, lookup->dest);
210205
}
211206
#if DEBUG_PRINT
212207
DEBUG_printf("mp_obj_class_lookup: Returning: ");

tests/unix/subclass_native.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ class A(NativeBaseClass):
2929
a._new_attribute = True
3030
print("._new_attribute", a._new_attribute)
3131

32+
a.print_subclass_attr("_new_attribute")
33+
3234

3335
class B(NativeBaseClass):
3436
def __init__(self, suffix):
@@ -43,3 +45,5 @@ def __init__(self, suffix):
4345

4446
b._new_attribute = True
4547
print("._new_attribute", b._new_attribute)
48+
49+
b.print_subclass_attr("_new_attribute")

tests/unix/subclass_native.py.exp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ native base class .test set to: 'test set directly'
55
native base class .test set to: 'test set indirectly'
66
.test: test set indirectly
77
._new_attribute True
8+
native base class ._new_attribute set to: True
89
.test: super init suffix
910
native base class .test set to: 'test set indirectly through b'
1011
.test: test set indirectly through b
1112
._new_attribute True
13+
native base class ._new_attribute set to: True

0 commit comments

Comments
 (0)
0