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
c42e4b6c
Commit
c42e4b6c
authored
Apr 11, 2014
by
Damien George
Browse files
Merge branch 'master' of github.com:micropython/micropython
parents
8b19db00
b9b1c00c
Changes
7
Hide whitespace changes
Inline
Side-by-side
py/builtinimport.c
View file @
c42e4b6c
...
...
@@ -19,6 +19,13 @@
#include "runtime.h"
#include "builtin.h"
#if 0 // print debugging info
#define DEBUG_PRINT (1)
#define DEBUG_printf DEBUG_printf
#else
// don't print debugging info
#define DEBUG_printf(...) (void)0
#endif
#define PATH_SEP_CHAR '/'
mp_obj_t
mp_sys_path
;
...
...
@@ -129,14 +136,14 @@ void do_load(mp_obj_t module_obj, vstr_t *file) {
}
mp_obj_t
mp_builtin___import__
(
uint
n_args
,
mp_obj_t
*
args
)
{
/*
printf("import:\n");
#if DEBUG_PRINT
printf
(
"
__
import
__
:
\n
"
);
for
(
int
i
=
0
;
i
<
n_args
;
i
++
)
{
printf
(
" "
);
mp_obj_print
(
args
[
i
],
PRINT_REPR
);
printf
(
"
\n
"
);
}
*/
#endif
mp_obj_t
fromtuple
=
mp_const_none
;
int
level
=
0
;
...
...
@@ -158,6 +165,7 @@ mp_obj_t mp_builtin___import__(uint n_args, mp_obj_t *args) {
// check if module already exists
mp_obj_t
module_obj
=
mp_module_get
(
mp_obj_str_get_qstr
(
args
[
0
]));
if
(
module_obj
!=
MP_OBJ_NULL
)
{
DEBUG_printf
(
"Module already loaded
\n
"
);
// If it's not a package, return module right away
char
*
p
=
strchr
(
mod_str
,
'.'
);
if
(
p
==
NULL
)
{
...
...
@@ -171,6 +179,7 @@ mp_obj_t mp_builtin___import__(uint n_args, mp_obj_t *args) {
qstr
pkg_name
=
qstr_from_strn
(
mod_str
,
p
-
mod_str
);
return
mp_module_get
(
pkg_name
);
}
DEBUG_printf
(
"Module not yet loaded
\n
"
);
uint
last
=
0
;
VSTR_FIXED
(
path
,
MICROPY_PATH_MAX
)
...
...
@@ -182,6 +191,7 @@ mp_obj_t mp_builtin___import__(uint n_args, mp_obj_t *args) {
if
(
i
==
mod_len
||
mod_str
[
i
]
==
'.'
)
{
// create a qstr for the module name up to this depth
qstr
mod_name
=
qstr_from_strn
(
mod_str
,
i
);
DEBUG_printf
(
"Processing module: %s
\n
"
,
qstr_str
(
mod_name
));
// find the file corresponding to the module name
mp_import_stat_t
stat
;
...
...
@@ -207,6 +217,7 @@ mp_obj_t mp_builtin___import__(uint n_args, mp_obj_t *args) {
module_obj
=
mp_obj_new_module
(
mod_name
);
if
(
stat
==
MP_IMPORT_STAT_DIR
)
{
DEBUG_printf
(
"%s is dir
\n
"
,
vstr_str
(
&
path
));
vstr_add_char
(
&
path
,
PATH_SEP_CHAR
);
vstr_add_str
(
&
path
,
"__init__.py"
);
if
(
mp_import_stat
(
vstr_str
(
&
path
))
!=
MP_IMPORT_STAT_FILE
)
{
...
...
@@ -217,6 +228,9 @@ mp_obj_t mp_builtin___import__(uint n_args, mp_obj_t *args) {
}
do_load
(
module_obj
,
&
path
);
vstr_cut_tail_bytes
(
&
path
,
sizeof
(
"/__init__.py"
)
-
1
);
// cut off /__init__.py
// https://docs.python.org/3.3/reference/import.html
// "Specifically, any module that contains a __path__ attribute is considered a package."
mp_store_attr
(
module_obj
,
MP_QSTR___path__
,
mp_obj_new_str
((
byte
*
)
vstr_str
(
&
path
),
vstr_len
(
&
path
),
false
));
}
else
{
// MP_IMPORT_STAT_FILE
do_load
(
module_obj
,
&
path
);
// TODO: We cannot just break here, at the very least, we must execute
...
...
py/makeqstrdata.py
View file @
c42e4b6c
...
...
@@ -26,10 +26,10 @@ def compute_hash(qstr):
def
do_work
(
infiles
):
# read the qstrs in from the input files
qstrs
=
{}
cpp_header_blocks
=
3
for
infile
in
infiles
:
with
open
(
infile
,
'rt'
)
as
f
:
line_number
=
0
conditional
=
None
for
line
in
f
:
line_number
+=
1
line
=
line
.
strip
()
...
...
@@ -38,17 +38,13 @@ def do_work(infiles):
if
len
(
line
)
==
0
or
line
.
startswith
(
'//'
):
continue
if
line
[
0
]
==
'#'
:
if
conditional
==
"<endif>"
:
assert
line
==
"#endif"
conditional
=
None
else
:
assert
conditional
is
None
conditional
=
line
# We'll have 3 line-number lines for py/qstrdefs.h - initial, leaving it to
# go into other headers, and returning to it.
if
line
.
startswith
(
'# '
)
and
'py/qstrdefs.h'
in
line
:
cpp_header_blocks
-=
1
continue
if
cpp_header_blocks
!=
0
:
continue
if
conditional
==
"<endif>"
:
assert
False
,
"#endif expected before '%s'"
%
line
# verify line is of the correct form
match
=
re
.
match
(
r
'Q\((.+)\)$'
,
line
)
...
...
@@ -65,21 +61,15 @@ def do_work(infiles):
continue
# add the qstr to the list, with order number to retain original order in file
qstrs
[
ident
]
=
(
len
(
qstrs
),
ident
,
qstr
,
conditional
)
if
conditional
is
not
None
:
conditional
=
"<endif>"
qstrs
[
ident
]
=
(
len
(
qstrs
),
ident
,
qstr
)
# process the qstrs, printing out the generated C header file
print
(
'// This file was automatically generated by makeqstrdata.py'
)
print
(
''
)
for
order
,
ident
,
qstr
,
conditional
in
sorted
(
qstrs
.
values
(),
key
=
lambda
x
:
x
[
0
]):
for
order
,
ident
,
qstr
in
sorted
(
qstrs
.
values
(),
key
=
lambda
x
:
x
[
0
]):
qhash
=
compute_hash
(
qstr
)
qlen
=
len
(
qstr
)
if
conditional
:
print
(
conditional
)
print
(
'Q({}, (const byte*)"
\\
x{:02x}
\\
x{:02x}
\\
x{:02x}
\\
x{:02x}" "{}")'
.
format
(
ident
,
qhash
&
0xff
,
(
qhash
>>
8
)
&
0xff
,
qlen
&
0xff
,
(
qlen
>>
8
)
&
0xff
,
qstr
))
if
conditional
:
print
(
'#endif'
)
return
True
...
...
py/py.mk
View file @
c42e4b6c
...
...
@@ -104,9 +104,10 @@ $(PY_BUILD)/py-version.h: FORCE
# Adding an order only dependency on $(PY_BUILD) causes $(PY_BUILD) to get
# created before we run the script to generate the .h
$(PY_BUILD)/qstrdefs.generated.h
:
| $(PY_BUILD)/
$(PY_BUILD)/qstrdefs.generated.h
:
$(PY_QSTR_DEFS) $(QSTR_DEFS) $(PY_SRC)/makeqstrdata.py
$(PY_BUILD)/qstrdefs.generated.h
:
$(PY_QSTR_DEFS) $(QSTR_DEFS) $(PY_SRC)/makeqstrdata.py
mpconfigport.h $(PY_SRC)/mpconfig.h
$(ECHO)
"makeqstrdata
$(PY_QSTR_DEFS)
$(QSTR_DEFS)
"
$(Q)$(PYTHON)
$(PY_SRC)
/makeqstrdata.py
$(PY_QSTR_DEFS)
$(QSTR_DEFS)
>
$@
$(CPP)
$(CFLAGS)
$(PY_QSTR_DEFS)
-o
$(PY_BUILD)
/qstrdefs.preprocessed.h
$(Q)$(PYTHON)
$(PY_SRC)
/makeqstrdata.py
$(PY_BUILD)
/qstrdefs.preprocessed.h
$(QSTR_DEFS)
>
$@
# We don't know which source files actually need the generated.h (since
# it is #included from str.h). The compiler generated dependencies will cause
...
...
py/qstrdefs.h
View file @
c42e4b6c
#include "mpconfig.h"
// All the qstr definitions in this file are available as constants.
// That is, they are in ROM and you can reference them simply as MP_QSTR_xxxx.
// TODO make it so we can use #defines here to select only those words that will be used
Q
(
__build_class__
)
Q
(
__class__
)
...
...
@@ -13,6 +13,7 @@ Q(__module__)
Q
(
__name__
)
Q
(
__next__
)
Q
(
__qualname__
)
Q
(
__path__
)
Q
(
__repl_print__
)
Q
(
__bool__
)
...
...
py/runtime.c
View file @
c42e4b6c
...
...
@@ -1043,13 +1043,45 @@ mp_obj_t mp_import_name(qstr name, mp_obj_t fromlist, mp_obj_t level) {
mp_obj_t
mp_import_from
(
mp_obj_t
module
,
qstr
name
)
{
DEBUG_printf
(
"import from %p %s
\n
"
,
module
,
qstr_str
(
name
));
mp_obj_t
x
=
mp_load_attr
(
module
,
name
);
/* TODO convert AttributeError to ImportError
if (fail) {
(ImportError, "cannot import name %s", qstr_str(name), NULL)
mp_obj_t
dest
[
2
];
mp_load_method_maybe
(
module
,
name
,
dest
);
if
(
dest
[
1
]
!=
MP_OBJ_NULL
)
{
// Hopefully we can't import bound method from an object
import_error:
nlr_raise
(
mp_obj_new_exception_msg_varg
(
&
mp_type_ImportError
,
"Cannot import name '%s'"
,
qstr_str
(
name
)));
}
if
(
dest
[
0
]
!=
MP_OBJ_NULL
)
{
return
dest
[
0
];
}
// See if it's a package, then can try FS import
mp_load_method_maybe
(
module
,
MP_QSTR___path__
,
dest
);
if
(
dest
[
0
]
==
MP_OBJ_NULL
)
{
goto
import_error
;
}
*/
return
x
;
mp_load_method_maybe
(
module
,
MP_QSTR___name__
,
dest
);
uint
pkg_name_len
;
const
char
*
pkg_name
=
mp_obj_str_get_data
(
dest
[
0
],
&
pkg_name_len
);
char
dot_name
[
pkg_name_len
+
1
+
qstr_len
(
name
)];
memcpy
(
dot_name
,
pkg_name
,
pkg_name_len
);
dot_name
[
pkg_name_len
]
=
'.'
;
memcpy
(
dot_name
+
pkg_name_len
+
1
,
qstr_str
(
name
),
qstr_len
(
name
));
qstr
dot_name_q
=
qstr_from_strn
(
dot_name
,
sizeof
(
dot_name
));
mp_obj_t
args
[
5
];
args
[
0
]
=
MP_OBJ_NEW_QSTR
(
dot_name_q
);
args
[
1
]
=
mp_const_none
;
// TODO should be globals
args
[
2
]
=
mp_const_none
;
// TODO should be locals
args
[
3
]
=
mp_const_true
;
// Pass sentinel "non empty" value to force returning of leaf module
args
[
4
]
=
0
;
// TODO lookup __import__ and call that instead of going straight to builtin implementation
return
mp_builtin___import__
(
5
,
args
);
}
void
mp_import_all
(
mp_obj_t
module
)
{
...
...
py/showbc.c
View file @
c42e4b6c
...
...
@@ -101,11 +101,20 @@ void mp_byte_code_print(const byte *ip, int len) {
printf
(
"LOAD_CONST_ID %s"
,
qstr_str
(
qstr
));
break
;
case
MP_BC_LOAD_CONST_BYTES
:
DECODE_QSTR
;
printf
(
"LOAD_CONST_BYTES %s"
,
qstr_str
(
qstr
));
break
;
case
MP_BC_LOAD_CONST_STRING
:
DECODE_QSTR
;
printf
(
"LOAD_CONST_STRING %s"
,
qstr_str
(
qstr
));
break
;
case
MP_BC_LOAD_NULL
:
printf
(
"LOAD_NULL"
);
break
;
case
MP_BC_LOAD_FAST_0
:
printf
(
"LOAD_FAST_0"
);
break
;
...
...
tests/basics/import-pkg3.py
0 → 100644
View file @
c42e4b6c
from
pkg
import
mod
print
(
mod
.
foo
())
import
pkg.mod
print
(
mod
is
pkg
.
mod
)
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