B
    `d*                 @   s4  d dl Z d dlmZ d dlZd dlmZmZmZ d dl	Z	d dl
mZmZmZ d dlZd dlmZ ddlmZ yd dlmZ dd	 ZW n  ek
r   ed
d	 ZY nX edd ZG dd deZG dd deZG dd deZG dd deZdddZd ddZdd ZG dd de Z!G dd de j"Z#dS )!    N)contextmanager)dirnameabspathjoin)
check_callcheck_outputSTDOUT)mkdtemp   )compatc               C   s   t tdS )Nz_in_process.py)	resourcespath__package__ r   r   ?/tmp/pip-unpacked-wheel-hu9qqap1/pip/_vendor/pep517/wrappers.py_in_proc_script_path   s    r   c               c   s   t tttdV  d S )Nz_in_process.py)pjoinr   r   __file__r   r   r   r   r      s    c           	   c   s"   t  } z
| V  W d t|  X d S )N)r	   shutilrmtree)tdr   r   r   tempdir   s    
r   c               @   s   e Zd ZdZdd ZdS )BackendUnavailablezEWill be raised if the backend cannot be imported in the hook process.c             C   s
   || _ d S )N)	traceback)selfr   r   r   r   __init__#   s    zBackendUnavailable.__init__N)__name__
__module____qualname____doc__r   r   r   r   r   r   !   s   r   c               @   s   e Zd ZdZdd ZdS )BackendInvalidz)Will be raised if the backend is invalid.c             C   s   || _ || _|| _d S )N)backend_namebackend_pathmessage)r   r!   r"   r#   r   r   r   r   )   s    zBackendInvalid.__init__N)r   r   r   r   r   r   r   r   r   r    '   s   r    c                   s    e Zd ZdZ fddZ  ZS )HookMissingz Will be raised on missing hooks.c                s   t t| | || _d S )N)superr$   r   	hook_name)r   r&   )	__class__r   r   r   1   s    zHookMissing.__init__)r   r   r   r   r   __classcell__r   r   )r'   r   r$   /   s   r$   c               @   s   e Zd ZdZdd ZdS )UnsupportedOperationzDMay be raised by build_sdist if the backend indicates that it can't.c             C   s
   || _ d S )N)r   )r   r   r   r   r   r   8   s    zUnsupportedOperation.__init__N)r   r   r   r   r   r   r   r   r   r)   6   s   r)   c             C   s*   t j }|r|| t| ||d dS )z5The default method of calling the wrapper subprocess.)cwdenvN)osenvironcopyupdater   )cmdr*   extra_environr+   r   r   r   default_subprocess_runner<   s    

r2   c             C   s,   t j }|r|| t| ||td dS )zDA method of calling the wrapper subprocess while suppressing output.)r*   r+   stderrN)r,   r-   r.   r/   r   r   )r0   r*   r1   r+   r   r   r   quiet_subprocess_runnerE   s    

r4   c             C   sn   t j|rtdt j| }t jt j||}t j|}t j|}t j||g|krjtd|S )zNormalise and check a backend path.

    Ensure that the requested backend path is specified as a relative path,
    and resolves to a location under the given source tree.

    Return an absolute version of the requested path.
    zpaths must be relativez paths must be inside source tree)	r,   r   isabs
ValueErrorr   normpathr   normcasecommonprefix)source_tree	requested
abs_sourceabs_requestednorm_sourcenorm_requestedr   r   r   norm_and_checkN   s    r@   c               @   s`   e Zd ZdZdddZedd ZdddZdd
dZdddZ	dddZ
dddZdd ZdS )Pep517HookCallerae  A wrapper around a source directory to be built with a PEP 517 backend.

    source_dir : The path to the source directory, containing pyproject.toml.
    build_backend : The build backend spec, as per PEP 517, from
        pyproject.toml.
    backend_path : The backend path, as per PEP 517, from pyproject.toml.
    runner : A callable that invokes the wrapper subprocess.

    The 'runner', if provided, must expect the following:
        cmd : a list of strings representing the command and arguments to
            execute, as would be passed to e.g. 'subprocess.check_call'.
        cwd : a string representing the working directory that must be
            used for the subprocess. Corresponds to the provided source_dir.
        extra_environ : a dict mapping environment variable names to values
            which must be set for the subprocess execution.
    Nc                sB   |d krt }t| _| _|r2 fdd|D }| _| _d S )Nc                s   g | ]}t  j|qS r   )r@   
source_dir).0p)r   r   r   
<listcomp>   s    z-Pep517HookCaller.__init__.<locals>.<listcomp>)r2   r   rB   build_backendr"   _subprocess_runner)r   rB   rF   r"   runnerr   )r   r   r   w   s    
zPep517HookCaller.__init__c             c   s$   | j }|| _ z
dV  W d|| _ X dS )z\A context manager for temporarily overriding the default subprocess
        runner.
        N)rG   )r   rH   prevr   r   r   subprocess_runner   s
    
