Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
uPython-mirror
Commits
777b0f32
Commit
777b0f32
authored
Apr 13, 2014
by
Damien George
Browse files
py: Add property object, with basic functionality.
Enabled by MICROPY_ENABLE_PROPERTY.
parent
4417478d
Changes
8
Hide whitespace changes
Inline
Side-by-side
py/builtintables.c
View file @
777b0f32
...
...
@@ -31,6 +31,9 @@ STATIC const mp_map_elem_t mp_builtin_object_table[] = {
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_list
),
(
mp_obj_t
)
&
mp_type_list
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_map
),
(
mp_obj_t
)
&
mp_type_map
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_object
),
(
mp_obj_t
)
&
mp_type_object
},
#if MICROPY_ENABLE_PROPERTY
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_property
),
(
mp_obj_t
)
&
mp_type_property
},
#endif
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_set
),
(
mp_obj_t
)
&
mp_type_set
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_str
),
(
mp_obj_t
)
&
mp_type_str
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_super
),
(
mp_obj_t
)
&
mp_type_super
},
...
...
py/mpconfig.h
View file @
777b0f32
...
...
@@ -135,6 +135,11 @@ typedef double mp_float_t;
#define MICROPY_ENABLE_SLICE (1)
#endif
// Whether to support the property object
#ifndef MICROPY_ENABLE_PROPERTY
#define MICROPY_ENABLE_PROPERTY (0)
#endif
// Enable features which improve CPython compatibility
// but may lead to more code size/memory usage.
// TODO: Originally intended as generic category to not
...
...
py/obj.h
View file @
777b0f32
...
...
@@ -283,6 +283,7 @@ extern const mp_obj_type_t mp_type_fun_bc;
extern
const
mp_obj_type_t
mp_type_module
;
extern
const
mp_obj_type_t
mp_type_staticmethod
;
extern
const
mp_obj_type_t
mp_type_classmethod
;
extern
const
mp_obj_type_t
mp_type_property
;
// Exceptions
extern
const
mp_obj_type_t
mp_type_BaseException
;
...
...
@@ -518,6 +519,9 @@ typedef struct _mp_obj_static_class_method_t {
mp_obj_t
fun
;
}
mp_obj_static_class_method_t
;
// property
const
mp_obj_t
*
mp_obj_property_get
(
mp_obj_t
self_in
);
// sequence helpers
void
mp_seq_multiply
(
const
void
*
items
,
uint
item_sz
,
uint
len
,
uint
times
,
void
*
dest
);
bool
m_seq_get_fast_slice_indexes
(
machine_uint_t
len
,
mp_obj_t
slice
,
machine_uint_t
*
begin
,
machine_uint_t
*
end
);
...
...
py/objproperty.c
0 → 100644
View file @
777b0f32
#include <stdlib.h>
#include <assert.h>
#include "nlr.h"
#include "misc.h"
#include "mpconfig.h"
#include "qstr.h"
#include "obj.h"
#include "runtime.h"
#if MICROPY_ENABLE_PROPERTY
typedef
struct
_mp_obj_property_t
{
mp_obj_base_t
base
;
mp_obj_t
proxy
[
3
];
// getter, setter, deleter
}
mp_obj_property_t
;
STATIC
mp_obj_t
property_make_new
(
mp_obj_t
type_in
,
uint
n_args
,
uint
n_kw
,
const
mp_obj_t
*
args
)
{
// TODO check n_kw == 0
mp_obj_property_t
*
o
=
m_new_obj
(
mp_obj_property_t
);
o
->
base
.
type
=
&
mp_type_property
;
if
(
n_args
>=
5
)
{
nlr_raise
(
mp_obj_new_exception_msg_varg
(
&
mp_type_TypeError
,
"property takes at most 4 arguments"
));
}
if
(
n_args
>=
4
)
{
// doc ignored
}
if
(
n_args
>=
3
)
{
o
->
proxy
[
2
]
=
args
[
2
];
}
else
{
o
->
proxy
[
2
]
=
mp_const_none
;
}
if
(
n_args
>=
2
)
{
o
->
proxy
[
1
]
=
args
[
1
];
}
else
{
o
->
proxy
[
1
]
=
mp_const_none
;
}
if
(
n_args
>=
1
)
{
o
->
proxy
[
0
]
=
args
[
0
];
}
else
{
o
->
proxy
[
0
]
=
mp_const_none
;
}
return
o
;
}
STATIC
mp_obj_t
property_getter
(
mp_obj_t
self_in
,
mp_obj_t
getter
)
{
mp_obj_property_t
*
p2
=
m_new_obj
(
mp_obj_property_t
);
*
p2
=
*
(
mp_obj_property_t
*
)
self_in
;
p2
->
proxy
[
0
]
=
getter
;
return
p2
;
}
STATIC
MP_DEFINE_CONST_FUN_OBJ_2
(
property_getter_obj
,
property_getter
);
STATIC
mp_obj_t
property_setter
(
mp_obj_t
self_in
,
mp_obj_t
setter
)
{
mp_obj_property_t
*
p2
=
m_new_obj
(
mp_obj_property_t
);
*
p2
=
*
(
mp_obj_property_t
*
)
self_in
;
p2
->
proxy
[
1
]
=
setter
;
return
p2
;
}
STATIC
MP_DEFINE_CONST_FUN_OBJ_2
(
property_setter_obj
,
property_setter
);
STATIC
mp_obj_t
property_deleter
(
mp_obj_t
self_in
,
mp_obj_t
deleter
)
{
mp_obj_property_t
*
p2
=
m_new_obj
(
mp_obj_property_t
);
*
p2
=
*
(
mp_obj_property_t
*
)
self_in
;
p2
->
proxy
[
2
]
=
deleter
;
return
p2
;
}
STATIC
MP_DEFINE_CONST_FUN_OBJ_2
(
property_deleter_obj
,
property_deleter
);
STATIC
const
mp_map_elem_t
property_locals_dict_table
[]
=
{
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_getter
),
(
mp_obj_t
)
&
property_getter_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_setter
),
(
mp_obj_t
)
&
property_setter_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_deleter
),
(
mp_obj_t
)
&
property_deleter_obj
},
};
STATIC
MP_DEFINE_CONST_DICT
(
property_locals_dict
,
property_locals_dict_table
);
const
mp_obj_type_t
mp_type_property
=
{
{
&
mp_type_type
},
.
name
=
MP_QSTR_property
,
.
make_new
=
property_make_new
,
.
locals_dict
=
(
mp_obj_t
)
&
property_locals_dict
,
};
const
mp_obj_t
*
mp_obj_property_get
(
mp_obj_t
self_in
)
{
assert
(
MP_OBJ_IS_TYPE
(
self_in
,
&
mp_type_property
));
mp_obj_property_t
*
self
=
self_in
;
return
self
->
proxy
;
}
#endif // MICROPY_ENABLE_PROPERTY
py/objtype.c
View file @
777b0f32
...
...
@@ -229,15 +229,35 @@ STATIC mp_obj_t class_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
STATIC
void
class_load_attr
(
mp_obj_t
self_in
,
qstr
attr
,
mp_obj_t
*
dest
)
{
// logic: look in obj members then class locals (TODO check this against CPython)
mp_obj_class_t
*
self
=
self_in
;
mp_map_elem_t
*
elem
=
mp_map_lookup
(
&
self
->
members
,
MP_OBJ_NEW_QSTR
(
attr
),
MP_MAP_LOOKUP
);
if
(
elem
!=
NULL
)
{
// object member, always treated as a value
// TODO should we check for properties?
dest
[
0
]
=
elem
->
value
;
return
;
}
mp_obj_t
member
=
mp_obj_class_lookup
(
self
->
base
.
type
,
attr
);
if
(
member
!=
MP_OBJ_NULL
)
{
class_convert_return_attr
(
self_in
,
member
,
dest
);
if
(
0
)
{
#if MICROPY_ENABLE_PROPERTY
}
else
if
(
MP_OBJ_IS_TYPE
(
member
,
&
mp_type_property
))
{
// object member is a property
// delegate the store to the property
// TODO should this be part of class_convert_return_attr?
const
mp_obj_t
*
proxy
=
mp_obj_property_get
(
member
);
if
(
proxy
[
0
]
==
mp_const_none
)
{
// TODO
}
else
{
dest
[
0
]
=
mp_call_function_n_kw
(
proxy
[
0
],
1
,
0
,
&
self_in
);
// TODO should we convert the returned value using class_convert_return_attr?
}
#endif
}
else
{
// not a property
class_convert_return_attr
(
self_in
,
member
,
dest
);
}
return
;
}
...
...
@@ -257,10 +277,30 @@ STATIC void class_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
STATIC
bool
class_store_attr
(
mp_obj_t
self_in
,
qstr
attr
,
mp_obj_t
value
)
{
mp_obj_class_t
*
self
=
self_in
;
#if MICROPY_ENABLE_PROPERTY
// for property, we need to do a lookup first in the class dict
// this makes all stores slow... how to fix?
mp_obj_t
member
=
mp_obj_class_lookup
(
self
->
base
.
type
,
attr
);
if
(
member
!=
MP_OBJ_NULL
&&
MP_OBJ_IS_TYPE
(
member
,
&
mp_type_property
))
{
// attribute already exists and is a property
// delegate the store to the property
const
mp_obj_t
*
proxy
=
mp_obj_property_get
(
member
);
if
(
proxy
[
1
]
==
mp_const_none
)
{
// TODO better error message
return
false
;
}
else
{
mp_obj_t
dest
[
2
]
=
{
self_in
,
value
};
mp_call_function_n_kw
(
proxy
[
1
],
2
,
0
,
dest
);
return
true
;
}
}
#endif
if
(
value
==
MP_OBJ_NULL
)
{
// delete attribute
mp_map_elem_t
*
el
=
mp_map_lookup
(
&
self
->
members
,
MP_OBJ_NEW_QSTR
(
attr
),
MP_MAP_LOOKUP_REMOVE_IF_FOUND
);
return
el
!=
NULL
;
mp_map_elem_t
*
el
em
=
mp_map_lookup
(
&
self
->
members
,
MP_OBJ_NEW_QSTR
(
attr
),
MP_MAP_LOOKUP_REMOVE_IF_FOUND
);
return
el
em
!=
NULL
;
}
else
{
// store attribute
mp_map_lookup
(
&
self
->
members
,
MP_OBJ_NEW_QSTR
(
attr
),
MP_MAP_LOOKUP_ADD_IF_NOT_FOUND
)
->
value
=
value
;
...
...
py/py.mk
View file @
777b0f32
...
...
@@ -60,6 +60,7 @@ PY_O_BASENAME = \
objmap.o
\
objmodule.o
\
objobject.o
\
objproperty.o
\
objnone.o
\
objnamedtuple.o
\
objrange.o
\
...
...
py/qstrdefs.h
View file @
777b0f32
...
...
@@ -281,3 +281,10 @@ Q(stdout)
Q
(
stderr
)
Q
(
version_info
)
#endif
#if MICROPY_ENABLE_PROPERTY
Q
(
property
)
Q
(
getter
)
Q
(
setter
)
Q
(
deleter
)
#endif
unix/mpconfigport.h
View file @
777b0f32
...
...
@@ -10,6 +10,7 @@
#define MICROPY_ENABLE_REPL_HELPERS (1)
#define MICROPY_ENABLE_LEXER_UNIX (1)
#define MICROPY_ENABLE_SOURCE_LINE (1)
#define MICROPY_ENABLE_PROPERTY (1)
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_DOUBLE)
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
#define MICROPY_PATH_MAX (PATH_MAX)
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment