U
    ees8                  
   @  s  d Z ddlmZ d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
ddlZddlmZ ddlmZmZmZmZmZmZmZ ddlZddlmZ dd	lmZmZmZmZmZ dd
lm Z m!Z! e	j"dkrddl#Z#nddl$Z#eee% ee% eee%e%f  gdf Z&ee%ee%ee% f f Z'ee%df Z(edddZ)dddgdZ*e+e,Z-ddddddZ.dddddZ/dddd d!Z0ddd"d#d$Z1d%d&d%d'd(d)Z2G d*d dZ3d+d,d-d.d/d0dd%d1d2g
Z4d3d4d5d6Z5dS )7z2
build - A simple, correct PEP 517 build frontend
    )annotationsz1.0.3N)Iterator)AnyCallableMappingOptionalSequenceTypeVarUnion   )env)BuildBackendExceptionBuildExceptionBuildSystemTableValidationErrorFailedProcessErrorTypoWarning)check_dependencyparse_wheel_filename)      zos.PathLike[str]_TProjectBuilderProjectBuilder)boundz setuptools.build_meta:__legacy__zsetuptools >= 40.8.0wheel)build-backendrequireszMapping[str, str]strNone)
dictionaryexpectedreturnc                 C  sB   | D ]8}t d || dkrtjd| d| dtdd qd S )Ng?zFound 'z#' in pyproject.toml, did you mean 'z'?   
stacklevel)difflibZSequenceMatcherZratiowarningswarnr   )r   r   obj r(   2/tmp/pip-unpacked-wheel-f07x2s22/build/__init__.py
_find_typo;   s    r*   PathType)
source_dirr    c                 C  sl   t j| s d|  d}t|t j| d}t j| d}t j|sht j|shd|  d}t|d S )NzSource z is not a directorypyproject.tomlzsetup.pyzF does not appear to be a Python project: no pyproject.toml or setup.py)ospathisdirr   joinexists)r,   msgpyproject_tomlsetup_pyr(   r(   r)   _validate_source_directoryE   s    r6   zMapping[str, Any])r/   r    c              
   C  s   z6t | d"}t|  W  5 Q R  W S Q R X W n tk
rN   i  Y S  tk
r } z"|j d|j d}t	|d W 5 d }~X Y n@ tj
k
r } z d|  d| d}t	|d W 5 d }~X Y nX d S )Nrbz: 'z' zFailed to parse z:  )opentomllibloadsreaddecodeFileNotFoundErrorPermissionErrorstrerrorfilenamer   ZTOMLDecodeError)r/   fer3   r(   r(   r)   _read_pyproject_tomlP   s    *rD   )r4   r    c                 C  s  d| krt | d tS t| d }d|krBt |d d}t|n0t|d trftdd |d D srd}t|d|krt |d td |d< nt|d tsd}t|d	|krt|d	 trtd
d |d	 D sd}t|| ddd	h }|rdd	| }t||S )Nzbuild-systemr   z!`requires` is a required propertyc                 s  s   | ]}t |tV  qd S N
isinstancer   .0ir(   r(   r)   	<genexpr>l   s    z,_parse_build_system_table.<locals>.<genexpr>z&`requires` must be an array of stringsr   z `build-backend` must be a stringbackend-pathc                 s  s   | ]}t |tV  qd S rE   rF   rH   r(   r(   r)   rK   }   s     z*`backend-path` must be an array of stringszUnknown properties: z, )
r*   _DEFAULT_BACKENDdictr   rG   listallr   keysr1   )r4   Zbuild_system_tabler3   Zunknown_propsr(   r(   r)   _parse_build_system_table^   s>    



rR   
RunnerTypeenv.IsolatedEnv)runnerr   r    c                   s   ddddd fdd}|S )NzSequence[str]
str | NonezMapping[str, str] | Noner   )cmdcwdextra_environr    c                   s    | |   pi |pi  d S rE   )Zmake_extra_environ)rW   rX   rY   r   rU   r(   r)   _invoke_wrapped_runner   s    z7_wrap_subprocess_runner.<locals>._invoke_wrapped_runnerr(   )rU   r   r[   r(   rZ   r)   _wrap_subprocess_runner   s    r\   c                   @  s,  e Zd ZdZejejfdddddddZe	ejfd	d
ddddddZ
eddddZeddddZeddddZd4ddddddZd5ddddddZd6ddddd d!d"Zd7dddddd#d$d%Zddd&d'd(Zd8dddd)dd*d+d,Zejdd-d.d/d0Zeddd1d2d3ZdS )9r   z#
    The PEP 517 consumer API.
    r+   r   rS   r   )r,   python_executablerU   r    c                 C  st   t j|| _t| || _|| _t j|d}tt	|| _
