Uploaded Test files
This commit is contained in:
		
							parent
							
								
									f584ad9d97
								
							
						
					
					
						commit
						2e81cb7d99
					
				
					 16627 changed files with 2065359 additions and 102444 deletions
				
			
		
							
								
								
									
										5
									
								
								venv/Lib/site-packages/IPython/external/__init__.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								venv/Lib/site-packages/IPython/external/__init__.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
"""
 | 
			
		||||
This package contains all third-party modules bundled with IPython.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
__all__ = []
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								venv/Lib/site-packages/IPython/external/__pycache__/__init__.cpython-36.pyc
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								venv/Lib/site-packages/IPython/external/__pycache__/__init__.cpython-36.pyc
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								venv/Lib/site-packages/IPython/external/__pycache__/mathjax.cpython-36.pyc
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								venv/Lib/site-packages/IPython/external/__pycache__/mathjax.cpython-36.pyc
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								venv/Lib/site-packages/IPython/external/__pycache__/qt_for_kernel.cpython-36.pyc
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								venv/Lib/site-packages/IPython/external/__pycache__/qt_for_kernel.cpython-36.pyc
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								venv/Lib/site-packages/IPython/external/__pycache__/qt_loaders.cpython-36.pyc
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								venv/Lib/site-packages/IPython/external/__pycache__/qt_loaders.cpython-36.pyc
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										8
									
								
								venv/Lib/site-packages/IPython/external/decorators/__init__.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								venv/Lib/site-packages/IPython/external/decorators/__init__.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
try:
 | 
			
		||||
    from numpy.testing import KnownFailure, knownfailureif
 | 
			
		||||
except ImportError:
 | 
			
		||||
    from ._decorators import knownfailureif
 | 
			
		||||
    try:
 | 
			
		||||
        from ._numpy_testing_noseclasses import KnownFailure
 | 
			
		||||
    except ImportError:
 | 
			
		||||
        pass
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								venv/Lib/site-packages/IPython/external/decorators/__pycache__/__init__.cpython-36.pyc
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								venv/Lib/site-packages/IPython/external/decorators/__pycache__/__init__.cpython-36.pyc
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								venv/Lib/site-packages/IPython/external/decorators/__pycache__/_decorators.cpython-36.pyc
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								venv/Lib/site-packages/IPython/external/decorators/__pycache__/_decorators.cpython-36.pyc
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										143
									
								
								venv/Lib/site-packages/IPython/external/decorators/_decorators.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								venv/Lib/site-packages/IPython/external/decorators/_decorators.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,143 @@
 | 
			
		|||
"""
 | 
			
		||||
Decorators for labeling and modifying behavior of test objects.
 | 
			
		||||
 | 
			
		||||
Decorators that merely return a modified version of the original
 | 
			
		||||
function object are straightforward. Decorators that return a new
 | 
			
		||||
function object need to use
 | 
			
		||||
::
 | 
			
		||||
 | 
			
		||||
  nose.tools.make_decorator(original_function)(decorator)
 | 
			
		||||
 | 
			
		||||
in returning the decorator, in order to preserve meta-data such as
 | 
			
		||||
function name, setup and teardown functions and so on - see
 | 
			
		||||
``nose.tools`` for more information.
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
# IPython changes: make this work if numpy not available
 | 
			
		||||
# Original code:
 | 
			
		||||
try:
 | 
			
		||||
    from ._numpy_testing_noseclasses import KnownFailureTest
 | 
			
		||||
