o
    ,]_l                     @   s  d Z ddlmZmZmZ ddlZddlZddlZddlZddl	Z	ddl
Z
ddlZedZeejZe Zee ee eej ddlmZmZ eg dZddd	d
ddddddddddZeee ee@ dksuJ g dZG dd de Z!G dd de Z"ereee eej#@ dksJ dd Z$dd Z%dd Z&G d d! d!e Z'd"d# Z(d$d% Z)d&d' Z*d(d) Z+d=d+d,Z,d-d. Z-d/d0 Z.e/ed1si e_0d2d3 Z1d=d4d5Z2d6d7 Z3G d8d9 d9e Z4g d:Z5d;d< Z6dS )>a  
Python 3 reorganized the standard library (PEP 3108). This module exposes
several standard library modules to Python 2 under their new Python 3
names.

It is designed to be used as follows::

    from future import standard_library
    standard_library.install_aliases()

And then these normal Py3 imports work on both Py3 and Py2::

    import builtins
    import copyreg
    import queue
    import reprlib
    import socketserver
    import winreg    # on Windows only
    import test.support
    import html, html.parser, html.entites
    import http, http.client, http.server
    import http.cookies, http.cookiejar
    import urllib.parse, urllib.request, urllib.response, urllib.error, urllib.robotparser
    import xmlrpc.client, xmlrpc.server

    import _thread
    import _dummy_thread
    import _markupbase

    from itertools import filterfalse, zip_longest
    from sys import intern
    from collections import UserDict, UserList, UserString
    from collections import OrderedDict, Counter, ChainMap     # even on Py2.6
    from subprocess import getoutput, getstatusoutput
    from subprocess import check_output              # even on Py2.6

(The renamed modules and functions are still available under their old
names on Python 2.)

This is a cleaner alternative to this idiom (see
http://docs.pythonsprints.com/python3_porting/py-porting.html)::

    try:
        import queue
    except ImportError:
        import Queue as queue


Limitations
-----------
We don't currently support these modules, but would like to::

    import dbm
    import dbm.dumb
    import dbm.gnu
    import collections.abc  # on Py33
    import pickle     # should (optionally) bring in cPickle on Python 2

    )absolute_importdivisionprint_functionNfuture_stdlib)PY2PY3)testurllibpickledbmbuiltinscopyregqueuesocketserverconfigparserreprlibwinreg_thread_dummy_threadxmlrpchtmlhttp_markupbase)__builtin__copy_regQueuezfuture.moves.socketserverConfigParserrepr_winregthreaddummy_threadzfuture.moves.xmlrpczfuture.moves.htmlzfuture.moves.httpzfuture.moves._markupbase))collectionsUserListr"   r"   )r!   UserDictr#   r#   )r!   
UserStringr$   r$   r!   ChainMapfuture.backports.miscr&   )	itertoolsfilterfalser(   ifilterfalse)r(   zip_longestr(   izip_longest)sysinternr   r.   )reASCIIstatST_MODE)base64encodebytesr3   encodestring)r3   decodebytesr3   decodestring)
subprocess	getoutputcommandsr9   )r8   getstatusoutputr:   r;   )r8   check_outputr'   r<   )mathceilr'   r>   )r!   OrderedDictr'   r?   )r!   Counterr'   r@   r%   )r(   countr'   rA   )r   recursive_reprr'   rB   )	functools
cmp_to_keyr'   rD   c                   @   s8   e Zd ZdZdZdd ZdddZdd	 Zdd
dZdS )RenameImportzX
    A class for import hooks mapping Py3 module names etc. to the Py2 equivalents.
    Tc                 C   sj   || _ t| t| @ }t|dkr#tt| t| ks'J dtdd | D | _dS )z
        Pass in a dictionary-like object mapping from old names to new
        names. E.g. {'ConfigParser': 'configparser', 'cPickle': 'pickle'}
        r   z/Ambiguity in renaming (handler not implemented)c                 s   s    | ]	\}}||fV  qd S N ).0oldnewrG   rG   B/usr/lib/python3/dist-packages/future/standard_library/__init__.py	<genexpr>   s    z(RenameImport.__init__.<locals>.<genexpr>N)
