class
ExtensionImporter
(
object
)
:
"""This importer redirects imports from this submodule to other locations.
This makes it possible to transition from the old flaskext.name to the
newer flask_name without people having a hard time.
"""
def
__init__
(
self
,
module_choices
,
wrapper_module
)
:
self
.
module_choices
=
module_choices
self
.
wrapper_module
=
wrapper_module
self
.
prefix
=
wrapper_module
+
'.'
self
.
prefix_cutoff
=
wrapper_module
.
count
(
'.'
)
+
1
def
__eq__
(
self
,
other
)
:
return
self
.
__class__
.
__module__
==
other
.
__class__
.
__module__
and
\
self
.
__class__
.
__name__
==
other
.
__class__
.
__name__
and
\
self
.
wrapper_module
==
other
.
wrapper_module
and
\
self
.
module_choices
==
other
.
module_choices
def
__ne__
(
self
,
other
)
:
return
not
self
.
__eq__
(
other
)
def
install
(
self
)
:
sys
.
meta_path
[
:
]
=
[
x
for
x
in
sys
.
meta_path
if
self
!=
x
]
+
[
self
]
def
find_module
(
self
,
fullname
,
path
=
None
)
:
if
fullname
.
startswith
(
self
.
prefix
)
:
return
self
def
load_module
(
self
,
fullname
)
:
if
fullname
in
sys
.
modules
:
return
sys
.
modules
[
fullname
]
modname
=
fullname
.
split
(
'.'
,
self
.
prefix_cutoff
)
[
self
.
prefix_cutoff
]
for
path
in
self
.
module_choices
:
realname
=
path
%
modname
try
:
__import__
(
realname
)
except
ImportError
:
exc_type
,
exc_value
,
tb
=
sys
.
exc_info
(
)
# since we only establish the entry in sys.modules at the
# very this seems to be redundant, but if recursive imports
# happen we will call into the move import a second time.
# On the second invocation we still don't have an entry for
# fullname in sys.modules, but we will end up with the same
# fake module name and that import will succeed since this
# one already has a temporary entry in the modules dict.
# Since this one "succeeded" temporarily that second
# invocation now will have created a fullname entry in
# sys.modules which we have to kill.
sys
.
modules
.
pop
(
fullname
,
None
)
# If it's an important traceback we reraise it, otherwise
# we swallow it and try the next choice. The skipped frame
# is the one from __import__ above which we don't care about
if
self
.
is_important_traceback
(
realname
,
tb
)
:
reraise
(
exc_type
,
exc_value
,
tb
.
tb_next
)
continue
module
=
sys
.
modules
[
fullname
]
=
sys
.
modules
[
realname
]
if
'.'
not
in
modname
:
setattr
(
sys
.
modules
[
self
.
wrapper_module
]
,
modname
,
module
)
return
module
raise
ImportError
(
'No module named %s'
%
fullname
)