except:
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
# End IPython changes
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def skipif(skip_condition, msg=None):
 | 
			
		||||
    """
 | 
			
		||||
    Make function raise SkipTest exception if a given condition is true.
 | 
			
		||||
 | 
			
		||||
    If the condition is a callable, it is used at runtime to dynamically
 | 
			
		||||
    make the decision. This is useful for tests that may require costly
 | 
			
		||||
    imports, to delay the cost until the test suite is actually executed.
 | 
			
		||||
 | 
			
		||||
    Parameters
 | 
			
		||||
    ----------
 | 
			
		||||
    skip_condition : bool or callable
 | 
			
		||||
        Flag to determine whether to skip the decorated test.
 | 
			
		||||
    msg : str, optional
 | 
			
		||||
        Message to give on raising a SkipTest exception. Default is None.
 | 
			
		||||
 | 
			
		||||
    Returns
 | 
			
		||||
    -------
 | 
			
		||||
    decorator : function
 | 
			
		||||
        Decorator which, when applied to a function, causes SkipTest
 | 
			
		||||
        to be raised when `skip_condition` is True, and the function
 | 
			
		||||
        to be called normally otherwise.
 | 
			
		||||
 | 
			
		||||
    Notes
 | 
			
		||||
    -----
 | 
			
		||||
    The decorator itself is decorated with the ``nose.tools.make_decorator``
 | 
			
		||||
    function in order to transmit function name, and various other metadata.
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def skip_decorator(f):
 | 
			
		||||
        # Local import to avoid a hard nose dependency and only incur the
 | 
			
		||||
        # import time overhead at actual test-time.
 | 
			
		||||
        import nose
 | 
			
		||||
 | 
			
		||||
        # Allow for both boolean or callable skip conditions.
 | 
			
		||||
        if callable(skip_condition):
 | 
			
		||||
            skip_val = lambda : skip_condition()
 | 
			
		||||
        else:
 | 
			
		||||
            skip_val = lambda : skip_condition
 | 
			
		||||
 | 
			
		||||
        def get_msg(func,msg=None):
 | 
			
		||||
            """Skip message with information about function being skipped."""
 | 
			
		||||
            if msg is None:
 | 
			
		||||
                out = 'Test skipped due to test condition'
 | 
			
		||||
            else:
 | 
			
		||||
                out = '\n'+msg
 | 
			
		||||
 | 
			
		||||
            return "Skipping test: %s%s" % (func.__name__,out)
 | 
			
		||||
 | 
			
		||||
        # We need to define *two* skippers because Python doesn't allow both
 | 
			
		||||
        # return with value and yield inside the same function.
 | 
			
		||||
        def skipper_func(*args, **kwargs):
 | 
			
		||||
            """Skipper for normal test functions."""
 | 
			
		||||
            if skip_val():
 | 
			
		||||
                raise nose.SkipTest(get_msg(f,msg))
 | 
			
		||||
            else:
 | 
			
		||||
                return f(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
        def skipper_gen(*args, **kwargs):
 | 
			
		||||
            """Skipper for test generators."""
 | 
			
		||||
            if skip_val():
 | 
			
		||||
                raise nose.SkipTest(get_msg(f,msg))
 | 
			
		||||
            else:
 | 
			
		||||
                for x in f(*args, **kwargs):
 | 
			
		||||
                    yield x
 | 
			
		||||
 | 
			
		||||
        # Choose the right skipper to use when building the actual decorator.
 | 
			
		||||
        if nose.util.isgenerator(f):
 | 
			
		||||
            skipper = skipper_gen
 | 
			
		||||
        else:
 | 
			
		||||
            skipper = skipper_func
 | 
			
		||||
 | 
			
		||||
        return nose.tools.make_decorator(f)(skipper)
 | 
			
		||||
 | 
			
		||||
    return skip_decorator
 | 
			
		||||
 | 
			
		||||
def knownfailureif(fail_condition, msg=None):
 | 
			
		||||
    """
 | 
			
		||||
    Make function raise KnownFailureTest exception if given condition is true.
 | 
			
		||||
 | 
			
		||||
    Parameters
 | 
			
		||||
    ----------
 | 
			
		||||
    fail_condition : bool
 | 
			
		||||
        Flag to determine whether to mark the decorated test as a known
 | 
			
		||||
        failure (if True) or not (if False).
 | 
			
		||||
    msg : str, optional
 | 
			
		||||
        Message to give on raising a KnownFailureTest exception.
 | 
			
		||||
        Default is None.
 | 
			
		||||
 | 
			
		||||
    Returns
 | 
			
		||||
    -------
 | 
			
		||||
    decorator : function
 | 
			
		||||
        Decorator, which, when applied to a function, causes KnownFailureTest to
 | 
			
		||||
        be raised when `fail_condition` is True and the test fails.
 | 
			
		||||
 | 
			
		||||
    Notes
 | 
			
		||||
    -----
 | 
			
		||||
    The decorator itself is decorated with the ``nose.tools.make_decorator``
 | 
			
		||||
    function in order to transmit function name, and various other metadata.
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    if msg is None:
 | 
			
		||||
        msg = 'Test skipped due to known failure'
 | 
			
		||||
 | 
			
		||||
    def knownfail_decorator(f):
 | 
			
		||||
        # Local import to avoid a hard nose dependency and only incur the
 | 
			
		||||
        # import time overhead at actual test-time.
 | 
			
		||||
        import nose
 | 
			
		||||
 | 
			
		||||
        def knownfailer(*args, **kwargs):
 | 
			
		||||
            if fail_condition:
 | 
			
		||||
                raise KnownFailureTest(msg)
 | 
			
		||||
            else:
 | 
			
		||||
                return f(*args, **kwargs)
 | 
			
		||||
        return nose.tools.make_decorator(f)(knownfailer)
 | 
			
		||||
 | 
			
		||||
    return knownfail_decorator
 | 
			
		||||
							
								
								
									
										41
									
								
								venv/Lib/site-packages/IPython/external/decorators/_numpy_testing_noseclasses.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								venv/Lib/site-packages/IPython/external/decorators/_numpy_testing_noseclasses.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,41 @@
 | 
			
		|||