old_to_newsetkeysvalueslendictitems
new_to_old)selfrM   bothrG   rG   rK   __init__   s   zRenameImport.__init__Nc                 C   s$   t dd | jD }||v r| S d S )Nc                 S   s   g | ]	}| d d qS ).r   )split)rH   srG   rG   rK   
<listcomp>  s    z,RenameImport.find_module.<locals>.<listcomp>)rN   rT   )rU   fullnamepathnew_base_namesrG   rG   rK   find_module  s   zRenameImport.find_modulec                 C   sP   d }|t jv rt j| S || jv r| j| }| |}n| |}|t j|< |S rF   )r-   modulesrT   _find_and_load_module)rU   namer]   oldnamemodulerG   rG   rK   load_module	  s   





zRenameImport.load_modulec                 C   s   | d}t|dkrD|d}| ||}z|j}W n" ty=   td| |t	j
v r6t	j
|  Y S td Y nw t|dks|d }t||}tj|g|R  S )zb
        Finds and loads it. But if there's a . in the name, handles it
        properly.
        rX      r   zPackage {0} has no __path__.zWhat to do here?)rY   rQ   popra   __path__AttributeErrorflogdebugformatr-   r`   impr_   re   )rU   rb   r]   bitspackagenamepackagemodule_inforG   rG   rK   ra     s    



z"RenameImport._find_and_load_modulerF   )	__name__
__module____qualname____doc__RENAMERrW   r_   re   ra   rG   rG   rG   rK   rE      s    
rE   c                   @       e Zd ZdZdd Zdd ZdS )hooksa  
    Acts as a context manager. Saves the state of sys.modules and restores it
    after the 'with' block.

    Use like this:

    >>> from future import standard_library
    >>> with standard_library.hooks():
    ...     import http.client
    >>> import requests

    For this to work, http.client will be scrubbed from sys.modules after the
    'with' block. That way the modules imported in the 'with' block will
    continue to be accessible in the current namespace but not from any
    imported modules (like requests).
    c                 C   s    t  tj| _t | _t  | S rF   )copyr-   r`   old_sys_modulesdetect_hookshooks_were_installedinstall_hooksrU   rG   rG   rK   	__enter__A  s   zhooks.__enter__c                 G   s   | j st  d S d S rF   )r|   remove_hooksrU   argsrG   rG   rK   __exit__I  s   
zhooks.__exit__Nrr   rs   rt   ru   r   r   rG   rG   rG   rK   rx   0  s    rx   c                 C   s   t rdS dtjvr,tjtjtjg}dd |D }tt|dks't	
d|  |d t_| jtjv r4dS t| d	rPtj| j}|d tjrPd
|d vrPdS dS )z
    Tries to infer whether the module m is from the Python 2 standard library.
    This may not be reliable on all systems.
    Fstdlib_pathc                 S   s   g | ]
}t j|d  qS )r   )osr]   rY   )rH   frG   rG   rK   r[   _  s    z(is_py2_stdlib_module.<locals>.<listcomp>rf   z<Multiple locations found for the Python standard library: %sr   T__file__zsite-packages)r   is_py2_stdlib_module__dict__
contextlibr   r   ry   rQ   rN   rj   warnr   rr   r-   builtin_module_nameshasattrr]   rY   
startswith)mstdlib_filesstdlib_pathsmodpathrG   rG   rK   r   V  s&   



r   c                  C   sj   t ri S i } ttt @ D ]$}|tjvrqtj| }t|r2t	d
| tj| | |< tj|= q| S )aE  
    Removes any Python 2 standard library modules from ``sys.modules`` that
    would interfere with Py3-style imports using import hooks. Examples are
    modules with the same names (like urllib or email).

    (Note that currently import hooks are disabled for modules like these
    with ambiguous names anyway ...)
    z"Deleting (Py2) {} from sys.modules)r   REPLACED_MODULESrN   RENAMESrO   r-   r`   r   rj   rk   rl   )scrubbed
modulenamerd   rG   rG   rK   scrub_py2_sys_modulest  s   	

r   c                   C   s   i S )z
    Deprecated.
    rG   rG   rG   rG   rK   scrub_future_sys_modules  s   r   c                   @   rw   )suspend_hooksa  
    Acts as a context manager. Use like this:

    >>> from future import standard_library
    >>> standard_library.install_hooks()
    >>> import http.client
    >>> # ...
    >>> with standard_library.suspend_hooks():
    >>>     import requests     # incompatible with ``future``'s standard library hooks

    If the hooks were disabled before the context, they are not installed when
    the context is left.
    c                 C   s   t  | _t  | S rF   )r{   r|   r   r~   rG   rG   rK   r     s   zsuspend_hooks.__enter__c                 G   s   | j rt  d S d S rF   )r|   r}   r   rG   rG   rK   r     s   
