Skip to content

Commit 4824404

Browse files
committed
py: Allow subclass of native object to delegate to the native buffer_p.
Addresses issue adafruit#1109.
1 parent 1a6721f commit 4824404

2 files changed

Lines changed: 39 additions & 1 deletion

File tree

py/objtype.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,25 @@ STATIC mp_obj_t instance_getiter(mp_obj_t self_in) {
666666
return mp_call_function_n_kw(meth, 0, 0, NULL);
667667
}
668668

669+
STATIC mp_int_t instance_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
670+
mp_obj_instance_t *self = self_in;
671+
mp_obj_t member[2] = {MP_OBJ_NULL};
672+
struct class_lookup_data lookup = {
673+
.obj = self,
674+
.attr = MP_QSTR_, // don't actually look for a method
675+
.meth_offset = offsetof(mp_obj_type_t, buffer_p.get_buffer),
676+
.dest = member,
677+
.is_type = false,
678+
};
679+
mp_obj_class_lookup(&lookup, self->base.type);
680+
if (member[0] == MP_OBJ_SENTINEL) {
681+
mp_obj_type_t *type = mp_obj_get_type(self->subobj[0]);
682+
return type->buffer_p.get_buffer(self->subobj[0], bufinfo, flags);
683+
} else {
684+
return 1; // object does not support buffer protocol
685+
}
686+
}
687+
669688
/******************************************************************************/
670689
// type object
671690
// - the struct is mp_obj_type_t and is defined in obj.h so const types can be made
@@ -807,13 +826,16 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
807826
o->name = name;
808827
o->print = instance_print;
809828
o->make_new = instance_make_new;
829+
o->call = mp_obj_instance_call;
810830
o->unary_op = instance_unary_op;
811831
o->binary_op = instance_binary_op;
812832
o->load_attr = mp_obj_instance_load_attr;
813833
o->store_attr = mp_obj_instance_store_attr;
814834
o->subscr = instance_subscr;
815-
o->call = mp_obj_instance_call;
816835
o->getiter = instance_getiter;
836+
//o->iternext = ; not implemented
837+
o->buffer_p.get_buffer = instance_get_buffer;
838+
//o->stream_p = ; not implemented
817839
o->bases_tuple = bases_tuple;
818840
o->locals_dict = locals_dict;
819841

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# test when we subclass a type with the buffer protocol
2+
3+
class my_bytes(bytes):
4+
pass
5+
6+
b1 = my_bytes([0, 1])
7+
b2 = my_bytes([2, 3])
8+
b3 = bytes([4, 5])
9+
10+
# addition will use the buffer protocol on the RHS
11+
print(b1 + b2)
12+
print(b1 + b3)
13+
print(b3 + b1)
14+
15+
# bytearray construction will use the buffer protocol
16+
print(bytearray(b1))

0 commit comments

Comments
 (0)