U
    
Ha3                     @   s  d dl Z d dlmZ d dlZd dl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 ddlmZ d	d
dddddg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)abspathjoin)
check_callcheck_outputSTDOUT)mkdtemp   )compat)_in_proc_script_pathBackendUnavailableBackendInvalidHookMissingUnsupportedOperationdefault_subprocess_runnerquiet_subprocess_runnerPep517HookCallerc               	   c   s"   t  } z
| V  W 5 t|  X d S N)r   shutilrmtree)td r   ?/tmp/pip-unpacked-wheel-tx790h60/pip/_vendor/pep517/wrappers.pytempdir   s    
r   c                   @   s   e Zd ZdZdd ZdS )r   zEWill 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   c                   @   s   e Zd ZdZdd ZdS )r   z)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   c                       s    e Zd ZdZ fddZ  ZS )r   z Will be raised on missing hooks.c                    s   t t| | || _d S r   )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   c                   @   s   e Zd ZdZdd ZdS )r   zDMay 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   8   s    zUnsupportedOperation.__init__Nr   r   r   r   r   r   6   s   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   r   <   s    

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/   r0   r1   r2   r   r   r3   r   r   r   r   E   s    

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)source_tree	requested
abs_sourceabs_requestednorm_sourcenorm_requestedr   r   r   norm_and_checkN   s    rC   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dZd!ddZd"ddZdd ZdS )#r   a  A wrapper around a source directory to be built with a PEP 517 backend.

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

    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                    sR   |d krt }t| _| _|r2 fdd|D }| _| _|sHtj}| _d S )Nc                    s   g | ]}t  j|qS r   )rC   
source_dir).0pr   r   r   
<listcomp>   s    z-Pep517HookCaller.__init__.<locals>.<listcomp>)	r   r   rD   build_backendr&   _subprocess_runnersys
executablepython_executable)r   rD   rI   r&   runnerrM   r   rG   r   r   z   s    

zPep517HookCaller.__init__c                 c   s$   | j }|| _ z
dV  W 5 || _ X dS )z\A context manager for temporarily overriding the default subprocess
        runner.
        N)rJ   )r   rN   prevr   r   r   subprocess_runner   s
    
z"Pep517HookCaller.subprocess_runnerc                 C   s   |  dd|iS )aI  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   rR   r   r   r   rQ      s     z-Pep517HookCaller.get_requires_for_build_wheelTc                 C   s   |  dt|||dS )au  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_directoryrR   _allow_fallbackrT   r   r   rX   rR   rY   r   r   r   rV      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_directoryrR   rX   r   rT   r   r^   rR   rX   r   r   r   r\      s    zPep517HookCaller.build_wheelc                 C   s   |  dd|iS )aS  Identify packages required for building an editable 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_editablerR   rS   rU   r   r   r   ra      s     z0Pep517HookCaller.get_requires_for_build_editablec                 C   s   |  dt|||dS )a  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 an editable
        wheel, and the dist-info extracted from that (unless _allow_fallback is
        False).
        #prepare_metadata_for_build_editablerW   rZ   r[   r   r   r   rb      s
    z4Pep517HookCaller.prepare_metadata_for_build_editablec                 C   s(   |dk	rt |}| dt |||dS )a  Build an editable wheel from this project.

        Returns the name of the newly created file.

        In general, this will call the 'build_editable' hook in the backend.
        However, if that was previously called by
        'prepare_metadata_for_build_editable', and the same metadata_directory
        is used, the previously built wheel will be copied to wheel_directory.
        Nbuild_editabler]   r_   r`   r   r   r   rc      s    zPep517HookCaller.build_editablec                 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_sdistrR   rS   rU   r   r   r   rd     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_directoryrR   rZ   )r   rf   rR   r   r   r   re     s    zPep517HookCaller.build_sdistc              
   C   sl  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}	| j|	tt|||g| j|d	 W 5 Q R X t
t|d
}
|
drt|
dd|
drt|
dd|
dr.t| j| j|
ddd|
drNt|
dpJ||
d W  5 Q R  S Q R X d S )Nr      ASCIIPEP517_BUILD_BACKENDPEP517_BACKEND_PATHkwargsz
input.json)indent)r-   r5   zoutput.jsonunsupportedr    
no_backendbackend_invalidbackend_errorr$   hook_missingZmissing_hook_name
return_val)rK   version_inforI   encoder&   r/   pathsepr   getfilesystemencodingr   r
   
write_jsonpjoinr   rM   rJ   r   strrD   	read_jsongetr   r   r   r   )r   r)   rk   rI   r5   r&   r   
hook_inputscriptpythondatar   r   r   rT   "  sF    

zPep517HookCaller._call_hook)NNN)N)NT)NN)N)NT)NN)N)N)r    r!   r"   r#   r   r   rP   rQ   rV   r\   ra   rb   rc   rd   re   rT   r   r   r   r   r   f   s0      


  
  

  
  


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   r   r   r   r   r   r   Z  s    zLoggerWrapper.__init__c                 C   s   | j S r   )r   rG   r   r   r   filenog  s    zLoggerWrapper.filenoc                 C   s   |  tjr| d d S | S )N)endswithr/   linesep)msgr   r   r   remove_newlinej  s    zLoggerWrapper.remove_newlinec                 C   s    | j D ]}| | | qd S r   )r   _writer   )r   liner   r   r   runn  s    
zLoggerWrapper.runc                 C   s   | j | j| d S r   )r   logr   )r   r'   r   r   r   r   r  s    zLoggerWrapper._writeN)
r    r!   r"   r#   r   r   staticmethodr   r   r   r   r   r   r   r   T  s   
r   )NN)NN)"r   
contextlibr   r/   os.pathr   r   ry   r   
subprocessr   r   r   rK   tempfiler   rn   r
   Z
in_processr   __all__r   	Exceptionr   r   r   r   r   r   rC   objectr   r   r   r   r   r   r   <module>   s:   

	
	 o