U
    P^g)                     @   s  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 eeeedZ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   )compatz_in_process.pyc               	   c   s"   t  } z
| V  W 5 t|  X d S N)r	   shutilrmtree)td r   </tmp/pip-install-220asx0h/pip/pip/_vendor/pep517/wrappers.py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 r   	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 r   backend_namebackend_pathmessage)r   r    r!   r"   r   r   r   r       s    zBackendInvalid.__init__Nr   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 r   )superr#   r   	hook_name)r   r%   	__class__r   r   r   (   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 r   r   r   r   r   r   r   /   s    zUnsupportedOperation.__init__Nr   r   r   r   r   r)   -   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_runner3   s    

r3   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   r   r   quiet_subprocess_runner<   s    

r5   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,   pathisabs
ValueErrorr   normpathr   normcasecommonprefix)Zsource_tree	requestedZ
abs_sourceZabs_requestedZnorm_sourceZnorm_requestedr   r   r   norm_and_checkE   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>)r3   r   r?   build_backendr!   _subprocess_runner)r   r?   rD   r!   runnerr   rB   r   r   n   s    

zPep517HookCaller.__init__c                 c   s   | j }|| _ dV  || _ dS )z\A context manager for temporarily overriding the default subprocess
        runner.
        N)rE   )r   rF   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   rJ   r   r   r   rI      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_directoryrJ   _allow_fallbackrL   r   )r   rO   rJ   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_directoryrJ   rO   )r   rL   )r   rS   rJ   rO   r   r   r   rR      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_sdistrJ   rK   rM   r   r   r   rT      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_directoryrJ   rQ   )r   rV   rJ   r   r   r   rU      s    zPep517HookCaller.build_sdistc           	   
   C   s@  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 | jt jt||g| j|d	 t
t|d
}|drt|dd|drt|dd|drt| j| j|ddd|dr"t||d W  5 Q R  S Q R X d S )Nr      ASCIIPEP517_BUILD_BACKENDZPEP517_BACKEND_PATHkwargsz
input.json)indent)r*   r2   zoutput.jsonunsupportedr    
no_backendZbackend_invalidZbackend_errorr   Zhook_missing
return_val)sysversion_inforD   encoder!   r,   pathsepr   getfilesystemencodingr   r   
write_jsonpjoinrE   
executable_in_proc_scriptr?   	read_jsongetr)   r   r   r#   )	r   r%   rZ   rD   r2   r!   r   Z
hook_inputdatar   r   r   rL      sB    


zPep517HookCaller._call_hook)NN)N)NT)NN)N)N)r   r   r   r   r   r   rH   rI   rN   rR   rT   rU   rL   r   r   r   r   r>   ]   s      

	
  
  


r>   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,   pipeZfd_readfd_writefdopenreaderstart)r   rp   rq   r   r   r   r     s    zLoggerWrapper.__init__c                 C   s   | j S r   )rs   rB   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    | j D ]}| | | qd S r   )ru   _writer|   )r   liner   r   r   run%  s    
zLoggerWrapper.runc                 C   s   | j | j| d S r   )rp   logrq   )r   r"   r   r   r   r}   )  s    zLoggerWrapper._writeN)
r   r   r   r   r   rw   staticmethodr|   r   r}   r   r   r   r   rl     s   
rl   )NN)NN)"rm   
contextlibr   r,   os.pathr   r   r   rf   r   
subprocessr   r   r   r`   tempfiler	   r]   r   __file__rh   r   	Exceptionr   r   r#   r)   r3   r5   r=   objectr>   rn   rl   r   r   r   r   <module>   s*   

	
	 /