| j
d | _tj| j| j| j
d| j| jd| _dS )aA  
        :param source_dir: The source directory
        :param python_executable: The python executable where the backend lives
        :param runner: Runner for backend subprocesses

        The ``runner``, if provided, must accept the following arguments:

        - ``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.

        The default runner simply calls the backend hooks in a subprocess, writing backend output
        to stdout/stderr.
        r-   r   rL   )backend_pathr]   rU   N)r.   r/   abspath_source_dirr6   _python_executableZ_runnerr1   rR   rD   _build_system_backendpyproject_hooksZBuildBackendHookCallerget_hook)selfr,   r]   rU   pyproject_toml_pathr(   r(   r)   __init__   s    
zProjectBuilder.__init__ztype[_TProjectBuilder]rT   r   )clsr   r,   rU   r    c                 C  s   | ||j t||dS )N)r,   r]   rU   )r]   r\   )rj   r   r,   rU   r(   r(   r)   from_isolated_env   s
    z ProjectBuilder.from_isolated_envr    c                 C  s   | j S )zProject source directory.)r`   rg   r(   r(   r)   r,      s    zProjectBuilder.source_dirc                 C  s   | j S )zC
        The Python executable used to invoke the backend.
        )ra   rm   r(   r(   r)   r]      s    z ProjectBuilder.python_executablezset[str]c                 C  s   t | jd S )z
        The dependencies defined in the ``pyproject.toml``'s
        ``build-system.requires`` field or the default build dependencies
        if ``pyproject.toml`` is missing or ``build-system`` is undefined.
        r   )setrb   rm   r(   r(   r)   build_system_requires   s    z$ProjectBuilder.build_system_requiresNzConfigSettingsType | None)distributionconfig_settingsr    c              
   C  sV   |  d| d d| }t| j|}| | t||W  5 Q R  S Q R X dS )a@  
        Return the dependencies defined by the backend in addition to
        :attr:`build_system_requires` for a given distribution.

        :param distribution: Distribution to get the dependencies of
            (``sdist`` or ``wheel``)
        :param config_settings: Config settings for the build backend
        zGetting build dependencies for ...Zget_requires_for_build_N)loggetattrrf   _handle_backendrn   )rg   rp   rq   	hook_nameget_requiresr(   r(   r)   get_requires_for_build   s
    	
z%ProjectBuilder.get_requires_for_buildzset[tuple[str, ...]]c                 C  s"   |  ||| j}dd |D S )a  
        Return the dependencies which are not satisfied from the combined set of
        :attr:`build_system_requires` and :meth:`get_requires_for_build` for a given
        distribution.

        :param distribution: Distribution to check (``sdist`` or ``wheel``)
        :param config_settings: Config settings for the build backend
        :returns: Set of variable-length unmet dependency tuples
        c                 S  s   h | ]}t |D ]}|qqS r(   )r   )rI   dur(   r(   r)   	<setcomp>   s     
  z4ProjectBuilder.check_dependencies.<locals>.<setcomp>)rx   unionro   )rg   rp   rq   Zdependenciesr(   r(   r)   check_dependencies   s    
z!ProjectBuilder.check_dependenciesrV   )rp   output_directoryrq   r    c              
   C  sn   |  d| d z| jd| ||ddW S  tk
rh } zt|jtjrVW Y 
dS  W 5 d}~X Y nX dS )aR  
        Prepare metadata for a distribution.

        :param distribution: Distribution to build (must be ``wheel``)
        :param output_directory: Directory to put the prepared metadata in
        :param config_settings: Config settings for the build backend
        :returns: The full path to the prepared metadata directory
        zGetting metadata for rr   Zprepare_metadata_for_build_F)_allow_fallbackN)rs   _call_backendr   rG   	exceptionrd   HookMissing)rg   rp   r~   rq   r   r(   r(   r)   prepare   s    
zProjectBuilder.prepare)rp   r~   rq   metadata_directoryr    c                 C  s>   |  d| d |dkri nd|i}| jd| ||f|S )a  
        Build a distribution.

        :param distribution: Distribution to build (``sdist`` or ``wheel``)
        :param output_directory: Directory to put the built distribution in
        :param config_settings: Config settings for the build backend
        :param metadata_directory: If provided, should be the return value of a
            previous ``prepare`` call on the same ``distribution`` kind
        :returns: The full path to the built distribution
        z	Building rr   Nr   Zbuild_)rs   r   )rg   rp   r~   rq   r   kwargsr(   r(   r)   build  s    zProjectBuilder.build)r~   r    c              	     s   |  d|}|dk	r|S | d|}ttj|}|sDd}t||d  d|d  d}| d t|$}|	| fd	d
|
 D  W 5 Q R X tj||S )a  
        Generate the metadata directory of a distribution and return its path.

        If the backend does not support the ``prepare_metadata_for_build_wheel``
        hook, a wheel will be built and the metadata will be extracted from it.

        :param output_directory: Directory to put the metadata distribution in
        :returns: The path of the metadata directory
        r   NzInvalid wheelrp   -versionz
.dist-info/c                 3  s   | ]}|  r|V  qd S rE   )
startswith)rI   memberZmember_prefixr(   r)   rK   F  s     
 z/ProjectBuilder.metadata_path.<locals>.<genexpr>)r   r   r   r.   r/   basename
ValueErrorzipfileZipFile
extractallnamelistr1   )rg   r~   metadatar   matchr3   Zdistinfowr(   r   r)   metadata_path,  s     
zProjectBuilder.metadata_pathr   )rv   outdirrq   r   r    c              	   K  s   t j|}t| j|}t j|rFt j|sPd| d}t|n
t | | 	| |||f|}W 5 Q R X t j
||S )NzBuild path 'z' exists and is not a directory)r.   r/   r_   rt   rf   r2   r0   r   makedirsru   r1   )rg   rv   r   rq   r   callbackr3   r   r(   r(   r)   r   J  s    

zProjectBuilder._call_backendzIterator[None])hookr    c              
   c  s   z
d V  W n t jk
rJ } z t|d| j dt d W 5 d }~X Y nh tjk
r~ } zt|d| d W 5 d }~X Y n4 tk
r } zt|t dd W 5 d }~X Y nX d S )Nz	Backend 'z' is not available.z0Backend subprocess exited when trying to invoke )exc_info)	rd   BackendUnavailabler   rc   sysr   
subprocessCalledProcessError	Exception)rg   r   r   r(   r(   r)   ru   ]  s    
"zProjectBuilder._handle_backend)messager    c                 C  s0   t jdkrtjtj| dd nttj|  dS )z
        Log a message.

        The default implementation uses the logging module but this function can be
        overridden by users to have a different implementation.

        :param message: Message to output
        )r      r!   r"   N)r   version_info_loggerrs   loggingINFO)r   r(   r(   r)   rs   l  s    

zProjectBuilder.log)N)N)N)NN)N)__name__
__module____qualname____doc__r   
executablerd   default_subprocess_runnerri   classmethodrk   propertyr,   r]   ro   rx   r}   r   r   r   r   
contextlibcontextmanagerru   staticmethodrs   r(   r(   r(   r)   r      s6   *    __version__r   r   r   ConfigSettingsTyper   r   r   z	list[str]rl   c                   C  s   t S rE   )__all__r(   r(   r(   r)   __dir__  s    r   )6r   
__future__r   r   r   r$   r   r.   r   r   r%   r   collections.abcr   typingr   r   r   r   r   r	   r
   rd    r   _exceptionsr   r   r   r   r   Z_utilr   r   r   r:   Ztomlir   rS   r   r+   r   rM   	getLoggerr   r   r*   r6   rD   rR   r\   r   r   r   r(   r(   r(   r)   <module>   s\   $

&

, m