Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
uPython-mirror
Commits
47b9809d
Commit
47b9809d
authored
May 03, 2015
by
Damien George
Browse files
py: Check that arg to object.__new__ is a user-defined type.
Addresses issue #1203.
parent
0116218f
Changes
4
Hide whitespace changes
Inline
Side-by-side
py/objobject.c
View file @
47b9809d
...
...
@@ -26,10 +26,9 @@
#include
<stdlib.h>
#include
"py/objtype.h"
#include
"py/runtime.h"
mp_obj_t
instance_make_new
(
mp_obj_t
self_in
,
mp_uint_t
n_args
,
mp_uint_t
n_kw
,
const
mp_obj_t
*
args
);
typedef
struct
_mp_obj_object_t
{
mp_obj_base_t
base
;
}
mp_obj_object_t
;
...
...
@@ -50,8 +49,12 @@ STATIC mp_obj_t object___init__(mp_obj_t self) {
STATIC
MP_DEFINE_CONST_FUN_OBJ_1
(
object___init___obj
,
object___init__
);
STATIC
mp_obj_t
object___new__
(
mp_obj_t
cls
)
{
if
(
!
MP_OBJ_IS_TYPE
(
cls
,
&
mp_type_type
)
||
!
mp_obj_is_instance_type
((
mp_obj_type_t
*
)
cls
))
{
nlr_raise
(
mp_obj_new_exception_msg
(
&
mp_type_TypeError
,
"__new__ arg must be a user-type"
));
}
mp_obj_t
o
=
MP_OBJ_SENTINEL
;
mp_obj_t
res
=
instance_make_new
(
cls
,
1
,
0
,
&
o
);
mp_obj_t
res
=
mp_obj_
instance_make_new
(
cls
,
1
,
0
,
&
o
);
return
res
;
}
STATIC
MP_DEFINE_CONST_FUN_OBJ_1
(
object___new___fun_obj
,
object___new__
);
...
...
py/objtype.c
View file @
47b9809d
...
...
@@ -48,10 +48,6 @@ STATIC mp_obj_t static_class_method_make_new(mp_obj_t self_in, mp_uint_t n_args,
/******************************************************************************/
// instance object
#define is_instance_type(type) ((type)->make_new == instance_make_new)
#define is_native_type(type) ((type)->make_new != instance_make_new)
mp_obj_t
instance_make_new
(
mp_obj_t
self_in
,
mp_uint_t
n_args
,
mp_uint_t
n_kw
,
const
mp_obj_t
*
args
);
STATIC
mp_obj_t
mp_obj_new_instance
(
mp_obj_t
class
,
uint
subobjs
)
{
mp_obj_instance_t
*
o
=
m_new_obj_var
(
mp_obj_instance_t
,
mp_obj_t
,
subobjs
);
o
->
base
.
type
=
class
;
...
...
@@ -73,7 +69,7 @@ STATIC int instance_count_native_bases(const mp_obj_type_t *type, const mp_obj_t
// Not a "real" type
continue
;
}
if
(
is_native_type
(
bt
))
{
if
(
mp_obj_
is_native_type
(
bt
))
{
*
last_native_base
=
bt
;
count
++
;
}
else
{
...
...
@@ -114,7 +110,7 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_
// This avoids extra method_name => slot lookup. On the other hand,
// this should not be applied to class types, as will result in extra
// lookup either.
if
(
lookup
->
meth_offset
!=
0
&&
is_native_type
(
type
))
{
if
(
lookup
->
meth_offset
!=
0
&&
mp_obj_
is_native_type
(
type
))
{
if
(
*
(
void
**
)((
char
*
)
type
+
lookup
->
meth_offset
)
!=
NULL
)
{
DEBUG_printf
(
"mp_obj_class_lookup: matched special meth slot for %s
\n
"
,
qstr_str
(
lookup
->
attr
));
lookup
->
dest
[
0
]
=
MP_OBJ_SENTINEL
;
...
...
@@ -135,7 +131,7 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_
mp_convert_member_lookup
(
NULL
,
org_type
,
elem
->
value
,
lookup
->
dest
);
}
else
{
mp_obj_instance_t
*
obj
=
lookup
->
obj
;
if
(
obj
!=
MP_OBJ_NULL
&&
is_native_type
(
type
)
&&
type
!=
&
mp_type_object
/* object is not a real type */
)
{
if
(
obj
!=
MP_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
->
subobj
[
0
];
}
...
...
@@ -153,7 +149,7 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_
// Previous code block takes care about attributes defined in .locals_dict,
// but some attributes of native types may be handled using .load_attr method,
// so make sure we try to lookup those too.
if
(
lookup
->
obj
!=
MP_OBJ_NULL
&&
!
lookup
->
is_type
&&
is_native_type
(
type
)
&&
type
!=
&
mp_type_object
/* object is not a real type */
)
{
if
(
lookup
->
obj
!=
MP_OBJ_NULL
&&
!
lookup
->
is_type
&&
mp_obj_
is_native_type
(
type
)
&&
type
!=
&
mp_type_object
/* object is not a real type */
)
{
mp_load_method_maybe
(
lookup
->
obj
->
subobj
[
0
],
lookup
->
attr
,
lookup
->
dest
);
if
(
lookup
->
dest
[
0
]
!=
MP_OBJ_NULL
)
{
return
;
...
...
@@ -238,9 +234,10 @@ STATIC void instance_print(const mp_print_t *print, mp_obj_t self_in, mp_print_k
mp_printf
(
print
,
"<%s object at %p>"
,
mp_obj_get_type_str
(
self_in
),
self_in
);
}
mp_obj_t
instance_make_new
(
mp_obj_t
self_in
,
mp_uint_t
n_args
,
mp_uint_t
n_kw
,
const
mp_obj_t
*
args
)
{
mp_obj_t
mp_obj_
instance_make_new
(
mp_obj_t
self_in
,
mp_uint_t
n_args
,
mp_uint_t
n_kw
,
const
mp_obj_t
*
args
)
{
assert
(
MP_OBJ_IS_TYPE
(
self_in
,
&
mp_type_type
));
mp_obj_type_t
*
self
=
self_in
;
assert
(
mp_obj_is_instance_type
(
self
));
const
mp_obj_type_t
*
native_base
;
uint
num_native_bases
=
instance_count_native_bases
(
self
,
&
native_base
);
...
...
@@ -442,7 +439,7 @@ STATIC mp_obj_t instance_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_i
STATIC
void
mp_obj_instance_load_attr
(
mp_obj_t
self_in
,
qstr
attr
,
mp_obj_t
*
dest
)
{
// logic: look in instance members then class locals
assert
(
is_instance_type
(
mp_obj_get_type
(
self_in
)));
assert
(
mp_obj_
is_instance_type
(
mp_obj_get_type
(
self_in
)));
mp_obj_instance_t
*
self
=
self_in
;
mp_map_elem_t
*
elem
=
mp_map_lookup
(
&
self
->
members
,
MP_OBJ_NEW_QSTR
(
attr
),
MP_MAP_LOOKUP
);
...
...
@@ -870,7 +867,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
o
->
base
.
type
=
&
mp_type_type
;
o
->
name
=
name
;
o
->
print
=
instance_print
;
o
->
make_new
=
instance_make_new
;
o
->
make_new
=
mp_obj_
instance_make_new
;
o
->
call
=
mp_obj_instance_call
;
o
->
unary_op
=
instance_unary_op
;
o
->
binary_op
=
instance_binary_op
;
...
...
py/objtype.h
View file @
47b9809d
...
...
@@ -44,4 +44,9 @@ void mp_obj_instance_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest);
bool
mp_obj_instance_is_callable
(
mp_obj_t
self_in
);
mp_obj_t
mp_obj_instance_call
(
mp_obj_t
self_in
,
mp_uint_t
n_args
,
mp_uint_t
n_kw
,
const
mp_obj_t
*
args
);
#define mp_obj_is_instance_type(type) ((type)->make_new == mp_obj_instance_make_new)
#define mp_obj_is_native_type(type) ((type)->make_new != mp_obj_instance_make_new)
// this needs to be exposed for the above macros to work correctly
mp_obj_t
mp_obj_instance_make_new
(
mp_obj_t
self_in
,
mp_uint_t
n_args
,
mp_uint_t
n_kw
,
const
mp_obj_t
*
args
);
#endif // __MICROPY_INCLUDED_PY_OBJTYPE_H__
tests/basics/object_new.py
View file @
47b9809d
...
...
@@ -18,3 +18,13 @@ o.__init__()
#print(dir(o))
print
(
hasattr
(
o
,
"attr"
))
print
(
o
.
attr
)
# should only be able to call __new__ on user types
try
:
object
.
__new__
(
1
)
except
TypeError
:
print
(
"TypeError"
)
try
:
object
.
__new__
(
int
)
except
TypeError
:
print
(
"TypeError"
)
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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