##// END OF EJS Templates
Replace exec/eval with proper __import__....
Fernando Perez -
Show More
@@ -1,51 +1,77 b''
1 """
1 """
2 Shim to maintain backwards compatibility with old frontend imports.
2 Shim to maintain backwards compatibility with old frontend imports.
3
3
4 We have moved all contents of the old `frontend` subpackage into top-level
4 We have moved all contents of the old `frontend` subpackage into top-level
5 subpackages (`html`, `qt` and `terminal`). This will let code that was making
5 subpackages (`html`, `qt` and `terminal`). This will let code that was making
6 `from IPython.frontend...` calls continue working, though a warning will be
6 `from IPython.frontend...` calls continue working, though a warning will be
7 printed.
7 printed.
8 """
8 """
9
9
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11 # Copyright (c) 2013, IPython Development Team.
11 # Copyright (c) 2013, IPython Development Team.
12 #
12 #
13 # Distributed under the terms of the Modified BSD License.
13 # Distributed under the terms of the Modified BSD License.
14 #
14 #
15 # The full license is in the file COPYING.txt, distributed with this software.
15 # The full license is in the file COPYING.txt, distributed with this software.
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # Imports
19 # Imports
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21 from __future__ import print_function
21 from __future__ import print_function
22
23 # Stdlib
22 import sys
24 import sys
23 import types
25 import types
24
26
27 m = """\
28 *** WARNING*** : The top-level `frontend` package has been deprecated.
29 All its subpackages have been moved to the top `IPython` level."""
30
31 print(m, file=sys.stderr)
32
33 # FIXME: turn this into a Warning once we've fixed all our own imports.
34 #raise DeprecationWarning(m)
35
25 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
26 # Class declarations
37 # Class declarations
27 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
28
39
29 class ShimModule(types.ModuleType):
40 class ShimModule(types.ModuleType):
30
41
31 def __getattribute__(self, key):
42 def __getattribute__(self, key):
32 m = ("*** WARNING*** : The top-level `frontend` module has been deprecated.\n"
43 # Use the equivalent of import_item(name), see below
33 "Please import %s directly from the `IPython` level." % key)
44 name = 'IPython.' + key
34
45
35 # FIXME: I don't understand why, but if the print statement below is
46 # NOTE: the code below is copied *verbatim* from
36 # redirected to stderr, this shim module stops working. It seems the
47 # importstring.import_item. For some very strange reason that makes no
37 # Python import machinery has problem with redirected prints happening
48 # sense to me, if we call it *as a function*, it doesn't work. This
38 # during the import process. If we can't figure out a solution, we may
49 # has something to do with the deep bowels of the import machinery and
39 # need to leave it to print to default stdout.
50 # I couldn't find a way to make the code work as a standard function
40 print(m)
51 # call. But at least since it's an unmodified copy of import_item,
52 # which is used extensively and has a test suite, we can be reasonably
53 # confident this is OK. If anyone finds how to call the function, all
54 # the below could be replaced simply with:
55 #
56 # from IPython.utils.importstring import import_item
57 # return import_item('IPython.' + key)
41
58
42 # FIXME: this seems to work fine, but we should replace it with an
59 parts = name.rsplit('.', 1)
43 # __import__ call instead of using exec/eval.
60 if len(parts) == 2:
44 exec 'from IPython import %s' % key
61 # called with 'foo.bar....'
45 return eval(key)
62 package, obj = parts
63 module = __import__(package, fromlist=[obj])
64 try:
65 pak = module.__dict__[obj]
66 except KeyError:
67 raise ImportError('No module named %s' % obj)
68 return pak
69 else:
70 # called with un-dotted string
71 return __import__(parts[0])
46
72
47
73
48 # Unconditionally insert the shim into sys.modules so that further import calls
74 # Unconditionally insert the shim into sys.modules so that further import calls
49 # trigger the custom attribute access above
75 # trigger the custom attribute access above
50
76
51 sys.modules['IPython.frontend'] = ShimModule('frontend')
77 sys.modules['IPython.frontend'] = ShimModule('frontend')
General Comments 0
You need to be logged in to leave comments. Login now