# IPython: modified copy of numpy.testing.noseclasses, so
 | 
			
		||||
# IPython.external._decorators works without numpy being installed.
 | 
			
		||||
 | 
			
		||||
# These classes implement a "known failure" error class.
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
from nose.plugins.errorclass import ErrorClass, ErrorClassPlugin
 | 
			
		||||
 | 
			
		||||
class KnownFailureTest(Exception):
 | 
			
		||||
    '''Raise this exception to mark a test as a known failing test.'''
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class KnownFailure(ErrorClassPlugin):
 | 
			
		||||
    '''Plugin that installs a KNOWNFAIL error class for the
 | 
			
		||||
    KnownFailureClass exception.  When KnownFailureTest is raised,
 | 
			
		||||
    the exception will be logged in the knownfail attribute of the
 | 
			
		||||
    result, 'K' or 'KNOWNFAIL' (verbose) will be output, and the
 | 
			
		||||
    exception will not be counted as an error or failure.'''
 | 
			
		||||
    enabled = True
 | 
			
		||||
    knownfail = ErrorClass(KnownFailureTest,
 | 
			
		||||
                           label='KNOWNFAIL',
 | 
			
		||||
                           isfailure=False)
 | 
			
		||||
 | 
			
		||||
    def options(self, parser, env=os.environ):
 | 
			
		||||
        env_opt = 'NOSE_WITHOUT_KNOWNFAIL'
 | 
			
		||||
        parser.add_option('--no-knownfail', action='store_true',
 | 
			
		||||
                          dest='noKnownFail', default=env.get(env_opt, False),
 | 
			
		||||
                          help='Disable special handling of KnownFailureTest '
 | 
			
		||||
                               'exceptions')
 | 
			
		||||
 | 
			
		||||
    def configure(self, options, conf):
 | 
			
		||||
        if not self.can_configure:
 | 
			
		||||
            return
 | 
			
		||||
        self.conf = conf
 | 
			
		||||
        disable = getattr(options, 'noKnownFail', False)
 | 
			
		||||
        if disable:
 | 
			
		||||
            self.enabled = False
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										13
									
								
								venv/Lib/site-packages/IPython/external/mathjax.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								venv/Lib/site-packages/IPython/external/mathjax.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,13 @@
 | 
			
		|||
#!/usr/bin/python
 | 
			
		||||
"""
 | 
			
		||||
`IPython.external.mathjax` is deprecated with IPython 4.0+
 | 
			
		||||
 | 
			
		||||
mathjax is now install by default with the notebook package
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import sys 
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__' :
 | 
			
		||||
    sys.exit("IPython.external.mathjax is deprecated, Mathjax is now installed by default with the notebook package")
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										95
									
								
								venv/Lib/site-packages/IPython/external/qt_for_kernel.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								venv/Lib/site-packages/IPython/external/qt_for_kernel.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,95 @@
 | 
			
		|||
""" Import Qt in a manner suitable for an IPython kernel.
 | 
			
		||||
 | 
			
		||||
This is the import used for the `gui=qt` or `matplotlib=qt` initialization.
 | 
			
		||||
 | 
			
		||||
Import Priority:
 | 
			
		||||
 | 
			
		||||
if Qt has been imported anywhere else:
 | 
			
		||||
   use that
 | 
			
		||||
 | 
			
		||||
if matplotlib has been imported and doesn't support v2 (<= 1.0.1):
 | 
			
		||||
    use PyQt4 @v1
 | 
			
		||||
 | 
			
		||||
Next, ask QT_API env variable
 | 
			
		||||
 | 
			
		||||