z"Pep517HookCaller.subprocess_runnerc             C   s   |  dd|iS )aG  Identify packages required for building a wheel

        Returns a list of dependency specifications, e.g.:
            ["wheel >= 0.25", "setuptools"]

        This does not include requirements specified in pyproject.toml.
        It returns the result of calling the equivalently named hook in a
        subprocess.
        get_requires_for_build_wheelconfig_settings)
_call_hook)r   rL   r   r   r   rK      s    
z-Pep517HookCaller.get_requires_for_build_wheelTc             C   s   |  dt|||dS )aq  Prepare a *.dist-info folder with metadata for this project.

        Returns the name of the newly created folder.

        If the build backend defines a hook with this name, it will be called
        in a subprocess. If not, the backend will be asked to build a wheel,
        and the dist-info extracted from that (unless _allow_fallback is
        False).
         prepare_metadata_for_build_wheel)metadata_directoryrL   _allow_fallback)rM   r   )r   rO   rL   rP   r   r   r   rN      s    z1Pep517HookCaller.prepare_metadata_for_build_wheelc             C   s(   |dk	rt |}| dt |||dS )av  Build a wheel from this project.

        Returns the name of the newly created file.

        In general, this will call the 'build_wheel' hook in the backend.
        However, if that was previously called by
        'prepare_metadata_for_build_wheel', and the same metadata_directory is
        used, the previously built wheel will be copied to wheel_directory.
        Nbuild_wheel)wheel_directoryrL   rO   )r   rM   )r   rR   rL   rO   r   r   r   rQ      s    zPep517HookCaller.build_wheelc             C   s   |  dd|iS )a<  Identify packages required for building a wheel

        Returns a list of dependency specifications, e.g.:
            ["setuptools >= 26"]

        This does not include requirements specified in pyproject.toml.
        It returns the result of calling the equivalently named hook in a
        subprocess.
        get_requires_for_build_sdistrL   )rM   )r   rL   r   r   r   rS      s    
z-Pep517HookCaller.get_requires_for_build_sdistc             C   s   |  dt||dS )zBuild an sdist from this project.

        Returns the name of the newly created file.

        This calls the 'build_sdist' backend hook in a subprocess.
        build_sdist)sdist_directoryrL   )rM   r   )r   rU   rL   r   r   r   rT      s    zPep517HookCaller.build_sdistc       
   
   C   sJ  t jd dkr| jd}n| j}d|i}| jrbtj| j}t jd dkrZ|t  }||d< t	 }d|i}t
j|t|ddd t &}| jt jt|||g| j|d	 W d Q R X t
t|d
}	|	drt|	dd|	drt|	dd|	dr$t| j| j|	ddd|	dr8t||	d S Q R X d S )Nr      ASCIIPEP517_BUILD_BACKENDPEP517_BACKEND_PATHkwargsz
input.json)indent)r*   r1   zoutput.jsonunsupportedr    
no_backendbackend_invalidbackend_error)r!   r"   r#   hook_missing
return_val)sysversion_inforF   encoder"   r,   pathsepr   getfilesystemencodingr   r   
write_jsonr   r   rG   
executablestrrB   	read_jsongetr)   r   r    r$   )
r   r&   rZ   rF   r1   r"   r   
hook_inputscriptdatar   r   r   rM      s>    

zPep517HookCaller._call_hook)NN)N)NT)NN)N)N)r   r   r   r   r   r   rJ   rK   rN   rQ   rS   rT   rM   r   r   r   r   rA   f   s    

 
 


rA   c               @   s<   e Zd ZdZdd Zdd Zedd Zdd	 Zd
d Z	dS )LoggerWrapperzd
    Read messages from a pipe and redirect them
    to a logger (see python's logging module).
    c             C   sH   t j|  d| _|| _|| _t \| _| _	t
| j| _|   d S )NT)	threadingThreadr   daemonloggerlevelr,   pipefd_readfd_writefdopenreaderstart)r   rt   ru   r   r   r   r     s    zLoggerWrapper.__init__c             C   s   | j S )N)rx   )r   r   r   r   fileno(  s    zLoggerWrapper.filenoc             C   s   |  tjr| d d S | S )N)endswithr,   linesep)msgr   r   r   remove_newline+  s    zLoggerWrapper.remove_newlinec             C   s$   x| j D ]}| | | qW d S )N)rz   _writer   )r   liner   r   r   run/  s    zLoggerWrapper.runc             C   s   | j | j| d S )N)rt   logru   )r   r#   r   r   r   r   3  s    zLoggerWrapper._writeN)
r   r   r   r   r   r|   staticmethodr   r   r   r   r   r   r   rp     s   rp   )NN)NN)$rq   
contextlibr   r,   os.pathr   r   r   r   r   
subprocessr   r   r   rc   tempfiler	   r]   r   importlib.resourcesr   r   ImportErrorr   	Exceptionr   r    r$   r)   r2   r4   r@   objectrA   rr   rp   r   r   r   r   <module>   s0   	
	
	 0