##// END OF EJS Templates
Replace exec/eval with proper __import__....
Fernando Perez -
Show More
@@ -1,51 +1,77 b''
1 1 """
2 2 Shim to maintain backwards compatibility with old frontend imports.
3 3
4 4 We have moved all contents of the old `frontend` subpackage into top-level
5 5 subpackages (`html`, `qt` and `terminal`). This will let code that was making
6 6 `from IPython.frontend...` calls continue working, though a warning will be
7 7 printed.
8 8 """
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Copyright (c) 2013, IPython Development Team.
12 12 #
13 13 # Distributed under the terms of the Modified BSD License.
14 14 #
15 15 # The full license is in the file COPYING.txt, distributed with this software.
16 16 #-----------------------------------------------------------------------------
17 17
18 18 #-----------------------------------------------------------------------------
19 19 # Imports
20 20 #-----------------------------------------------------------------------------
21 21 from __future__ import print_function
22
23 # Stdlib
22 24 import sys
23 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 37 # Class declarations
27 38 #-----------------------------------------------------------------------------
28 39
29 40 class ShimModule(types.ModuleType):
30 41
31 42 def __getattribute__(self, key):
32 m = ("*** WARNING*** : The top-level `frontend` module has been deprecated.\n"
33 "Please import %s directly from the `IPython` level." % key)
34
35 # FIXME: I don't understand why, but if the print statement below is
36 # redirected to stderr, this shim module stops working. It seems the
37 # Python import machinery has problem with redirected prints happening
38 # during the import process. If we can't figure out a solution, we may
39 # need to leave it to print to default stdout.
40 print(m)
43 # Use the equivalent of import_item(name), see below
44 name = 'IPython.' + key
45
46 # NOTE: the code below is copied *verbatim* from
47 # importstring.import_item. For some very strange reason that makes no
48 # sense to me, if we call it *as a function*, it doesn't work. This
49 # has something to do with the deep bowels of the import machinery and
50 # I couldn't find a way to make the code work as a standard function
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
43 # __import__ call instead of using exec/eval.
44 exec 'from IPython import %s' % key
45 return eval(key)
59 parts = name.rsplit('.', 1)
60 if len(parts) == 2:
61 # called with 'foo.bar....'
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 74 # Unconditionally insert the shim into sys.modules so that further import calls
49 75 # trigger the custom attribute access above
50 76
51 77 sys.modules['IPython.frontend'] = ShimModule('frontend')
General Comments 0
You need to be logged in to leave comments. Login now