if QT_API not set:
 | 
			
		||||
    ask matplotlib what it's using. If Qt4Agg or Qt5Agg, then use the
 | 
			
		||||
        version matplotlib is configured with
 | 
			
		||||
 | 
			
		||||
    else: (matplotlib said nothing)
 | 
			
		||||
        # this is the default path - nobody told us anything
 | 
			
		||||
        try in this order:
 | 
			
		||||
            PyQt default version, PySide, PyQt5
 | 
			
		||||
else:
 | 
			
		||||
    use what QT_API says
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
# NOTE: This is no longer an external, third-party module, and should be
 | 
			
		||||
# considered part of IPython. For compatibility however, it is being kept in
 | 
			
		||||
# IPython/external.
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
from IPython.utils.version import check_version
 | 
			
		||||
from IPython.external.qt_loaders import (load_qt, loaded_api, QT_API_PYSIDE,
 | 
			
		||||
                                         QT_API_PYSIDE2, QT_API_PYQT, QT_API_PYQT5,
 | 
			
		||||
                                         QT_API_PYQTv1, QT_API_PYQT_DEFAULT)
 | 
			
		||||
 | 
			
		||||
_qt_apis = (QT_API_PYSIDE, QT_API_PYSIDE2, QT_API_PYQT, QT_API_PYQT5, QT_API_PYQTv1,
 | 
			
		||||
            QT_API_PYQT_DEFAULT)
 | 
			
		||||
 | 
			
		||||
#Constraints placed on an imported matplotlib
 | 
			
		||||
def matplotlib_options(mpl):
 | 
			
		||||
    if mpl is None:
 | 
			
		||||
        return
 | 
			
		||||
    backend = mpl.rcParams.get('backend', None)
 | 
			
		||||
    if backend == 'Qt4Agg':
 | 
			
		||||
        mpqt = mpl.rcParams.get('backend.qt4', None)
 | 
			
		||||
        if mpqt is None:
 | 
			
		||||
            return None
 | 
			
		||||
        if mpqt.lower() == 'pyside':
 | 
			
		||||
            return [QT_API_PYSIDE]
 | 
			
		||||
        elif mpqt.lower() == 'pyqt4':
 | 
			
		||||
            return [QT_API_PYQT_DEFAULT]
 | 
			
		||||
        elif mpqt.lower() == 'pyqt4v2':
 | 
			
		||||
            return [QT_API_PYQT]
 | 
			
		||||
        raise ImportError("unhandled value for backend.qt4 from matplotlib: %r" %
 | 
			
		||||
                          mpqt)
 | 
			
		||||
    elif backend == 'Qt5Agg':
 | 
			
		||||
        mpqt = mpl.rcParams.get('backend.qt5', None)
 | 
			
		||||
        if mpqt is None:
 | 
			
		||||
            return None
 | 
			
		||||
        if mpqt.lower() == 'pyqt5':
 | 
			
		||||
            return [QT_API_PYQT5]
 | 
			
		||||
        raise ImportError("unhandled value for backend.qt5 from matplotlib: %r" %
 | 
			
		||||
                          mpqt)
 | 
			
		||||
 | 
			
		||||
def get_options():
 | 
			
		||||
    """Return a list of acceptable QT APIs, in decreasing order of
 | 
			
		||||
    preference
 | 
			
		||||
    """
 | 
			
		||||
    #already imported Qt somewhere. Use that
 | 
			
		||||
    loaded = loaded_api()
 | 
			
		||||
    if loaded is not None:
 | 
			
		||||
        return [loaded]
 | 
			
		||||
 | 
			
		||||
    mpl = sys.modules.get('matplotlib', None)
 | 
			
		||||
 | 
			
		||||
    if mpl is not None and not check_version(mpl.__version__, '1.0.2'):
 | 
			
		||||
        #1.0.1 only supports PyQt4 v1
 | 
			
		||||
        return [QT_API_PYQT_DEFAULT]
 | 
			
		||||
 | 
			
		||||
    qt_api = os.environ.get('QT_API', None)
 | 
			
		||||
    if qt_api is None:
 | 
			
		||||
        #no ETS variable. Ask mpl, then use default fallback path
 | 
			
		||||
        return matplotlib_options(mpl) or [QT_API_PYQT_DEFAULT, QT_API_PYSIDE,
 | 
			
		||||
                                           QT_API_PYQT5, QT_API_PYSIDE2]
 | 
			
		||||
    elif qt_api not in _qt_apis:
 | 
			
		||||
        raise RuntimeError("Invalid Qt API %r, valid values are: %r" %
 | 
			
		||||
                           (qt_api, ', '.join(_qt_apis)))
 | 
			
		||||
    else:
 | 
			
		||||
        return [qt_api]
 | 
			
		||||
 | 
			
		||||
