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
d08fd686
Commit
d08fd686
authored
Feb 27, 2014
by
Paul Sokolovsky
Browse files
Add basic collections.namedtuple implementation.
parent
61f9b1c6
Changes
6
Hide whitespace changes
Inline
Side-by-side
py/builtin.h
View file @
d08fd686
...
...
@@ -32,4 +32,6 @@ MP_DECLARE_CONST_FUN_OBJ(mp_builtin_sorted_obj);
MP_DECLARE_CONST_FUN_OBJ
(
mp_builtin_sum_obj
);
MP_DECLARE_CONST_FUN_OBJ
(
mp_builtin_str_obj
);
MP_DECLARE_CONST_FUN_OBJ
(
mp_namedtuple_obj
);
void
mp_module_micropython_init
(
void
);
py/objnamedtuple.c
0 → 100644
View file @
d08fd686
#include
<string.h>
#include
"misc.h"
#include
"mpconfig.h"
#include
"nlr.h"
#include
"qstr.h"
#include
"obj.h"
#include
"objtuple.h"
typedef
struct
_mp_obj_namedtuple_type_t
{
mp_obj_type_t
base
;
const
char
*
fields
;
}
mp_obj_namedtuple_type_t
;
typedef
struct
_mp_obj_namedtuple_t
{
mp_obj_tuple_t
tuple
;
}
mp_obj_namedtuple_t
;
static
inline
bool
is_end_tok
(
char
c
)
{
return
c
==
' '
||
c
==
','
;
}
static
inline
const
char
*
skip_to_next
(
const
char
*
p
)
{
while
(
!
is_end_tok
(
*
p
))
{
if
(
*
p
==
0
)
{
return
NULL
;
}
p
++
;
}
while
(
is_end_tok
(
*
p
))
{
if
(
*
p
==
0
)
{
return
NULL
;
}
p
++
;
}
return
p
;
}
STATIC
uint
namedtuple_count_fields
(
const
char
*
namedef
)
{
uint
cnt
=
0
;
while
(
*
namedef
!=
0
)
{
cnt
++
;
while
(
!
is_end_tok
(
*
namedef
)
&&
*
namedef
!=
0
)
{
namedef
++
;
}
while
(
is_end_tok
(
*
namedef
)
&&
*
namedef
!=
0
)
{
namedef
++
;
}
}
return
cnt
;
}
STATIC
int
namedtuple_find_field
(
const
char
*
name
,
const
char
*
namedef
)
{
int
id
=
0
;
int
len
=
strlen
(
name
);
while
(
namedef
)
{
if
(
memcmp
(
name
,
namedef
,
len
)
==
0
)
{
namedef
+=
len
;
if
(
*
namedef
==
0
||
is_end_tok
(
*
namedef
))
{
return
id
;
}
}
namedef
=
skip_to_next
(
namedef
);
id
++
;
}
return
-
1
;
}
STATIC
void
namedtuple_print
(
void
(
*
print
)(
void
*
env
,
const
char
*
fmt
,
...),
void
*
env
,
mp_obj_t
o_in
,
mp_print_kind_t
kind
)
{
mp_obj_namedtuple_t
*
o
=
o_in
;
print
(
env
,
"%s("
,
qstr_str
(
o
->
tuple
.
base
.
type
->
name
));
const
char
*
fields
=
((
mp_obj_namedtuple_type_t
*
)
o
->
tuple
.
base
.
type
)
->
fields
;
for
(
int
i
=
0
;
i
<
o
->
tuple
.
len
;
i
++
)
{
if
(
i
>
0
)
{
print
(
env
,
", "
);
}
const
char
*
next
=
fields
;
while
(
!
is_end_tok
(
*
next
)
&&
*
next
!=
0
)
{
next
++
;
}
print
(
env
,
"%.*s="
,
next
-
fields
,
fields
);
mp_obj_print_helper
(
print
,
env
,
o
->
tuple
.
items
[
i
],
PRINT_REPR
);
while
(
is_end_tok
(
*
next
)
&&
*
next
!=
0
)
{
next
++
;
}
fields
=
next
;
}
print
(
env
,
")"
);
}
STATIC
void
namedtuple_load_attr
(
mp_obj_t
self_in
,
qstr
attr
,
mp_obj_t
*
dest
)
{
mp_obj_namedtuple_t
*
self
=
self_in
;
const
char
*
fields
=
((
mp_obj_namedtuple_type_t
*
)
self
->
tuple
.
base
.
type
)
->
fields
;
int
id
=
namedtuple_find_field
(
qstr_str
(
attr
),
fields
);
if
(
id
<
0
)
{
return
;
}
dest
[
0
]
=
self
->
tuple
.
items
[
id
];
}
STATIC
bool
namedtuple_store_attr
(
mp_obj_t
self_in
,
qstr
attr
,
mp_obj_t
value
)
{
nlr_jump
(
mp_obj_new_exception_msg
(
&
mp_type_AttributeError
,
"can't set attribute"
));
}
STATIC
mp_obj_t
namedtuple_make_new
(
mp_obj_t
type_in
,
uint
n_args
,
uint
n_kw
,
const
mp_obj_t
*
args
)
{
mp_obj_namedtuple_type_t
*
type
=
type_in
;
uint
num_fields
=
namedtuple_count_fields
(
type
->
fields
);
if
(
n_args
!=
num_fields
)
{
// Counts include implicit "self"
nlr_jump
(
mp_obj_new_exception_msg_varg
(
&
mp_type_TypeError
,
"__new__() takes %d positional arguments but %d were given"
,
num_fields
+
1
,
n_args
+
1
));
}
mp_obj_tuple_t
*
tuple
=
mp_obj_new_tuple
(
n_args
,
args
);
tuple
->
base
.
type
=
type_in
;
return
tuple
;
}
STATIC
const
mp_obj_tuple_t
namedtuple_base_tuple
=
{{
&
tuple_type
},
1
,
{(
mp_obj_t
)
&
tuple_type
}};
mp_obj_t
mp_obj_new_namedtuple_type
(
qstr
name
,
const
char
*
fields
)
{
mp_obj_namedtuple_type_t
*
o
=
m_new0
(
mp_obj_namedtuple_type_t
,
1
);
o
->
base
.
base
.
type
=
&
mp_type_type
;
o
->
base
.
name
=
name
;
o
->
base
.
print
=
namedtuple_print
;
o
->
base
.
make_new
=
namedtuple_make_new
;
// o->base.unary_op = ;
// o->base.binary_op = ;
o
->
base
.
load_attr
=
namedtuple_load_attr
;
o
->
base
.
store_attr
=
namedtuple_store_attr
;
o
->
base
.
bases_tuple
=
(
mp_obj_t
)
&
namedtuple_base_tuple
;
o
->
fields
=
fields
;
return
o
;
}
STATIC
mp_obj_t
new_namedtuple_type
(
mp_obj_t
name_in
,
mp_obj_t
fields_in
)
{
qstr
name
=
MP_OBJ_QSTR_VALUE
(
name_in
);
const
char
*
fields
=
mp_obj_str_get_str
(
fields_in
);
return
mp_obj_new_namedtuple_type
(
name
,
fields
);
}
MP_DEFINE_CONST_FUN_OBJ_2
(
mp_namedtuple_obj
,
new_namedtuple_type
);
py/py.mk
View file @
d08fd686
...
...
@@ -58,6 +58,7 @@ PY_O_BASENAME = \
objmap.o
\
objmodule.o
\
objnone.o
\
objnamedtuple.o
\
objrange.o
\
objset.o
\
objslice.o
\
...
...
py/qstrdefs.h
View file @
d08fd686
...
...
@@ -57,6 +57,7 @@ Q(bytes)
Q
(
callable
)
Q
(
chr
)
Q
(
classmethod
)
Q
(
collections
)
Q
(
complex
)
Q
(
dict
)
Q
(
dir
)
...
...
@@ -77,6 +78,7 @@ Q(list)
Q
(
map
)
Q
(
max
)
Q
(
min
)
Q
(
namedtuple
)
Q
(
next
)
Q
(
ord
)
Q
(
path
)
...
...
py/runtime.c
View file @
d08fd686
...
...
@@ -189,6 +189,9 @@ void rt_init(void) {
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
);
mp_obj_t
m_collections
=
mp_obj_new_module
(
MP_QSTR_collections
);
rt_store_attr
(
m_collections
,
MP_QSTR_namedtuple
,
(
mp_obj_t
)
&
mp_namedtuple_obj
);
#if MICROPY_CPYTHON_COMPAT
// Precreate sys module, so "import sys" didn't throw exceptions.
mp_obj_t
m_sys
=
mp_obj_new_module
(
MP_QSTR_sys
);
...
...
tests/basics/namedtuple1.py
0 → 100644
View file @
d08fd686
from
collections
import
namedtuple
T
=
namedtuple
(
"Tup"
,
"foo bar"
)
# CPython prints fully qualified name, what we don't bother to do so far
#print(T)
t
=
T
(
1
,
2
)
print
(
t
)
print
(
t
.
foo
,
t
.
bar
)
print
(
isinstance
(
t
,
tuple
))
try
:
t
[
0
]
=
200
except
TypeError
:
print
(
"TypeError"
)
try
:
t
.
bar
=
200
except
AttributeError
:
print
(
"AttribiteError"
)
try
:
t
=
T
(
1
)
except
TypeError
:
print
(
"TypeError"
)
try
:
t
=
T
(
1
,
2
,
3
)
except
TypeError
:
print
(
"TypeError"
)
# Try comma field separator
T2
=
namedtuple
(
"TupComma"
,
"foo,bar"
)
t
=
T2
(
1
,
2
)
print
(
t
)
print
(
t
.
foo
,
t
.
bar
)
# Try list of fields
# Not implemented so far
#T3 = namedtuple("TupComma", ["foo", "bar"])
#t = T3(1, 2)
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