zsuspend_hooks.__exit__Nr   rG   rG   rG   rK   r     s    r   c                 C   sH   t tjt | @ }t|dkrt|d }td|tj|  dS )zp
    Add any previously scrubbed modules back to the sys.modules cache,
    but only if it's safe to do so.
    r   z(future module {} clashes with Py2 moduleN)rN   r-   r`   rQ   listImportErrorrl   update)r   clashfirstrG   rG   rK   restore_sys_modules  s   r   c                  C   s  t rdS tD ]#\} }}}t|  tj|  }t| tj| }t||}t||| qddl}ddlm	} ddlm
}	 ddlm}
 ddlm} ddlm} ||_	|	|_
|
|_||_||_|tjd< |	tjd	< |
tjd
< |tjd< |tjd< zddl}W n	 ty   Y nw zddlm} W n	 ty   Y n	w ||_|tjd< zddl}W n
 ty   Y dS w ddlm} ||_|tjd< zddlm} W n	 ty   Y n	w ||_|tjd< zddlm} W n
 ty   Y dS w ||_|tjd< dS )zm
    Monkey-patches the standard library in Py2.6/7 to provide
    aliases for better Py3 compatibility.
    Nr   )request)response)parse)error)robotparserzurllib.requestzurllib.responsezurllib.parsezurllib.errorzurllib.robotparser)supportztest.support)dumbzdbm.dumb)gnuzdbm.gnu)ndbmzdbm.ndbm)r   MOVES
__import__r-   r`   getattrsetattrr	   future.backports.urllibr   r   r   r   r   r   r   future.moves.testr   r   future.moves.dbmr   r   r   )
newmodname
newobjname
oldmodname
oldobjnamenewmodoldmodobjr	   r   r   r   r   r   r   r   r   r   r   r   rG   rG   rK   install_aliases  sv   










