Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
Pyston
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
Pyston
Commits
f7ac934e
Commit
f7ac934e
authored
Mar 04, 2015
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement sys.meta_path handling
parent
4e53dd09
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
74 additions
and
6 deletions
+74
-6
src/runtime/builtin_modules/sys.cpp
src/runtime/builtin_modules/sys.cpp
+2
-0
src/runtime/import.cpp
src/runtime/import.cpp
+35
-6
test/tests/sys_meta_path.py
test/tests/sys_meta_path.py
+37
-0
No files found.
src/runtime/builtin_modules/sys.cpp
View file @
f7ac934e
...
...
@@ -274,6 +274,8 @@ void setupSys() {
new
BoxedBuiltinFunctionOrMethod
(
boxRTFunction
((
void
*
)
sysGetFilesystemEncoding
,
STR
,
0
),
"getfilesystemencoding"
));
sys_module
->
giveAttr
(
"meta_path"
,
new
BoxedList
());
// TODO: should configure this in a better way
sys_module
->
giveAttr
(
"prefix"
,
boxStrConstant
(
"/usr"
));
sys_module
->
giveAttr
(
"exec_prefix"
,
boxStrConstant
(
"/usr"
));
...
...
src/runtime/import.cpp
View file @
f7ac934e
...
...
@@ -65,7 +65,9 @@ static bool pathExists(const std::string& path) {
}
struct
SearchResult
{
// Each of these fields are only valid/used for certain filetypes:
std
::
string
path
;
Box
*
loader
;
enum
filetype
{
SEARCH_ERROR
,
...
...
@@ -82,9 +84,34 @@ struct SearchResult {
SearchResult
(
const
std
::
string
&
path
,
filetype
type
)
:
path
(
path
),
type
(
type
)
{}
SearchResult
(
std
::
string
&&
path
,
filetype
type
)
:
path
(
std
::
move
(
path
)),
type
(
type
)
{}
SearchResult
(
Box
*
loader
)
:
loader
(
loader
),
type
(
IMP_HOOK
)
{}
};
SearchResult
findModule
(
const
std
::
string
&
name
,
const
std
::
string
&
full_name
,
BoxedList
*
path_list
)
{
BoxedList
*
meta_path
=
static_cast
<
BoxedList
*>
(
sys_module
->
getattr
(
"meta_path"
));
if
(
!
meta_path
||
meta_path
->
cls
!=
list_cls
)
raiseExcHelper
(
RuntimeError
,
"sys.meta_path must be a list of import hooks"
);
const
static
std
::
string
find_module_str
(
"find_module"
);
for
(
int
i
=
0
;
i
<
meta_path
->
size
;
i
++
)
{
Box
*
finder
=
meta_path
->
elts
->
elts
[
i
];
auto
path_pass
=
path_list
?
path_list
:
None
;
Box
*
loader
=
callattr
(
finder
,
&
find_module_str
,
CallattrFlags
({.
cls_only
=
false
,
.
null_on_nonexistent
=
false
}),
ArgPassSpec
(
2
),
new
BoxedString
(
full_name
),
path_pass
,
NULL
,
NULL
,
NULL
);
if
(
loader
!=
None
)
return
SearchResult
(
loader
);
}
if
(
!
path_list
)
path_list
=
getSysPath
();
if
(
path_list
==
NULL
||
path_list
->
cls
!=
list_cls
)
{
raiseExcHelper
(
RuntimeError
,
"sys.path must be a list of directory names"
);
}
llvm
::
SmallString
<
128
>
joined_path
;
for
(
int
i
=
0
;
i
<
path_list
->
size
;
i
++
)
{
Box
*
_p
=
path_list
->
elts
->
elts
[
i
];
...
...
@@ -121,10 +148,7 @@ static Box* importSub(const std::string& name, const std::string& full_name, Box
BoxedList
*
path_list
;
if
(
parent_module
==
NULL
)
{
path_list
=
getSysPath
();
if
(
path_list
==
NULL
||
path_list
->
cls
!=
list_cls
)
{
raiseExcHelper
(
RuntimeError
,
"sys.path must be a list of directory names"
);
}
path_list
=
NULL
;
}
else
{
path_list
=
static_cast
<
BoxedList
*>
(
parent_module
->
getattr
(
"__path__"
,
NULL
));
if
(
path_list
==
NULL
||
path_list
->
cls
!=
list_cls
)
{
...
...
@@ -135,13 +159,18 @@ static Box* importSub(const std::string& name, const std::string& full_name, Box
SearchResult
sr
=
findModule
(
name
,
full_name
,
path_list
);
if
(
sr
.
type
!=
SearchResult
::
SEARCH_ERROR
)
{
Box
edModule
*
module
;
Box
*
module
;
if
(
sr
.
type
==
SearchResult
::
PY_SOURCE
)
module
=
createAndRunModule
(
full_name
,
sr
.
path
);
else
if
(
sr
.
type
==
SearchResult
::
PKG_DIRECTORY
)
module
=
createAndRunModule
(
full_name
,
sr
.
path
+
"/__init__.py"
,
sr
.
path
);
else
else
if
(
sr
.
type
==
SearchResult
::
IMP_HOOK
)
{
const
static
std
::
string
load_module_str
(
"load_module"
);
module
=
callattr
(
sr
.
loader
,
&
load_module_str
,
CallattrFlags
({.
cls_only
=
false
,
.
null_on_nonexistent
=
false
}),
ArgPassSpec
(
1
),
new
BoxedString
(
full_name
),
NULL
,
NULL
,
NULL
,
NULL
);
}
else
RELEASE_ASSERT
(
0
,
"%d"
,
sr
.
type
);
if
(
parent_module
)
...
...
test/tests/sys_meta_path.py
0 → 100644
View file @
f7ac934e
# PEP-302 import hook test
import
sys
from
types
import
ModuleType
import
imp
class
Loader
(
object
):
def
load_module
(
self
,
fullname
):
print
"load"
,
fullname
if
fullname
.
endswith
(
"test"
):
return
1
else
:
r
=
ModuleType
(
fullname
)
r
.
__package__
=
fullname
r
.
__path__
=
[]
return
r
class
Finder
(
object
):
def
find_module
(
self
,
fullname
,
path
=
None
):
print
"find"
,
fullname
,
path
return
Loader
()
try
:
import
a.b.test
except
ImportError
,
e
:
print
"caught import error"
# The error CPython gives here is "No module named a.b.test". Both we and PyPy think this
# is wrong and that the error should be "No module named a".
# So unfortunately we can't print out the error message.
sys
.
meta_path
.
append
(
Finder
())
import
a
print
a
import
a.b.test
as
test
print
test
import
a.b
as
b
print
b
Write
Preview
Markdown
is supported
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