parent
53bc6d4bd1
commit
63079c75b0
@ -55,8 +55,24 @@ MP_PROPERTY_GETSET(native_base_class_test_obj,
|
||||
(mp_obj_t)&native_base_class_get_test_obj,
|
||||
(mp_obj_t)&native_base_class_set_test_obj);
|
||||
|
||||
STATIC mp_obj_t native_base_class_obj_print_subclass_attr(mp_obj_t self_in, mp_obj_t attr_name_obj) {
|
||||
if (!mp_obj_is_str(attr_name_obj)) {
|
||||
mp_raise_TypeError(NULL);
|
||||
}
|
||||
qstr attr_name = mp_obj_str_get_qstr(attr_name_obj);
|
||||
mp_obj_t value = mp_load_attr(self_in, attr_name);
|
||||
mp_printf(&mp_plat_print, "native base class .%q set to: ", attr_name);
|
||||
mp_obj_print_helper(&mp_plat_print, value, PRINT_REPR);
|
||||
mp_printf(&mp_plat_print, "\n");
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(native_base_class_print_subclass_attr_obj, native_base_class_obj_print_subclass_attr);
|
||||
|
||||
STATIC const mp_rom_map_elem_t native_base_class_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_test), MP_ROM_PTR(&native_base_class_test_obj) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_print_subclass_attr), MP_ROM_PTR(&native_base_class_print_subclass_attr_obj) },
|
||||
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(native_base_class_locals_dict, native_base_class_locals_dict_table);
|
||||
|
||||
|
@ -45,15 +45,26 @@ STATIC void check_stringio_is_open(const mp_obj_stringio_t *o) {
|
||||
#define check_stringio_is_open(o)
|
||||
#endif
|
||||
|
||||
STATIC mp_obj_stringio_t *native_obj(mp_obj_t o_in) {
|
||||
mp_obj_stringio_t *native = mp_obj_cast_to_native_base(o_in, &mp_type_stringio);
|
||||
|
||||
#if MICROPY_PY_IO_BYTESIO
|
||||
if (native == MP_OBJ_NULL) {
|
||||
native = mp_obj_cast_to_native_base(o_in, &mp_type_bytesio);
|
||||
}
|
||||
#endif
|
||||
return native;
|
||||
}
|
||||
|
||||
STATIC void stringio_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
(void)kind;
|
||||
mp_obj_stringio_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_obj_stringio_t *self = native_obj(self_in);
|
||||
mp_printf(print, self->base.type == &mp_type_stringio ? "<io.StringIO 0x%x>" : "<io.BytesIO 0x%x>", self);
|
||||
}
|
||||
|
||||
STATIC mp_uint_t stringio_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) {
|
||||
(void)errcode;
|
||||
mp_obj_stringio_t *o = MP_OBJ_TO_PTR(o_in);
|
||||
mp_obj_stringio_t *o = native_obj(o_in);
|
||||
check_stringio_is_open(o);
|
||||
if (o->vstr->len <= o->pos) { // read to EOF, or seeked to EOF or beyond
|
||||
return 0;
|
||||
@ -77,7 +88,7 @@ STATIC void stringio_copy_on_write(mp_obj_stringio_t *o) {
|
||||
|
||||
STATIC mp_uint_t stringio_write(mp_obj_t o_in, const void *buf, mp_uint_t size, int *errcode) {
|
||||
(void)errcode;
|
||||
mp_obj_stringio_t *o = MP_OBJ_TO_PTR(o_in);
|
||||
mp_obj_stringio_t *o = native_obj(o_in);
|
||||
check_stringio_is_open(o);
|
||||
|
||||
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,
|
||||
|
||||
STATIC mp_uint_t stringio_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, int *errcode) {
|
||||
(void)errcode;
|
||||
mp_obj_stringio_t *o = MP_OBJ_TO_PTR(o_in);
|
||||
mp_obj_stringio_t *o = native_obj(o_in);
|
||||
switch (request) {
|
||||
case MP_STREAM_SEEK: {
|
||||
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,
|
||||
#define STREAM_TO_CONTENT_TYPE(o) (((o)->base.type == &mp_type_stringio) ? &mp_type_str : &mp_type_bytes)
|
||||
|
||||
STATIC mp_obj_t stringio_getvalue(mp_obj_t self_in) {
|
||||
mp_obj_stringio_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_obj_stringio_t *self = native_obj(self_in);
|
||||
check_stringio_is_open(self);
|
||||
// TODO: Try to avoid copying string
|
||||
return mp_obj_new_str_of_type(STREAM_TO_CONTENT_TYPE(self), (byte *)self->vstr->buf, self->vstr->len);
|
||||
|
11
py/objtype.c
11
py/objtype.c
@ -199,14 +199,9 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_t
|
||||
return;
|
||||
} else {
|
||||
mp_obj_instance_t *obj = lookup->obj;
|
||||
mp_obj_t obj_obj;
|
||||
if (obj != NULL && mp_obj_is_native_type(type) && type != &mp_type_object /* object is not a real type */) {
|
||||
// If we're dealing with native base class, then it applies to native sub-object
|
||||
obj_obj = obj->subobj[0];
|
||||
} else {
|
||||
obj_obj = MP_OBJ_FROM_PTR(obj);
|
||||
}
|
||||
mp_convert_member_lookup(obj_obj, type, elem->value, lookup->dest);
|
||||
// CIRCUITPY-CHANGE: Pass object directly. MP passes the native object.
|
||||
// This allows native code to lookup and call functions on Python subclasses.
|
||||
mp_convert_member_lookup(obj, type, elem->value, lookup->dest);
|
||||
}
|
||||
#if DEBUG_PRINT
|
||||
DEBUG_printf("mp_obj_class_lookup: Returning: ");
|
||||
|
@ -29,6 +29,8 @@ print(".test:", a.test)
|
||||
a._new_attribute = True
|
||||
print("._new_attribute", a._new_attribute)
|
||||
|
||||
a.print_subclass_attr("_new_attribute")
|
||||
|
||||
|
||||
class B(NativeBaseClass):
|
||||
def __init__(self, suffix):
|
||||
@ -43,3 +45,5 @@ print(".test:", b.test)
|
||||
|
||||
b._new_attribute = True
|
||||
print("._new_attribute", b._new_attribute)
|
||||
|
||||
b.print_subclass_attr("_new_attribute")
|
||||
|
@ -5,7 +5,9 @@ native base class .test set to: 'test set directly'
|
||||
native base class .test set to: 'test set indirectly'
|
||||
.test: test set indirectly
|
||||
._new_attribute True
|
||||
native base class ._new_attribute set to: True
|
||||
.test: super init suffix
|
||||
native base class .test set to: 'test set indirectly through b'
|
||||
.test: test set indirectly through b
|
||||
._new_attribute True
|
||||
native base class ._new_attribute set to: True
|
||||
|
Loading…
Reference in New Issue
Block a user