summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--py/obj.h19
-rw-r--r--py/objtype.c26
-rw-r--r--py/qstrdefs.h2
-rw-r--r--py/runtime.c11
4 files changed, 38 insertions, 20 deletions
diff --git a/py/obj.h b/py/obj.h
index 2f4d441264..660ac6627c 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -66,11 +66,11 @@ typedef struct _mp_obj_base_t mp_obj_base_t;
// These macros are used to declare and define constant staticmethond and classmethod objects
// You can put "static" in front of the definitions to make them local
-#define MP_DECLARE_CONST_STATICMETHOD_OBJ(obj_name) extern const mp_obj_staticmethod_t obj_name
-#define MP_DECLARE_CONST_CLASSMETHOD_OBJ(obj_name) extern const mp_obj_classmethod_t obj_name
+#define MP_DECLARE_CONST_STATICMETHOD_OBJ(obj_name) extern const mp_obj_static_class_method_t obj_name
+#define MP_DECLARE_CONST_CLASSMETHOD_OBJ(obj_name) extern const mp_obj_static_class_method_t obj_name
-#define MP_DEFINE_CONST_STATICMETHOD_OBJ(obj_name, fun_name) const mp_obj_staticmethod_t obj_name = {{&mp_type_staticmethod}, fun_name}
-#define MP_DEFINE_CONST_CLASSMETHOD_OBJ(obj_name, fun_name) const mp_obj_classmethod_t obj_name = {{&mp_type_classmethod}, fun_name}
+#define MP_DEFINE_CONST_STATICMETHOD_OBJ(obj_name, fun_name) const mp_obj_static_class_method_t obj_name = {{&mp_type_staticmethod}, fun_name}
+#define MP_DEFINE_CONST_CLASSMETHOD_OBJ(obj_name, fun_name) const mp_obj_static_class_method_t obj_name = {{&mp_type_classmethod}, fun_name}
// Need to declare this here so we are not dependent on map.h
struct _mp_map_t;
@@ -180,7 +180,6 @@ struct _mp_obj_type_t {
abs float complex
hash bool int none str
equal int str
- less int
get_array_n tuple list
unpack seq list tuple
@@ -389,15 +388,11 @@ struct _mp_map_t *mp_obj_module_get_globals(mp_obj_t self_in);
extern const mp_obj_type_t mp_type_staticmethod;
extern const mp_obj_type_t mp_type_classmethod;
-typedef struct _mp_obj_staticmethod_t {
+// this structure is used for instances of both staticmethod and classmethod
+typedef struct _mp_obj_static_class_method_t {
mp_obj_base_t base;
mp_obj_t fun;
-} mp_obj_staticmethod_t;
-
-typedef struct _mp_obj_classmethod_t {
- mp_obj_base_t base;
- mp_obj_t fun;
-} mp_obj_classmethod_t;
+} mp_obj_static_class_method_t;
// sequence helpers
void mp_seq_multiply(const void *items, uint item_sz, uint len, uint times, void *dest);
diff --git a/py/objtype.c b/py/objtype.c
index 6934cb354d..6ff18b47bf 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -212,10 +212,10 @@ static void class_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
// TODO check that this is the correct place to have this logic
if (MP_OBJ_IS_TYPE(member, &mp_type_staticmethod)) {
// return just the function
- dest[0] = ((mp_obj_staticmethod_t*)member)->fun;
+ dest[0] = ((mp_obj_static_class_method_t*)member)->fun;
} else if (MP_OBJ_IS_TYPE(member, &mp_type_classmethod)) {
// return a bound method, with self being the type of this object
- dest[0] = ((mp_obj_classmethod_t*)member)->fun;
+ dest[0] = ((mp_obj_static_class_method_t*)member)->fun;
dest[1] = mp_obj_get_type(self_in);
} else {
// return a bound method, with self being this object
@@ -304,10 +304,10 @@ static void type_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
// see http://docs.python.org/3.3/howto/descriptor.html
if (MP_OBJ_IS_TYPE(member, &mp_type_staticmethod)) {
// return just the function
- dest[0] = ((mp_obj_staticmethod_t*)member)->fun;
+ dest[0] = ((mp_obj_static_class_method_t*)member)->fun;
} else if (MP_OBJ_IS_TYPE(member, &mp_type_classmethod)) {
// return a bound method, with self being this class
- dest[0] = ((mp_obj_classmethod_t*)member)->fun;
+ dest[0] = ((mp_obj_static_class_method_t*)member)->fun;
dest[1] = self_in;
} else {
// return just the function
@@ -417,10 +417,10 @@ static void super_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
// TODO check that this is the correct place to have this logic
if (MP_OBJ_IS_TYPE(member, &mp_type_staticmethod)) {
// return just the function
- dest[0] = ((mp_obj_staticmethod_t*)member)->fun;
+ dest[0] = ((mp_obj_static_class_method_t*)member)->fun;
} else if (MP_OBJ_IS_TYPE(member, &mp_type_classmethod)) {
// return a bound method, with self being the type of this object
- dest[0] = ((mp_obj_classmethod_t*)member)->fun;
+ dest[0] = ((mp_obj_static_class_method_t*)member)->fun;
dest[1] = mp_obj_get_type(self->obj);
} else {
// return a bound method, with self being this object
@@ -507,12 +507,26 @@ MP_DEFINE_CONST_FUN_OBJ_2(mp_builtin_isinstance_obj, mp_builtin_isinstance);
/******************************************************************************/
// staticmethod and classmethod types (probably should go in a different file)
+static mp_obj_t static_class_method_make_new(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) {
+ assert(self_in == &mp_type_staticmethod || self_in == &mp_type_classmethod);
+
+ if (n_args != 1 || n_kw != 0) {
+ nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "function takes 1 positional argument but %d were given", (void*)(machine_int_t)n_args));
+ }
+
+ mp_obj_static_class_method_t *o = m_new_obj(mp_obj_static_class_method_t);
+ *o = (mp_obj_static_class_method_t){{(mp_obj_type_t*)self_in}, args[0]};
+ return o;
+}
+
const mp_obj_type_t mp_type_staticmethod = {
{ &mp_const_type },
"staticmethod",
+ .make_new = static_class_method_make_new
};
const mp_obj_type_t mp_type_classmethod = {
{ &mp_const_type },
"classmethod",
+ .make_new = static_class_method_make_new
};
diff --git a/py/qstrdefs.h b/py/qstrdefs.h
index dcd4ba42c0..b90c5023de 100644
--- a/py/qstrdefs.h
+++ b/py/qstrdefs.h
@@ -51,6 +51,7 @@ Q(bytearray)
Q(bytes)
Q(callable)
Q(chr)
+Q(classmethod)
Q(complex)
Q(dict)
Q(dir)
@@ -80,6 +81,7 @@ Q(range)
Q(repr)
Q(set)
Q(sorted)
+Q(staticmethod)
Q(sum)
Q(super)
Q(str)
diff --git a/py/runtime.c b/py/runtime.c
index fc18c01510..6790da4e59 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -134,6 +134,9 @@ void rt_init(void) {
mp_map_add_qstr(&map_builtins, MP_QSTR_type, (mp_obj_t)&mp_const_type);
mp_map_add_qstr(&map_builtins, MP_QSTR_zip, (mp_obj_t)&zip_type);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_classmethod, (mp_obj_t)&mp_type_classmethod);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_staticmethod, (mp_obj_t)&mp_type_staticmethod);
+
mp_obj_t m_array = mp_obj_new_module(MP_QSTR_array);
rt_store_attr(m_array, MP_QSTR_array, (mp_obj_t)&array_type);
@@ -876,10 +879,10 @@ static void rt_load_method_maybe(mp_obj_t base, qstr attr, mp_obj_t *dest) {
// see http://docs.python.org/3.3/howto/descriptor.html
if (MP_OBJ_IS_TYPE(meth->fun, &mp_type_staticmethod)) {
// return just the function
- dest[0] = ((mp_obj_staticmethod_t*)meth->fun)->fun;
+ dest[0] = ((mp_obj_static_class_method_t*)meth->fun)->fun;
} else if (MP_OBJ_IS_TYPE(meth->fun, &mp_type_classmethod)) {
// return a bound method, with self being the type of this object
- dest[0] = ((mp_obj_classmethod_t*)meth->fun)->fun;
+ dest[0] = ((mp_obj_static_class_method_t*)meth->fun)->fun;
dest[1] = mp_obj_get_type(base);
} else {
// return a bound method, with self being this object
@@ -970,6 +973,8 @@ mp_obj_t rt_iternext(mp_obj_t o_in) {
}
mp_obj_t rt_import_name(qstr name, mp_obj_t fromlist, mp_obj_t level) {
+ DEBUG_printf("import name %s\n", qstr_str(name));
+
// build args array
mp_obj_t args[5];
args[0] = MP_OBJ_NEW_QSTR(name);
@@ -983,6 +988,8 @@ mp_obj_t rt_import_name(qstr name, mp_obj_t fromlist, mp_obj_t level) {
}
mp_obj_t rt_import_from(mp_obj_t module, qstr name) {
+ DEBUG_printf("import from %p %s\n", module, qstr_str(name));
+
mp_obj_t x = rt_load_attr(module, name);
/* TODO convert AttributeError to ImportError
if (fail) {