r   c                  C   sZ   t rdS t  tdtj td tt} t	 s"tj
|  tdtj dS )z`
    This function installs the future.standard_library import hook into
    sys.meta_path.
    Nzsys.meta_path was: {0}zInstalling hooks ...zsys.meta_path is now: {0})r   r   rj   rk   rl   r-   	meta_pathrE   r   r{   append)newhookrG   rG   rK   r}     s   
r}   c                   C   
   t   dS )z_
    Deprecated. Use install_hooks() instead. This will be removed by
    ``future`` v1.0.
    N)r}   rG   rG   rG   rK   enable_hooks     
r   Fc                 C   sX   t rdS td tttjddd D ]\}}t|dr"tj|= q| r*t  dS dS )zC
    This function removes the import hook from sys.meta_path.
    NzUninstalling hooks ...rv   )	r   rj   rk   r   	enumerater-   r   r   r   )scrub_sys_modulesihookrG   rG   rK   r   '  s   
 

r   c                   C   r   )z^
    Deprecated. Use remove_hooks() instead. This will be removed by
    ``future`` v1.0.
    N)r   rG   rG   rG   rK   disable_hooks;  r   r   c                  C   s>   t d tdd tjD } | rt d | S t d | S )zG
    Returns True if the import hooks are installed, False if not.
    zDetecting hooks ...c                 S   s   g | ]}t |d qS )rv   )r   )rH   r   rG   rG   rK   r[   H      z detect_hooks.<locals>.<listcomp>z	Detected.zNot detected.)rj   rk   anyr-   r   )presentrG   rG   rK   r{   C  s   


r{   py2_modulesc                  C   sV   t tjdkr	dS t rJ ddl} | tjd< ddl}|tjd< ddl}|tjd< dS )z
    Currently this function is unneeded, as we are not attempting to provide import hooks
    for modules with ambiguous names: email, urllib, pickle.
    r   Nr	   emailr
   )rQ   r-   r   r{   r	   r   r
   )r	   r   r
   rG   rG   rK   cache_py2_modulesX  s   


r   c           	      C   s   ddl }tr
t| S |rd}nd}|d| d }g }t|D ]\}}d|d|d  }||| q!tt	t|D ]\}}|dkrN |d S t
||d  |||  qA|d S )a  
    Pass a (potentially dotted) module name of a Python 3 standard library
    module. This function imports the module compatibly on Py2 and Py3 and
    returns the top-level module.

    Example use:
        >>> http = import_('http.client')
        >>> http = import_('http.server')
        >>> urllib = import_('urllib.request')

    Then:
        >>> conn = http.client.HTTPConnection(...)
        >>> response = urllib.request.urlopen('http://mywebsite.com')
        >>> # etc.

    Use as follows:
        >>> package_name = import_(module_name)

    On Py3, equivalent to this:

        >>> import module_name

    On Py2, equivalent to this if backport=False:

        >>> from future.moves import module_name

    or to this if backport=True:

        >>> from future.backports import module_name

    except that it also handles dotted module names such as ``http.client``
    The effect then is like this:

        >>> from future.backports import module
        >>> from future.backports.module import submodule
        >>> module.submodule = submodule

    Note that this would be a SyntaxError in Python:

        >>> from future.backports import http.client

    r   Nfuture.backportsfuture.movesrX   rf      )	importlibr   r   rY   r   joinr   import_modulereversedr   r   )	module_namebackportr   prefixpartsr`   r   partsofarrG   rG   rK   import_t  s"   .r   c                    sz   t rt| S d|v rt|d rd}nd}|d| d }t|d |    fdd|D }t|dkr;|d S |S )	aa  
    Example use:
        >>> HTTPConnection = from_import('http.client', 'HTTPConnection')
        >>> HTTPServer = from_import('http.server', 'HTTPServer')
        >>> urlopen, urlparse = from_import('urllib.request', 'urlopen', 'urlparse')

    Equivalent to this on Py3:

        >>> from module_name import symbol_names[0], symbol_names[1], ...

    and this on Py2:

        >>> from future.moves.module_name import symbol_names[0], ...

    or:

        >>> from future.backports.module_name import symbol_names[0], ...

    except that it also handles dotted module names such as ``http.client``.
    r   r   r   rX   c                    s   g | ]}t  |qS rG   )r   )rH   rb   rd   rG   rK   r[     r   zfrom_import.<locals>.<listcomp>rf   r   )r   r   boolrY   r   r   rQ   )r   symbol_nameskwargsr   r   outputrG   r   rK   from_import  s   r   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	exclude_local_folder_importsaZ  
    A context-manager that prevents standard library modules like configparser
    from being imported from the local python-future source folder on Py3.

    (This was need prior to v0.16.0 because the presence of a configparser
    folder would otherwise have prevented setuptools from running on Py3. Maybe
    it's not needed any more?)
    c                 G   s6   t |dksJ || _tdd | jD rtdd S )Nr   c                 S   s   g | ]}d |v qS )rX   rG   )rH   r   rG   rG   rK   r[     s    z9exclude_local_folder_imports.__init__.<locals>.<listcomp>z%Dotted module names are not supported)rQ   module_namesr   NotImplementedErrorr   rG   rG   rK   rW     s
   z%exclude_local_folder_imports.__init__c              	      s   t  tj| _t  tj| _tjd dk rd S g d}| jD ] t fdd|D r1tj  q| j	D ]}zt
|dd}W q5 tyH   Y q5w d S )Nr      )futurepastlibfuturizelibpasteurizer   c                    s"   g | ]}t jt j |qS rG   )r   r]   existsr   )rH   	subfolderfolderrG   rK   r[     s    z:exclude_local_folder_imports.__enter__.<locals>.<listcomp>)level)ry   r-   r]   old_sys_pathr`   rz   version_infoallremover   r   r   )rU   FUTURE_SOURCE_SUBFOLDERSr   rd   rG   r   rK   r     s$   

z&exclude_local_folder_imports.__enter__c                 G   s>   | j t_t| j ttj  D ]
}| j| tj|< qd S rF   )r   r-   r]   rN   rz   rO   r`   )rU   r   r   rG   rG   rK   r     s    z%exclude_local_folder_imports.__exit__N)rr   rs   rt   ru   rW   r   r   rG   rG   rG   rK   r     s
     r   )r   r   r   r   r   r   r   r   tkinterr   r   r   r   r   c               
   C   sV   t t  tD ]} zt|  W q ty   Y qw W d    d S 1 s$w   Y  d S rF   )r   TOP_LEVEL_MODULESr   r   )r   rG   rG   rK   import_top_level_modules)  s   
"r   )F)7ru   
__future__r   r   r   r-   loggingrm   r   typesry   r   	getLoggerrj   	FormatterBASIC_FORMAT
_formatterStreamHandler_handlersetFormatter
addHandlersetLevelWARNfuture.utilsr   r   rN   r   r   rQ   rP   r   objectrE   rx   r   r   r   r   r   r   r   r}   r   r   r   r{   r   r   r   r   r   r   r   r   rG   rG   rG   rK   <module>   sp    <



 C6F""P


I&6