api_opts = get_options()
 | 
			
		||||
QtCore, QtGui, QtSvg, QT_API = load_qt(api_opts)
 | 
			
		||||
							
								
								
									
										329
									
								
								venv/Lib/site-packages/IPython/external/qt_loaders.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										329
									
								
								venv/Lib/site-packages/IPython/external/qt_loaders.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,329 @@
 | 
			
		|||
"""
 | 
			
		||||
This module contains factory functions that attempt
 | 
			
		||||
to return Qt submodules from the various python Qt bindings.
 | 
			
		||||
 | 
			
		||||
It also protects against double-importing Qt with different
 | 
			
		||||
bindings, which is unstable and likely to crash
 | 
			
		||||
 | 
			
		||||
This is used primarily by qt and qt_for_kernel, and shouldn't
 | 
			
		||||
be accessed directly from the outside
 | 
			
		||||
"""
 | 
			
		||||
import sys
 | 
			
		||||
import types
 | 
			
		||||
from functools import partial
 | 
			
		||||
from importlib import import_module
 | 
			
		||||
 | 
			
		||||
from IPython.utils.version import check_version
 | 
			
		||||
 | 
			
		||||
# Available APIs.
 | 
			
		||||
QT_API_PYQT = 'pyqt' # Force version 2
 | 
			
		||||
QT_API_PYQT5 = 'pyqt5'
 | 
			
		||||
QT_API_PYQTv1 = 'pyqtv1' # Force version 2
 | 
			
		||||
QT_API_PYQT_DEFAULT = 'pyqtdefault' # use system default for version 1 vs. 2
 | 
			
		||||
QT_API_PYSIDE = 'pyside'
 | 
			
		||||
QT_API_PYSIDE2 = 'pyside2'
 | 
			
		||||
 | 
			
		||||
