From 38991ca3beea0b2dc2eb7bcf6535fd8a3bcb688a 2015-03-24 22:23:47 From: Thomas Kluyver Date: 2015-03-24 22:23:47 Subject: [PATCH] Add shim to preserve IPython.qt imports --- diff --git a/IPython/frontend.py b/IPython/frontend.py index 5a47d77..f47b7b7 100644 --- a/IPython/frontend.py +++ b/IPython/frontend.py @@ -9,17 +9,9 @@ This will let code that was making `from IPython.frontend...` calls continue working, though a warning will be printed. """ -#----------------------------------------------------------------------------- -# Copyright (c) 2013, IPython Development Team. -# -# Distributed under the terms of the Modified BSD License. -# -# The full license is in the file COPYING.txt, distributed with this software. -#----------------------------------------------------------------------------- +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- from __future__ import print_function # Stdlib @@ -30,47 +22,7 @@ from warnings import warn warn("The top-level `frontend` package has been deprecated. " "All its subpackages have been moved to the top `IPython` level.") -#----------------------------------------------------------------------------- -# Class declarations -#----------------------------------------------------------------------------- - -class ShimModule(types.ModuleType): - - def __init__(self, *args, **kwargs): - self._mirror = kwargs.pop("mirror") - super(ShimModule, self).__init__(*args, **kwargs) - - def __getattr__(self, key): - # Use the equivalent of import_item(name), see below - name = "%s.%s" % (self._mirror, key) - - # NOTE: the code below is copied *verbatim* from - # importstring.import_item. For some very strange reason that makes no - # sense to me, if we call it *as a function*, it doesn't work. This - # has something to do with the deep bowels of the import machinery and - # I couldn't find a way to make the code work as a standard function - # call. But at least since it's an unmodified copy of import_item, - # which is used extensively and has a test suite, we can be reasonably - # confident this is OK. If anyone finds how to call the function, all - # the below could be replaced simply with: - # - # from IPython.utils.importstring import import_item - # return import_item('MIRROR.' + key) - - parts = name.rsplit('.', 1) - if len(parts) == 2: - # called with 'foo.bar....' - package, obj = parts - module = __import__(package, fromlist=[obj]) - try: - pak = module.__dict__[obj] - except KeyError: - raise AttributeError(obj) - return pak - else: - # called with un-dotted string - return __import__(parts[0]) - +from IPython.utils.shimmodule import ShimModule # Unconditionally insert the shim into sys.modules so that further import calls # trigger the custom attribute access above diff --git a/IPython/qt.py b/IPython/qt.py new file mode 100644 index 0000000..bccdb4b --- /dev/null +++ b/IPython/qt.py @@ -0,0 +1,22 @@ +""" +Shim to maintain backwards compatibility with old IPython.qt imports. +""" +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + +from __future__ import print_function + +# Stdlib +import sys +import types +from warnings import warn + +warn("The `IPython.qt` package has been deprecated. " + "You should import from jupyter_qtconsole instead.") + +from IPython.utils.shimmodule import ShimModule + +# Unconditionally insert the shim into sys.modules so that further import calls +# trigger the custom attribute access above + +sys.modules['IPython.qt'] = ShimModule('qt', mirror='jupyter_qtconsole') diff --git a/IPython/utils/shimmodule.py b/IPython/utils/shimmodule.py new file mode 100644 index 0000000..a766ebb --- /dev/null +++ b/IPython/utils/shimmodule.py @@ -0,0 +1,49 @@ +"""A shim module for deprecated imports +""" +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + +import types + +class ShimModule(types.ModuleType): + + def __init__(self, *args, **kwargs): + self._mirror = kwargs.pop("mirror") + super(ShimModule, self).__init__(*args, **kwargs) + + def __getattr__(self, key): + # Use the equivalent of import_item(name), see below + name = "%s.%s" % (self._mirror, key) + + # NOTE: the code below is copied *verbatim* from + # importstring.import_item. For some very strange reason that makes no + # sense to me, if we call it *as a function*, it doesn't work. This + # has something to do with the deep bowels of the import machinery and + # I couldn't find a way to make the code work as a standard function + # call. But at least since it's an unmodified copy of import_item, + # which is used extensively and has a test suite, we can be reasonably + # confident this is OK. If anyone finds how to call the function, all + # the below could be replaced simply with: + # + # from IPython.utils.importstring import import_item + # return import_item('MIRROR.' + key) + + parts = name.rsplit('.', 1) + if len(parts) == 2: + # called with 'foo.bar....' + package, obj = parts + module = __import__(package, fromlist=[obj]) + try: + pak = module.__dict__[obj] + except KeyError: + raise + raise AttributeError(obj) + return pak + else: + # called with un-dotted string + return __import__(parts[0]) + +class ShimPackage(ShimModule): + @property + def __path__(self): + return __import__(self._mirror).__path__