Skip to content

Commit 63079c7

Browse files
committed
Re-add passing native methods the subclass instance
Fixes #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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy