B
    \N%                 @   s   d Z ddlZddlZddlmZ ddlmZ ddlmZ dZ	dZ
dZd	Zd
ZdZedede	dede
dediZG dd deZe Zejde dd Zdd Zdd Zdd Zdd Zd'ddZdd  Zd!d" Zd#d$ Zd%d& ZdS )(aD  
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
    N)partial)import_module)check_versionZpyqtZpyqt5Zpyqtv1ZpyqtdefaultZpysideZpyside2PySide2PySidePyQt4PyQt5c               @   s2   e Zd ZdZdd Zdd ZdddZd	d
 ZdS )ImportDenierzfImport Hook that will guard against bad Qt imports
    once IPython commits to a specific binding
    c             C   s   t  | _d S )N)set_ImportDenier__forbidden)self r   :lib/python3.7/site-packages/IPython/external/qt_loaders.py__init__(   s    zImportDenier.__init__c             C   s   t j|d  | j| d S )N)sysmodulespopr   add)r   module_namer   r   r   forbid+   s    zImportDenier.forbidNc             C   s   |rd S || j kr| S d S )N)r   )r   fullnamepathr   r   r   find_module/   s    
zImportDenier.find_modulec             C   s   t d|t f d S )Nzi
    Importing %s disabled by IPython, which has
    already imported an Incompatible QT Binding: %s
    )ImportError
loaded_api)r   r   r   r   r   load_module5   s    zImportDenier.load_module)N)__name__
__module____qualname____doc__r   r   r   r   r   r   r   r   r	   #   s
   
r	   c             C   s   | t kr(td td td nn| tkrPtd td td nF| tkrxtd td td ntd td td dS )z[Commit to a particular API, and trigger ImportErrors on subsequent
       dangerous importsr   r   r   r   N)QT_API_PYSIDE2IDr   QT_API_PYSIDEQT_API_PYQT5)apir   r   r   
commit_api?   s    







r%   c               C   sL   dt jkrt dkrtS tS n*dt jkr,tS dt jkr:tS dt jkrHtS dS )zReturn 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'
    zPyQt4.QtCore   zPySide.QtCorezPySide2.QtCorezPyQt5.QtCoreN)r   r   qtapi_versionQT_API_PYQTQT_API_PYQTv1r"   r    r#   r   r   r   r   r   U   s    





r   c          	   C   s   t |  }ddlm} dddg}| ttfkr4|d xB|D ]:}y|d||f }W n tk
rf   dS X |d	kr:dS q:W | tkrdd	l}t	|j
d
S dS )aS  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
     r   )	find_specQtCoreQtGuiQtSvg	QtWidgetsz%s.%sFNz1.0.3T)api_to_moduleimportlib.utilr*   r#   r    appendr   r"   r   r   __version__)r$   r   r*   ZrequiredZsubmodspecr   r   r   r   has_bindingm   s     


r4   c              C   sF   yddl } W n tk
r    dS X y
| dS  tk
r@   dS X dS )zReturn which QString API has been set, if any

    Returns
    -------
    The QString API version (1 or 2), or None if not set
    r   NQString)sipr   getapi
ValueError)r6   r   r   r   r'      s    
r'   c             C   s8   t | sdS t }| tkr(|ttdgkS || dgkS dS )z?Safely query whether an API is importable, without importing itFN)r4   r   QT_API_PYQT_DEFAULTr(   r)   )r$   Zcurrentr   r   r   
can_import   s    r:   r&   c             C   s   ddl }| dk	r(|d|  |d|  ddlm}m}m} t|jdsVtd|j |j	|_
|j|_|d} | dkr|tnt}||||fS )	z
    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
    r   Nr5   ZQVariant)r,   r+   r-   z4.7z'IPython requires PyQt4 >= 4.7, found %s   )r6   Zsetapir   r,   r+   r-   r   ZPYQT_VERSION_STRr   
pyqtSignalSignalpyqtSlotSlotr7   r)   r(   )versionr6   r,   r+   r-   r$   r   r   r   import_pyqt4   s    

rA   c              C   s^   ddl m} m}m}m} | j| _| j| _t	
d}|j|j |j|j t}| |||fS )zX
    Import PyQt5

    ImportErrors rasied within this function are non-recoverable
    r   )r+   r-   r.   r,   QtGuiCompat)r   r+   r-   r.   r,   r<   r=   r>   r?   types
ModuleType__dict__updater#   )r+   r-   r.   r,   rB   r$   r   r   r   import_pyqt5   s    
rG   c              C   s    ddl m} m}m} || |tfS )zY
    Import PySide

    ImportErrors raised within this function are non-recoverable
    r   )r,   r+   r-   )r   r,   r+   r-   r"   )r,   r+   r-   r   r   r   import_pyside   s    rH   c              C   s\   ddl m} m}m}m}m} td}|j	| j |j	|j |j	|j |||t
fS )zZ
    Import PySide2

    ImportErrors raised within this function are non-recoverable
    r   )r,   r+   r-   r.   QtPrintSupportrB   )r   r,   r+   r-   r.   rI   rC   rD   rE   rF   r    )r,   r+   r-   r.   rI   rB   r   r   r   import_pyside2   s    
rJ   c             C   s   t ttttttttt	tddt
t	tddi}x| D ]V}||krbtd|ddd | D f t|slq2||  }|d }t| |S W td	t tttttttt | f dS )
a  
    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 becaues they aren't installed, or because
    an incompatible library has already been installed)
    r;   )r@   Nz'Invalid Qt API %r, valid values are: %sz, c             S   s   g | ]}d | qS )z%rr   ).0kr   r   r   
<listcomp>.  s    zload_qt.<locals>.<listcomp>a@  
    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
    )r    rJ   r"   rH   r(   rA   r#   rG   r)   r   r9   RuntimeErrorjoinkeysr:   r%   r   r   r4   )Zapi_optionsloadersr$   resultr   r   r   load_qt  s0    
 
rT   )r&   )r   r   rC   	functoolsr   	importlibr   ZIPython.utils.versionr   r(   r#   r)   r9   r"   r    r/   objectr	   r!   	meta_pathinsertr%   r   r4   r'   r:   rA   rG   rH   rJ   rT   r   r   r   r   <module>
   s<   '
%	