api_to_module = {QT_API_PYSIDE2: 'PySide2',
 | 
			
		||||
                 QT_API_PYSIDE: 'PySide',
 | 
			
		||||
                 QT_API_PYQT: 'PyQt4',
 | 
			
		||||
                 QT_API_PYQTv1: 'PyQt4',
 | 
			
		||||
                 QT_API_PYQT5: 'PyQt5',
 | 
			
		||||
                 QT_API_PYQT_DEFAULT: 'PyQt4',
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ImportDenier(object):
 | 
			
		||||
    """Import Hook that will guard against bad Qt imports
 | 
			
		||||
    once IPython commits to a specific binding
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.__forbidden = set()
 | 
			
		||||
 | 
			
		||||
    def forbid(self, module_name):
 | 
			
		||||
        sys.modules.pop(module_name, None)
 | 
			
		||||
        self.__forbidden.add(module_name)
 | 
			
		||||
 | 
			
		||||
    def find_module(self, fullname, path=None):
 | 
			
		||||
        if path:
 | 
			
		||||
            return
 | 
			
		||||
        if fullname in self.__forbidden:
 | 
			
		||||
            return self
 | 
			
		||||
 | 
			
		||||
    def load_module(self, fullname):
 | 
			
		||||
        raise ImportError("""
 | 
			
		||||
    Importing %s disabled by IPython, which has
 | 
			
		||||
    already imported an Incompatible QT Binding: %s
 | 
			
		||||
    """ % (fullname, loaded_api()))
 | 
			
		||||
 | 
			
		||||
ID = ImportDenier()
 | 
			
		||||
sys.meta_path.insert(0, ID)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def commit_api(api):
 | 
			
		||||
    """Commit to a particular API, and trigger ImportErrors on subsequent
 | 
			
		||||
       dangerous imports"""
 | 
			
		||||
 | 
			
		||||
    if api == QT_API_PYSIDE2:
 | 
			
		||||
        ID.forbid('PySide')
 | 
			
		||||
        ID.forbid('PyQt4')
 | 
			
		||||
        ID.forbid('PyQt5')
 | 
			
		||||
    elif api == QT_API_PYSIDE:
 | 
			
		||||
        ID.forbid('PySide2')
 | 
			
		||||
        ID.forbid('PyQt4')
 | 
			
		||||
        ID.forbid('PyQt5')
 | 
			
		||||
    elif api == QT_API_PYQT5:
 | 
			
		||||
        ID.forbid('PySide2')
 | 
			
		||||
        ID.forbid('PySide')
 | 
			
		||||
        ID.forbid('PyQt4')
 | 
			
		||||
    else:   # There are three other possibilities, all representing PyQt4
 | 
			
		||||
        ID.forbid('PyQt5')
 | 
			
		||||
        ID.forbid('PySide2')
 | 
			
		||||
        ID.forbid('PySide')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def loaded_api():
 | 
			
		||||
    """Return which API is loaded, if any
 | 
			
		||||
 | 
			
		||||
    If this returns anything besides None,
 | 
			
		||||
    importing any other Qt binding is unsafe.
 | 
			
		||||
 | 
			
		||||
    Returns
 | 
			
		||||
    -------
 | 
			
		||||
    None, 'pyside2', 'pyside', 'pyqt', 'pyqt5', or 'pyqtv1'
 | 
			
		||||
    """
 | 
			
		||||
    if 'PyQt4.QtCore' in sys.modules:
 | 
			
		||||
        if qtapi_version() == 2:
 | 
			
		||||
            return QT_API_PYQT
 | 
			
		||||
        else:
 | 
			
		||||
            return QT_API_PYQTv1
 | 
			
		||||
    elif 'PySide.QtCore' in sys.modules:
 | 
			
		||||
        return QT_API_PYSIDE
 | 
			
		||||
    elif 'PySide2.QtCore' in sys.modules:
 | 
			
		||||
        return QT_API_PYSIDE2
 | 
			
		||||
    elif 'PyQt5.QtCore' in sys.modules:
 | 
			
		||||
        return QT_API_PYQT5
 | 
			
		||||
    return None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def has_binding(api):
 | 
			
		||||
    """Safely check for PyQt4/5, PySide or PySide2, without importing submodules
 | 
			
		||||
 | 
			
		||||
        Parameters
 | 
			
		||||
        ----------
 | 
			
		||||
        api : str [ 'pyqtv1' | 'pyqt' | 'pyqt5' | 'pyside' | 'pyside2' | 'pyqtdefault']
 | 
			
		||||
             Which module to check for
 | 
			
		||||
 | 
			
		||||
        Returns
 | 
			
		||||
        -------
 | 
			
		||||
        True if the relevant module appears to be importable
 | 
			
		||||
     """
 | 
			
		||||
    module_name = api_to_module[api]
 | 
			
		||||
    from importlib.util import find_spec
 | 
			
		||||
 | 
			
		||||
    required = ['QtCore', 'QtGui', 'QtSvg']
 | 
			
		||||
    if api in (QT_API_PYQT5, QT_API_PYSIDE2):
 | 
			
		||||
        # QT5 requires QtWidgets too
 | 
			
		||||
        required.append('QtWidgets')
 | 
			
		||||
 | 
			
		||||
    for submod in required:
 | 
			
		||||
        try:
 | 
			
		||||
            spec = find_spec('%s.%s' % (module_name, submod))
 | 
			
		||||
        except ImportError:
 | 
			
		||||
            # Package (e.g. PyQt5) not found
 | 
			
		||||
            return False
 | 
			
		||||
        else:
 | 
			
		||||
            if spec is None:
 | 
			
		||||
                # Submodule (e.g. PyQt5.QtCore) not found
 | 
			
		||||
                return False
 | 
			
		||||
 | 
			
		||||
    if api == QT_API_PYSIDE:
 | 
			
		||||
        # We can also safely check PySide version
 | 
			
		||||
        import PySide
 | 
			
		||||
        return check_version(PySide.__version__, '1.0.3')
 | 
			
		||||
 | 
			
		||||
    return True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def qtapi_version():
 | 
			
		||||
    """Return which QString API has been set, if any
 | 
			
		||||
 | 
			
		||||
    Returns
 | 
			
		||||
    -------
 | 
			
		||||
    The QString API version (1 or 2), or None if not set
 | 
			
		||||
    """
 | 
			
		||||
    try:
 | 
			
		||||
        import sip
 | 
			
		||||
    except ImportError:
 | 
			
		||||
        return
 | 
			
		||||
    try:
 | 
			
		||||
        return sip.getapi('QString')
 | 
			
		||||
    except ValueError:
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def can_import(api):
 | 
			
		||||
    """Safely query whether an API is importable, without importing it"""
 | 
			
		||||
    if not has_binding(api):
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
    current = loaded_api()
 | 
			
		||||
    if api == QT_API_PYQT_DEFAULT:
 | 
			
		||||
        return current in [QT_API_PYQT, QT_API_PYQTv1, None]
 | 
			
		||||
    else:
 | 
			
		||||
        return current in [api, None]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def import_pyqt4(version=2):
 | 
			
		||||
    """
 | 
			
		||||
    Import PyQt4
 | 
			
		||||
 | 
			
		||||
    Parameters
 | 
			
		||||
    ----------
 | 
			
		||||
    version : 1, 2, or None
 | 
			
		||||
      Which QString/QVariant API to use. Set to None to use the system
 | 
			
		||||
      default
 | 
			
		||||
 | 
			
		||||
    ImportErrors rasied within this function are non-recoverable
 | 
			
		||||
    """
 | 
			
		||||
    # The new-style string API (version=2) automatically
 | 
			
		||||
    # converts QStrings to Unicode Python strings. Also, automatically unpacks
 | 
			
		||||
    # QVariants to their underlying objects.
 | 
			
		||||
    import sip
 | 
			
		||||
 | 
			
		||||
    if version is not None:
 | 
			
		||||
        sip.setapi('QString', version)
 | 
			
		||||
        sip.setapi('QVariant', version)
 | 
			
		||||
 | 
			
		||||
    from PyQt4 import QtGui, QtCore, QtSvg
 | 
			
		||||
 | 
			
		||||
    if not check_version(QtCore.PYQT_VERSION_STR, '4.7'):
 | 
			
		||||
        raise ImportError("IPython requires PyQt4 >= 4.7, found %s" %
 | 
			
		||||
                          QtCore.PYQT_VERSION_STR)
 | 
			
		||||
 | 
			
		||||
    # Alias PyQt-specific functions for PySide compatibility.
 | 
			
		||||
    QtCore.Signal = QtCore.pyqtSignal
 | 
			
		||||
    QtCore.Slot = QtCore.pyqtSlot
 | 
			
		||||
 | 
			
		||||
    # query for the API version (in case version == None)
 | 
			
		||||
    version = sip.getapi('QString')
 | 
			
		||||
    api = QT_API_PYQTv1 if version == 1 else QT_API_PYQT
 | 
			
		||||
    return QtCore, QtGui, QtSvg, api
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def import_pyqt5():
 | 
			
		||||
    """
 | 
			
		||||
    Import PyQt5
 | 
			
		||||
 | 
			
		||||
    ImportErrors rasied within this function are non-recoverable
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    from PyQt5 import QtCore, QtSvg, QtWidgets, QtGui
 | 
			
		||||
    
 | 
			
		||||
    # Alias PyQt-specific functions for PySide compatibility.
 | 
			
		||||
    QtCore.Signal = QtCore.pyqtSignal
 | 
			
		||||
    QtCore.Slot = QtCore.pyqtSlot
 | 
			
		||||
 | 
			
		||||
    # Join QtGui and QtWidgets for Qt4 compatibility.
 | 
			
		||||
    QtGuiCompat = types.ModuleType('QtGuiCompat')
 | 
			
		||||
    QtGuiCompat.__dict__.update(QtGui.__dict__)
 | 
			
		||||
    QtGuiCompat.__dict__.update(QtWidgets.__dict__)
 | 
			
		||||
 | 
			
		||||
    api = QT_API_PYQT5
 | 
			
		||||
    return QtCore, QtGuiCompat, QtSvg, api
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def import_pyside():
 | 
			
		||||
    """
 | 
			
		||||
    Import PySide
 | 
			
		||||
 | 
			
		||||
    ImportErrors raised within this function are non-recoverable
 | 
			
		||||
    """
 | 
			
		||||
    from PySide import QtGui, QtCore, QtSvg
 | 
			
		||||
    return QtCore, QtGui, QtSvg, QT_API_PYSIDE
 | 
			
		||||
 | 
			
		||||
def import_pyside2():
 | 
			
		||||
    """
 | 
			
		||||
    Import PySide2
 | 
			
		||||
 | 
			
		||||
    ImportErrors raised within this function are non-recoverable
 | 
			
		||||
    """
 | 
			
		||||
    from PySide2 import QtGui, QtCore, QtSvg, QtWidgets, QtPrintSupport
 | 
			
		||||
 | 
			
		||||
    # Join QtGui and QtWidgets for Qt4 compatibility.
 | 
			
		||||
    QtGuiCompat = types.ModuleType('QtGuiCompat')
 | 
			
		||||
    QtGuiCompat.__dict__.update(QtGui.__dict__)
 | 
			
		||||
    QtGuiCompat.__dict__.update(QtWidgets.__dict__)
 | 
			
		||||
    QtGuiCompat.__dict__.update(QtPrintSupport.__dict__)
 | 
			
		||||
 | 
			
		||||
    return QtCore, QtGuiCompat, QtSvg, QT_API_PYSIDE2
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def load_qt(api_options):
 | 
			
		||||
    """
 | 
			
		||||
    Attempt to import Qt, given a preference list
 | 
			
		||||
    of permissible bindings
 | 
			
		||||
 | 
			
		||||
    It is safe to call this function multiple times.
 | 
			
		||||
 | 
			
		||||
    Parameters
 | 
			
		||||
    ----------
 | 
			
		||||
    api_options: List of strings
 | 
			
		||||
        The order of APIs to try. Valid items are 'pyside', 'pyside2',
 | 
			
		||||
        'pyqt', 'pyqt5', 'pyqtv1' and 'pyqtdefault'
 | 
			
		||||
 | 
			
		||||
    Returns
 | 
			
		||||
    -------
 | 
			
		||||
 | 
			
		||||
    A tuple of QtCore, QtGui, QtSvg, QT_API
 | 
			
		||||
    The first three are the Qt modules. The last is the
 | 
			
		||||
    string indicating which module was loaded.
 | 
			
		||||
 | 
			
		||||
    Raises
 | 
			
		||||
    ------
 | 
			
		||||
    ImportError, if it isn't possible to import any requested
 | 
			
		||||
    bindings (either because they aren't installed, or because
 | 
			
		||||
    an incompatible library has already been installed)
 | 
			
		||||
    """
 | 
			
		||||
    loaders = {
 | 
			
		||||
               QT_API_PYSIDE2: import_pyside2,
 | 
			
		||||
               QT_API_PYSIDE: import_pyside,
 | 
			
		||||
               QT_API_PYQT: import_pyqt4,
 | 
			
		||||
               QT_API_PYQT5: import_pyqt5,
 | 
			
		||||
               QT_API_PYQTv1: partial(import_pyqt4, version=1),
 | 
			
		||||
               QT_API_PYQT_DEFAULT: partial(import_pyqt4, version=None)
 | 
			
		||||
              }
 | 
			
		||||
 | 
			
		||||
    for api in api_options:
 | 
			
		||||
 | 
			
		||||
        if api not in loaders:
 | 
			
		||||
            raise RuntimeError(
 | 
			
		||||
                "Invalid Qt API %r, valid values are: %s" %
 | 
			
		||||
                (api, ", ".join(["%r" % k for k in loaders.keys()])))
 | 
			
		||||
 | 
			
		||||
        if not can_import(api):
 | 
			
		||||
            continue
 | 
			
		||||
 | 
			
		||||
        #cannot safely recover from an ImportError during this
 | 
			
		||||
        result = loaders[api]()
 | 
			
		||||
        api = result[-1]  # changed if api = QT_API_PYQT_DEFAULT
 | 
			
		||||
        commit_api(api)
 | 
			
		||||
        return result
 | 
			
		||||
    else:
 | 
			
		||||
        raise ImportError("""
 | 
			
		||||
    Could not load requested Qt binding. Please ensure that
 | 
			
		||||
    PyQt4 >= 4.7, PyQt5, PySide >= 1.0.3 or PySide2 is available,
 | 
			
		||||
    and only one is imported per session.
 | 
			
		||||
 | 
			
		||||
    Currently-imported Qt library:                              %r
 | 
			
		||||
    PyQt4 available (requires QtCore, QtGui, QtSvg):            %s
 | 
			
		||||
    PyQt5 available (requires QtCore, QtGui, QtSvg, QtWidgets): %s
 | 
			
		||||
    PySide >= 1.0.3 installed:                                  %s
 | 
			
		||||
    PySide2 installed:                                          %s
 | 
			
		||||
    Tried to load:                                              %r
 | 
			
		||||
    """ % (loaded_api(),
 | 
			
		||||
           has_binding(QT_API_PYQT),
 | 
			
		||||
           has_binding(QT_API_PYQT5),
 | 
			
		||||
           has_binding(QT_API_PYSIDE),
 | 
			
		||||
           has_binding(QT_API_PYSIDE2),
 | 
			
		||||
           api_options))
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue