3
ûâdeu4  ã               @   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 d tj| ƒ X d S )N)r   ÚshutilÚrmtree)Útd© r   ú:/tmp/pip-build-red6nood/pip/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 )N)Ú	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 )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   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| ƒj|ƒ || _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   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 )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   c             C   s*   t jjƒ }|r|j|ƒ 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jƒ }|r|j|ƒ t| ||td� dS )zDA method of calling the wrapper subprocess while suppressing output.)r'   r(   ÚstderrN)r)   r*   r+   r,   r   r   )r-   r'   r.   r(   r   r   r   r   E   s    

c             C   sn   t jj|ƒrtdƒ‚t jj| ƒ}t jjt jj||ƒƒ}t jj|ƒ}t jj|ƒ}t jj||gƒ|krjtdƒ‚|S )zèNormalise 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_checkN   s    r7   c               @   s†   e Zd ZdZddd„Zedd„ ƒZ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   )r7   Ú
source_dir)Ú.0Úp)r   r   r   ú
<listcomp>‰   s    z-Pep517HookCaller.__init__.<locals>.<listcomp>)	r   r   r8   Úbuild_backendr!   Ú_subprocess_runnerÚsysÚ
executableÚpython_executable)r   r8   r<   r!   Úrunnerr@   r   )r   r   r   z   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)r=   )r   rA   Úprevr   r   r   Úsubprocess_runner‘   s
    
z"Pep517HookCaller.subprocess_runnerc             C   s   | j di ƒS )z>Return the list of optional features supported by the backend.Ú_supported_features)Ú
_call_hook)r   r   r   r   rD   �   s    z$Pep517HookCaller._supported_featuresc             C   s   | j 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)rE   )r   rG   r   r   r   rF   ¡   s    z-Pep517HookCaller.get_requires_for_build_wheelTc             C   s   | j 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_directoryrG   Ú_allow_fallback)rE   r   )r   rI   rG   rJ   r   r   r   rH   °   s    z1Pep517HookCaller.prepare_metadata_for_build_wheelc             C   s(   |dk	rt |ƒ}| j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_directoryrG   rI   )r   rE   )r   rL   rG   rI   r   r   r   rK   Â   s    zPep517HookCaller.build_wheelc             C   s   | j 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_editablerG   )rE   )r   rG   r   r   r   rM   Ö   s    z0Pep517HookCaller.get_requires_for_build_editablec             C   s   | j 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_editable)rI   rG   rJ   )rE   r   )r   rI   rG   rJ   r   r   r   rN   å   s    z4Pep517HookCaller.prepare_metadata_for_build_editablec             C   s(   |dk	rt |ƒ}| j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_editable)rL   rG   rI   )r   rE   )r   rL   rG   rI   r   r   r   rO   ÷   s    zPep517HookCaller.build_editablec             C   s   | j 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_sdistrG   )rE   )r   rG   r   r   r   rP     s    z-Pep517HookCaller.get_requires_for_build_sdistc             C   s   | j dt|ƒ|dœƒS )z£Build 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_directoryrG   )rE   r   )r   rR   rG   r   r   r   rQ     s    zPep517HookCaller.build_sdistc             C   s`  t jd dkr| jjdƒ}n| j}d|i}| jrbtjj| jƒ}t jd dkrZ|jt jƒ ƒ}||d< t	ƒ �î}d|i}t
j|t|dƒdd� tƒ �.}| j}	| j|	tt|ƒƒ||g| j|d	� W d Q R X t
jt|d
ƒƒ}
|
jdƒrìt|
jddƒƒ‚|
jdƒ�rt|
jddƒƒ‚|
jdƒ�r.t| j| j|
jddƒd�‚|
jdƒ�rNt|
jdƒ�pJ|ƒ‚|
d S Q R X d S )Nr   é   ÚASCIIZPEP517_BUILD_BACKENDZPEP517_BACKEND_PATHÚkwargsz
input.json)Úindent)r'   r.   zoutput.jsonZunsupportedr   Ú Z
no_backendZbackend_invalidZbackend_error)r    r!   r"   Zhook_missingZmissing_hook_nameZ
return_val)r>   Úversion_infor<   Úencoder!   r)   Úpathsepr   Úgetfilesystemencodingr   r
   Z
write_jsonÚpjoinr   r@   r=   r   Ústrr8   Z	read_jsonÚgetr   r   r   r   )r   r$   rU   r<   r.   r!   r   Z
hook_inputÚscriptÚpythonÚdatar   r   r   rE   &  s@    
zPep517HookCaller._call_hook)NNN)N)NT)NN)N)NT)NN)N)N)r   r   r   r   r   r   rC   rD   rF   rH   rK   rM   rN   rO   rP   rQ   rE   r   r   r   r   r   f   s&     

 
 

 
 


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j| ƒ d| _|| _|| _tjƒ \| _| _	tj
| jƒ| _| jƒ  d S )NT)Ú	threadingÚThreadr   ÚdaemonÚloggerÚlevelr)   ÚpipeZfd_readÚfd_writeÚfdopenÚreaderÚstart)r   rf   rg   r   r   r   r   ^  s    zLoggerWrapper.__init__c             C   s   | j S )N)ri   )r   r   r   r   Úfilenok  s    zLoggerWrapper.filenoc             C   s   | j tjƒr| d d… S | S )Nr	   éÿÿÿÿ)Úendswithr)   Úlinesep)Úmsgr   r   r   Úremove_newlinen  s    zLoggerWrapper.remove_newlinec             C   s$   x| j D ]}| j| j|ƒƒ qW d S )N)rk   Ú_writerr   )r   Úliner   r   r   Úrunr  s    zLoggerWrapper.runc             C   s   | j j| j|ƒ d S )N)rf   Úlogrg   )r   r"   r   r   r   rs   v  s    zLoggerWrapper._writeN)
r   r   r   r   r   rm   Ústaticmethodrr   ru   rs   r   r   r   r   rb   X  s   rb   )NN)NN)"rc   Ú
contextlibr   r)   Úos.pathr   r   r\   r   Ú
subprocessr   r   r   r>   Útempfiler   rW   r
   Z
in_processr   Ú__all__r   Ú	Exceptionr   r   r   r   r   r   r7   Úobjectr   rd   rb   r   r   r   r   Ú<module>   s6   	
	
	 s