Branch data Line data Source code
1 : : /*
2 : : * This file is part of the MicroPython project, http://micropython.org/
3 : : *
4 : : * The MIT License (MIT)
5 : : *
6 : : * Copyright (c) 2013, 2014 Damien P. George
7 : : *
8 : : * Permission is hereby granted, free of charge, to any person obtaining a copy
9 : : * of this software and associated documentation files (the "Software"), to deal
10 : : * in the Software without restriction, including without limitation the rights
11 : : * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 : : * copies of the Software, and to permit persons to whom the Software is
13 : : * furnished to do so, subject to the following conditions:
14 : : *
15 : : * The above copyright notice and this permission notice shall be included in
16 : : * all copies or substantial portions of the Software.
17 : : *
18 : : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 : : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 : : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 : : * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 : : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 : : * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 : : * THE SOFTWARE.
25 : : */
26 : :
27 : : #include <stdlib.h>
28 : :
29 : : #include "py/objtype.h"
30 : : #include "py/runtime.h"
31 : :
32 : : typedef struct _mp_obj_object_t {
33 : : mp_obj_base_t base;
34 : : } mp_obj_object_t;
35 : :
36 : 16 : static mp_obj_t object_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
37 : 16 : (void)args;
38 : 16 : mp_arg_check_num(n_args, n_kw, 0, 0, false);
39 : 16 : mp_obj_object_t *o = mp_obj_malloc(mp_obj_object_t, type);
40 : 16 : return MP_OBJ_FROM_PTR(o);
41 : : }
42 : :
43 : : #if MICROPY_CPYTHON_COMPAT
44 : 28 : static mp_obj_t object___init__(mp_obj_t self) {
45 : 28 : (void)self;
46 : 28 : return mp_const_none;
47 : : }
48 : : static MP_DEFINE_CONST_FUN_OBJ_1(object___init___obj, object___init__);
49 : :
50 : 24 : static mp_obj_t object___new__(mp_obj_t cls) {
51 [ - + - + : 24 : if (!mp_obj_is_type(cls, &mp_type_type) || !mp_obj_is_instance_type((mp_obj_type_t *)MP_OBJ_TO_PTR(cls))) {
- + - + +
+ + - +
+ ]
52 : 8 : mp_raise_TypeError(MP_ERROR_TEXT("arg must be user-type"));
53 : : }
54 : : // This executes only "__new__" part of instance creation.
55 : : // TODO: This won't work well for classes with native bases.
56 : : // TODO: This is a hack, should be resolved along the lines of
57 : : // https://github.com/micropython/micropython/issues/606#issuecomment-43685883
58 : 16 : const mp_obj_type_t *native_base;
59 : 16 : return MP_OBJ_FROM_PTR(mp_obj_new_instance(MP_OBJ_TO_PTR(cls), &native_base));
60 : : }
61 : : static MP_DEFINE_CONST_FUN_OBJ_1(object___new___fun_obj, object___new__);
62 : : static MP_DEFINE_CONST_STATICMETHOD_OBJ(object___new___obj, MP_ROM_PTR(&object___new___fun_obj));
63 : :
64 : : #if MICROPY_PY_DELATTR_SETATTR
65 : 12 : static mp_obj_t object___setattr__(mp_obj_t self_in, mp_obj_t attr, mp_obj_t value) {
66 [ - + ]: 12 : if (!mp_obj_is_instance_type(mp_obj_get_type(self_in))) {
67 : 0 : mp_raise_TypeError(MP_ERROR_TEXT("arg must be user-type"));
68 : : }
69 : :
70 [ + + - + : 12 : if (!mp_obj_is_str(attr)) {
- - ]
71 : 4 : mp_raise_TypeError(NULL);
72 : : }
73 : :
74 : 8 : mp_obj_instance_t *self = MP_OBJ_TO_PTR(self_in);
75 : 8 : mp_map_lookup(&self->members, attr, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value;
76 : 8 : return mp_const_none;
77 : : }
78 : : static MP_DEFINE_CONST_FUN_OBJ_3(object___setattr___obj, object___setattr__);
79 : :
80 : 12 : static mp_obj_t object___delattr__(mp_obj_t self_in, mp_obj_t attr) {
81 [ - + ]: 12 : if (!mp_obj_is_instance_type(mp_obj_get_type(self_in))) {
82 : 0 : mp_raise_TypeError(MP_ERROR_TEXT("arg must be user-type"));
83 : : }
84 : :
85 [ - + - - : 12 : if (!mp_obj_is_str(attr)) {
- - ]
86 : 0 : mp_raise_TypeError(NULL);
87 : : }
88 : :
89 : 12 : mp_obj_instance_t *self = MP_OBJ_TO_PTR(self_in);
90 [ + + ]: 12 : if (mp_map_lookup(&self->members, attr, MP_MAP_LOOKUP_REMOVE_IF_FOUND) == NULL) {
91 : 4 : mp_raise_msg(&mp_type_AttributeError, MP_ERROR_TEXT("no such attribute"));
92 : : }
93 : 8 : return mp_const_none;
94 : : }
95 : : static MP_DEFINE_CONST_FUN_OBJ_2(object___delattr___obj, object___delattr__);
96 : : #endif
97 : :
98 : : static const mp_rom_map_elem_t object_locals_dict_table[] = {
99 : : #if MICROPY_CPYTHON_COMPAT
100 : : { MP_ROM_QSTR(MP_QSTR___init__), MP_ROM_PTR(&object___init___obj) },
101 : : #endif
102 : : #if MICROPY_CPYTHON_COMPAT
103 : : { MP_ROM_QSTR(MP_QSTR___new__), MP_ROM_PTR(&object___new___obj) },
104 : : #endif
105 : : #if MICROPY_PY_DELATTR_SETATTR
106 : : { MP_ROM_QSTR(MP_QSTR___setattr__), MP_ROM_PTR(&object___setattr___obj) },
107 : : { MP_ROM_QSTR(MP_QSTR___delattr__), MP_ROM_PTR(&object___delattr___obj) },
108 : : #endif
109 : : };
110 : :
111 : : static MP_DEFINE_CONST_DICT(object_locals_dict, object_locals_dict_table);
112 : : #endif
113 : :
114 : : #if MICROPY_CPYTHON_COMPAT
115 : : #define OBJECT_TYPE_LOCALS_DICT , locals_dict, &object_locals_dict
116 : : #else
117 : : #define OBJECT_TYPE_LOCALS_DICT
118 : : #endif
119 : :
120 : : MP_DEFINE_CONST_OBJ_TYPE(
121 : : mp_type_object,
122 : : MP_QSTR_object,
123 : : MP_TYPE_FLAG_NONE,
124 : : make_new, object_make_new
125 : : OBJECT_TYPE_LOCALS_DICT
126 : : );
|