o
    ^+)hy                  
   @   s  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m	Z	 ddl
mZ ddlmZ ddlmZ ddlmZ ddlmZ dd	lmZmZmZmZmZmZmZmZmZmZ dd
lm Z m!Z!m"Z"m#Z# ddl$m%Z& ddl'm(Z( ddl)m*Z* erddl+m,Z, ej-dkrddlm.Z. nerddl/m.Z. nddl0m1Z. ee2ef Z3ede3dZ4e5e6Z7G dd deZ8dZ9dZ:G dd de Z;G dd de.Z<G dd dZ=G dd de=Z>G d d! d!Z?d"ed#e@fd$d%ZAd&ee2 d'ee2e2f d(ed#e@fd)d*ZBd+d, ZCd-e*d#ee2 fd.d/ZDd-e*d#ee2 fd0d1ZEd&ee2 d'ee2e2f d2e3d#ee2e2f fd3d4ZFd5e3d#e2fd6d7ZGd8ee2e2f d#ee2 fd9d:ZHd&ee2 d8ee2e2f d#eee2ee2 f  fd;d<ZId8ee2e2f d#ee2e2f fd=d>ZJd?e2d@e2dAe2dBe2d#e@f
dCdDZKdEe3d#e2fdFdGZLdHe4d#e4fdIdJZMdKe2d#e2fdLdMZNG dNdO dOe#jOZPdPZQdKe2dQee2e2f dRee2ee2 f d#e2fdSdTZRG dUdV dVeSZTG dWdX dXe"jUZVdS )Ya  
Create a wheel that, when installed, will make the source package 'editable'
(add it to the interpreter's path, including metadata) per PEP 660. Replaces
'setup.py develop'.

.. note::
   One of the mechanisms briefly mentioned in PEP 660 to implement editable installs is
   to create a separated directory inside ``build`` and use a .pth file to point to that
   directory. In the context of this file such directory is referred as
   *auxiliary build directory* or ``auxiliary_dir``.
    N)suppress)Enum)cleandoc)chain)Path)TemporaryDirectory)
TYPE_CHECKINGDictIterableIteratorListMappingOptionalTupleTypeVarUnion)CommandSetuptoolsDeprecationWarningerrors
namespaces)build_pyfind_package_path)Distribution	WheelFile)      )Protocol)ABC_P)boundc                   @   s6   e Zd ZdZdZdZdZedee	 dd fddZ
d	S )
_EditableModea  
    Possible editable installation modes:
    `lenient` (new files automatically added to the package - DEFAULT);
    `strict` (requires a new installation when files are added/removed); or
    `compat` (attempts to emulate `python setup.py develop` - DEPRECATED).
    strictlenientcompatmodereturnc                 C   sN   |st jS | }|t jvrtd|d|dkr#d}t|t t | S )NzInvalid editable mode: z. Try: 'strict'.COMPATax  
            The 'compat' editable mode is transitional and will be removed
            in future versions of `setuptools`.
            Please adapt your code accordingly to use either the 'strict' or the
            'lenient' modes.

            For more information, please check:
            https://setuptools.pypa.io/en/latest/userguide/development_mode.html
            )	r"   LENIENTupper__members__r   OptionErrorwarningswarnr   )clsr&   _modemsg r2   `C:\Users\User\Downloads\Proyecto_IoT\venv\Lib\site-packages\setuptools/command/editable_wheel.pyconvertG   s   
	z_EditableMode.convertN)__name__
__module____qualname____doc__STRICTr)   r(   classmethodr   strr4   r2   r2   r2   r3   r"   ;   s    r"   zU
New or renamed files may not be automatically picked up without a new installation.
zt
Options like `package-data`, `include/exclude-package-data` or
`packages.find.exclude/include` may have no effect.
c                   @   s$  e Zd ZdZdZddddeejpdfgZdd	 Zd
d Z	dd Z
dd Zdd Zdee fddZdedededefddZdd Zdeee eeef f fddZdededededeee eeef f f
d d!Zd"d# Zd$efd%d&Zd'd( Zd)efd*d+Zded,ededd-fd.d/ZdS )0editable_wheelzkBuild 'editable' wheel for development.
    (This command is reserved for internal use of setuptools).
    z!create a PEP 660 'editable' wheel)z	dist-dir=dz-directory to put final built distributions in)zdist-info-dir=Iz(path to a pre-build .dist-info directoryzmode=N c                 C   s   d | _ d | _d | _d | _d S N)dist_dirdist_info_dirproject_dirr&   selfr2   r2   r3   initialize_optionsv   s   
z!editable_wheel.initialize_optionsc                 C   s@   | j }|jptj| _|jpi | _t| jptj	| jd| _d S )Ndist)
distributionsrc_rootoscurdirrC   package_dirr   rA   pathjoin)rE   rG   r2   r2   r3   finalize_options|   s    zeditable_wheel.finalize_optionsc              
   C   s|   z#| j jdd |   | d | d}|| j | | W d S  ty= } zt	
  d}tt||d }~ww )NT)exist_okbdist_wheela  
            Support for editable installs via PEP 660 was recently introduced
            in `setuptools`. If you are seeing this error, please report to:

            https://github.com/pypa/setuptools/issues

            Meanwhile you can try the legacy behavior by setting an
            environment variable and trying to install again:

            SETUPTOOLS_ENABLE_FEATURES="legacy-editable"
            )rA   mkdir_ensure_dist_inforeinitialize_commandget_finalized_commandZwrite_wheelfilerB   _create_wheel_file	Exception	traceback	print_excr   ZInternalErrorr   )rE   rQ   exr1   r2   r2   r3   run   s   

zeditable_wheel.runc                 C   sd   | j d u r| d}| j|_|  |  |j | _ d S t| j ds&J t| j d	 s0J d S )N	dist_infoz
.dist-infoMETADATA)
rB   rT   rA   
output_dirensure_finalizedr[   r;   endswithr   exists)rE   r\   r2   r2   r3   rS      s   

z editable_wheel._ensure_dist_infoc                 C   sD   | j }|jsd S t| j| jdd }t||||}|  d S )Nr?   .)	rH   namespace_packagesr   rC   rL   getresolve_NamespaceInstallerZinstall_namespaces)rE   installation_dirZ
pth_prefixrG   rI   	installerr2   r2   r3   _install_namespaces   s   z"editable_wheel._install_namespacesr'   c                 C   s2   | j r	t| j jnt }tt|d}t|d S )Nz
*.egg-info)rB   r   parentmapr;   globnext)rE   
parent_dir
candidatesr2   r2   r3   _find_egg_info_dir   s   
z!editable_wheel._find_egg_info_dirnameunpacked_wheel	build_libtmp_dirc                 C   s  | j }t|}t|}tt|| dd}tt|| dd}tt|| dd}	|jddd}
t||
_d|
_|jddd}|jd	dd}| |_ |_|_| |_	 |_
|_|	 |_|_||_||_|d
}d|_t||_|d}d|_|  |_|   |  |  dS )a  Configure commands to behave in the following ways:

        - Build commands can write to ``build_lib`` if they really want to...
          (but this folder is expected to be ignored and modules are expected to live
          in the project directory...)
        - Binary extensions should be built in-place (editable_mode = True)
        - Data/header/script files are not part of the "editable" specification
          so they are written directly to the unpacked_wheel directory.
        z.datadataheadersscriptsegg_infoT)Zreinit_subcommandsbuildinstallinstall_scriptsr   FN)rH   r;   r   rT   Zegg_baseZignore_egg_info_in_manifestZbuild_platlibZbuild_purelibrs   Zinstall_purelibZinstall_platlibZinstall_libr{   Zbuild_scriptsZinstall_headersZinstall_dataget_command_objZno_epZ
build_tempcompilerp   Zexisting_egg_info_dir_set_editable_moder_   )rE   rq   rr   rs   rt   rG   wheelru   rv   rw   rx   ry   rz   r{   r   r2   r2   r3   _configure_build   s2   




zeditable_wheel._configure_buildc                 C   sN   | j }|d}| D ]}||}t|drd|_qt|dr$d|_qdS )z8Set the ``editable_mode`` flag in the build sub-commandsry   editable_modeTinplaceN)rH   r|   get_sub_commandshasattrr   r   )rE   rG   ry   cmd_namecmdr2   r2   r3   r~      s   



z!editable_wheel._set_editable_modec                 C   sj   g }i }|  d}| D ]#}|  |}t|dr"|| p g  t|dr0|| p.i  q||fS )Nry   get_outputsget_output_mapping)rU   r   r   extendr   updater   )rE   filesmappingry   r   r   r2   r2   r3   _collect_build_outputs   s   



z%editable_wheel._collect_build_outputs	dist_namec                 C   sJ   |  |||| |   |  \}}| d | d | d ||fS )Nrv   rw   ru   )r   _run_build_subcommandsr   _run_install)rE   r   rr   rs   rt   r   r   r2   r2   r3   _run_build_commands  s   


z"editable_wheel._run_build_commandsc                 C   sP   |  d}| D ]}|  |}|dkr t|tkr | | q	| | q	dS )a}  
        Issue #3501 indicates that some plugins/customizations might rely on:

        1. ``build_py`` not running
        2. ``build_py`` always copying files to ``build_lib``

        However both these assumptions may be false in editable_wheel.
        This method implements a temporary workaround to support the ecosystem
        while the implementations catch up.
        ry   r   N)rU   r   typebuild_py_cls_safely_runrun_command)rE   ry   rq   r   r2   r2   r3   r     s   

z%editable_wheel._run_build_subcommandsr   c              	   C   sL   z|  |W S  ty%   t  d| d| d}tj|tdd Y d S w )Nz

            If you are seeing this warning it is very likely that a setuptools
            plugin or customization overrides the `z` command, without
            taking into consideration how editable installs run build steps
            starting from v64.0.0.

            Plugin authors and developers relying on custom build steps are encouraged
            to update their `aO  ` implementation considering the information in
            https://setuptools.pypa.io/en/latest/userguide/extension.html
            about editable installs.

            For the time being `setuptools` will silence this error and ignore
            the faulty command, but this behaviour will change in future versions.

               )
stacklevel)r   rW   rX   
format_excr-   r.   r   )rE   r   r1   r2   r2   r3   r   "  s   
zeditable_wheel._safely_runc                 C   s  ddl m} | d}|j}d| }d}| d| d| d}t| j|}| r0|	  t
|d}	t
dd}
t
d	d}|	}|
t}|b}t|t| jj}t| j| | ||j | ||||\}}| |||}|( ||d
}|||| || W d    n1 sw   Y  W d    n1 sw   Y  W d    n1 sw   Y  W d    n1 sw   Y  W d    |S W d    |S 1 sw   Y  |S )Nr   r   r\   -z
0.editablez.whl)suffixz
.build-libz.build-tempw)wheel.wheelfiler   rU   rq   rN   Zget_tagr   rA   ra   unlinkr   rB   shutilcopytreeri   r   _select_strategyZwrite_files)rE   rQ   r   r\   r   tag	build_tagarchive_name
wheel_pathrr   rs   Z	build_tmpunpackedlibtmpZunpacked_dist_infor   r   ZstrategyZ	wheel_objr2   r2   r3   rV   6  sB   



 ( 


z!editable_wheel._create_wheel_filecategoryc                 C   sL   t | jd| d }|r"| r$td| d | d|  d S d S d S )NZhas_zInstalling z as non editableZinstall_)getattrrH   _loggerinfor   )rE   r   Zhas_categoryr2   r2   r3   r   R  s
   
zeditable_wheel._run_installr   EditableStrategyc                 C   s   d| d| }t | j}t| j}|tju r)tt | jd|}t| j|||S t	| j}t
|| j|}	|tju }
t| jdhkrD|	sF|
rX| jdd}t| j|t ||gS t| j|S )zDDecides which strategy to use to implement an editable installation.__editable__.r   ry   r?   rb   )r   rC   r"   r4   r&   r9   
_empty_dir	_LinkTreerH   _find_packages_simple_layoutrL   r(   setrd   
_StaticPth_TopLevelFinder)rE   rq   r   rs   Z
build_namerC   r&   auxiliary_dirpackagesZhas_simple_layoutZis_compat_modesrc_dirr2   r2   r3   r   X  s   



zeditable_wheel._select_strategy)r5   r6   r7   r8   descriptionr   r"   Zuser_optionsrF   rO   r[   rS   ri   r   r;   rp   _Pathr   r~   r   r   r	   r   r   r   r   rV   r   r   r2   r2   r2   r3   r<   i   s`    

2"
r<   c                   @   s>   e Zd Zdddee deeef fddZdd Zd	d
 ZdS )r   r   r   r   r   c                 C      d S r@   r2   rE   r   r   r   r2   r2   r3   __call__t     zEditableStrategy.__call__c                 C   r   r@   r2   rD   r2   r2   r3   	__enter__w  r   zEditableStrategy.__enter__c                 C   r   r@   r2   rE   	_exc_type
_exc_value
_tracebackr2   r2   r3   __exit__z  r   zEditableStrategy.__exit__N)	r5   r6   r7   r   r;   r	   r   r   r   r2   r2   r2   r3   r   s  s    "r   c                   @   sX   e Zd Zdededee fddZdddee d	eeef fd
dZ	dd Z
dd ZdS )r   rG   rq   path_entriesc                 C   s   || _ || _|| _d S r@   )rG   rq   r   )rE   rG   rq   r   r2   r2   r3   __init__  s   
z_StaticPth.__init__r   r   r   r   c                 C   s@   d dd | jD }t| dd}|d| j d| d S )N
c                 s   s    | ]	}t | V  qd S r@   )r;   re   ).0pr2   r2   r3   	<genexpr>      z&_StaticPth.__call__.<locals>.<genexpr>utf-8r   .pth)rN   r   byteswritestrrq   )rE   r   r   r   entriescontentsr2   r2   r3   r     s   z_StaticPth.__call__c                 C   s,   dt ttj| jd}t|t  | S )Nz_
        Editable install will be performed using .pth file to extend `sys.path` with:
        z	
        )listrk   rJ   fspathr   r   warning_LENIENT_WARNINGrE   r1   r2   r2   r3   r     s
   z_StaticPth.__enter__c                 C   r   r@   r2   r   r2   r2   r3   r     r   z_StaticPth.__exit__N)r5   r6   r7   r   r;   r   r   r   r	   r   r   r   r2   r2   r2   r3   r   ~  s
    "r   c                       s   e Zd ZdZdedededef fddZdd	d
ee de	eef f fddZ
dedee fddZddedefddZdd Zdd Zdd Z  ZS )r   a`  
    Creates a ``.pth`` file that points to a link tree in the ``auxiliary_dir``.

    This strategy will only link files (not dirs), so it can be implemented in
    any OS, even if that means using hardlinks instead of symlinks.

    By collocating ``auxiliary_dir`` and the original source code, limitations
    with hardlinks should be avoided.
    rG   rq   r   rs   c                    s>   t || _t | | _|dj| _t ||| jg d S )Nr   )	r   r   re   rs   r|   	copy_file_filesuperr   )rE   rG   rq   r   rs   	__class__r2   r3   r     s   
z_LinkTree.__init__r   r   r   r   c                    s    |  || t ||| d S r@   )_create_linksr   r   r   r   r2   r3   r     s   z_LinkTree.__call__filer'   c                 C   sR   t t t| | j}t|tj	dW  d    S 1 s"w   Y  d S )N/)
r   
ValueErrorr   re   relative_tors   r;   replacerJ   sep)rE   r   rM   r2   r2   r3   _normalize_output  s
   
 z_LinkTree._normalize_outputNrelative_outputsrc_filec                 C   s6   | j | }|j s|jjdd | j|||d d S )NT)parentslink)r   rj   is_dirrR   r   )rE   r   r   r   destr2   r2   r3   _create_file  s   

z_LinkTree._create_filec                    s    j jddd t j rdnd} fdd| D }|d d  |D ]} |}|r7||vr7 || q$| D ]\}} j|||d q<d S )NT)r   rP   symZhardc                    s   i | ]
\}}  ||qS r2   )r   r   kvrD   r2   r3   
<dictcomp>  s    
z+_LinkTree._create_links.<locals>.<dictcomp>r   )r   rR   _can_symlink_filesitemspopr   r   )rE   outputsZoutput_mappingZ	link_typeZmappingsoutputZrelativesrcr2   rD   r3   r     s   

z_LinkTree._create_linksc                 C      d}t |t  | S )Nz=Strict editable install will be performed using a link tree.
)r   r   _STRICT_WARNINGr   r2   r2   r3   r        z_LinkTree.__enter__c                 C   s   d| j  d}t|t d S )Nz\

        Strict editable installation performed using the auxiliary directory:
            z

        Please be careful to not remove this directory, otherwise you might not be able
        to import/use your package.
        )r   r-   r.   InformationOnlyrE   r   r   r   r1   r2   r2   r3   r     s   z_LinkTree.__exit__r@   )r5   r6   r7   r8   r   r;   r   r   r   r	   r   r   r   r   r   r   r   __classcell__r2   r2   r   r3   r     s"    	&r   c                   @   sP   e Zd ZdedefddZdddee deeef fd	d
Zdd Z	dd Z
dS )r   rG   rq   c                 C   s   || _ || _d S r@   )rG   rq   )rE   rG   rq   r2   r2   r3   r     s   
z_TopLevelFinder.__init__r   r   r   r   c                 C   s   | j jptj}tt| j t| j }| j jpi }t|||}t	tt
| j jp&g |dd t|D }d| j d}	t|	}
tt|	||d}||
 d| td|
 d|
 d	d}|d| j d
| d S )Nc                 s   s    | ]}|g fV  qd S r@   r2   )r   nsr2   r2   r3   r     s    z+_TopLevelFinder.__call__.<locals>.<genexpr>r   z.finderr   z.pyzimport z; z
.install()r   )rG   rI   rJ   rK   r   r   _find_top_level_modulesrL   _find_package_rootsdict_find_namespacesr   _find_virtual_namespacesrq   _make_identifierr   _finder_templater   )rE   r   r   r   rI   Z	top_levelrL   rootsZnamespaces_rq   findercontentr2   r2   r3   r     s   z_TopLevelFinder.__call__c                 C   r   )Nz=Editable install will be performed using a meta path finder.
)r   r   r   r   r2   r2   r3   r     r   z_TopLevelFinder.__enter__c                 C   s   d}t |t d S )Nz

        Please be careful with folders in your working directory with the same
        name as your package as they may take precedence during imports.
        )r-   r.   r   r   r2   r2   r3   r     s   z_TopLevelFinder.__exit__N)r5   r6   r7   r   r;   r   r   r	   r   r   r   r2   r2   r2   r3   r     s
    "r   base_dirr'   c                 C   s  t t|  do}t|dt|d}}|jddd tttt) t	
|| | rD|jdddkrD	 W d    W d    dS W d    n1 sNw   Y  zt	|| W n tyn } zd}t||d }~ww 	 W d    d	S 1 s{w   Y  d S )
N)dirz	file1.txtz	file2.txtZfile1r   )encodingTzFile system does not seem to support either symlinks or hard links. Strict editable installs require one of them to be supported.F)r   r;   re   r   
write_textr   AttributeErrorNotImplementedErrorOSErrorrJ   symlink
is_symlink	read_textr   rW   LinksNotSupported)r  r   Zpath1Zpath2rZ   r1   r2   r2   r3   r     s*   
$r   r   rL   rC   c                    s^    fdd| D }|st  i dhfv S tjdd | D tfdd| D S )a[  Return ``True`` if:
    - all packages are contained by the same parent directory, **and**
    - all packages become importable if the parent directory is added to ``sys.path``.

    >>> _simple_layout(['a'], {"": "src"}, "/tmp/myproj")
    True
    >>> _simple_layout(['a', 'a.b'], {"": "src"}, "/tmp/myproj")
    True
    >>> _simple_layout(['a', 'a.b'], {}, "/tmp/myproj")
    True
    >>> _simple_layout(['a', 'a.a1', 'a.a1.a2', 'b'], {"": "src"}, "/tmp/myproj")
    True
    >>> _simple_layout(['a', 'a.a1', 'a.a1.a2', 'b'], {"a": "a", "b": "b"}, ".")
    True
    >>> _simple_layout(['a', 'a.a1', 'a.a1.a2', 'b'], {"a": "_a", "b": "_b"}, ".")
    False
    >>> _simple_layout(['a', 'a.a1', 'a.a1.a2', 'b'], {"a": "_a"}, "/tmp/myproj")
    False
    >>> _simple_layout(['a', 'a.a1', 'a.a1.a2', 'b'], {"a.a1.a2": "_a2"}, ".")
    False
    >>> _simple_layout(['a', 'a.b'], {"": "src", "a.b": "_ab"}, "/tmp/myproj")
    False
    >>> # Special cases, no packages yet:
    >>> _simple_layout([], {"": "src"}, "/tmp/myproj")
    True
    >>> _simple_layout([], {"a": "_a", "": "src"}, "/tmp/myproj")
    False
    c                    s   i | ]	}|t | qS r2   r   r   pkg)rL   rC   r2   r3   r   4  s    z"_simple_layout.<locals>.<dictcomp>r?   c                 S   s   g | ]	\}}t ||qS r2   )_parent_pathr   r2   r2   r3   
<listcomp>:  s    z"_simple_layout.<locals>.<listcomp>c                 3   s6    | ]\}}t t g|d R  t |kV  qdS rb   N)_normalize_pathr   split)r   keyvalue)rj   r2   r3   r   ;  s
     
z!_simple_layout.<locals>.<genexpr>)r   rJ   rM   
commonpathr   all)r   rL   rC   Zlayoutr2   )rL   rj   rC   r3   r     s   r   c                 C   s0   | | r|dt|   n|}|dtj S )a7  Infer the parent path containing a package, that if added to ``sys.path`` would
    allow importing that package.
    When ``pkg`` is directly mapped into a directory with a different name, return its
    own path.
    >>> _parent_path("a", "src/a")
    'src'
    >>> _parent_path("b", "src/c")
    'src/c'
    Nr   )r`   lenrstriprJ   r   )r  pkg_pathrj   r2   r2   r3   r  A  s    
r  rG   c                 c   s~    t | jpg E d H  | jpg }dd |D }| jr| jV  n| jp#g }|dd |D 7 }|D ]}|d\}}}|V  q/d S )Nc                 S   s   g | ]}d |v r|qS rb   r2   r   modr2   r2   r3   r  S  s    z"_find_packages.<locals>.<listcomp>c                 S   s   g | ]
}d |j v r|j qS r   rq   r   xr2   r2   r3   r  X  s    rb   )iterr   
py_modulesext_packageext_modules
rpartition)rG   r'  Znested_modulesr)  modulepackage_r2   r2   r3   r   O  s   


r   c                 c   sL    | j pg }dd |D E d H  | js$| jpg }dd |D E d H  d S d S )Nc                 s   s    | ]	}d |vr|V  qdS r  r2   r!  r2   r2   r3   r   a  r   z*_find_top_level_modules.<locals>.<genexpr>c                 s   s     | ]}d |j vr|j V  qdS r  r#  r$  r2   r2   r3   r   e  s    )r'  r(  r)  )rG   r'  r)  r2   r2   r3   r   _  s   

r   rI   c                    s     fddt | D }t|S )Nc                    s   i | ]}|t t| qS r2   )_absolute_rootr   r  rL   rI   r2   r3   r   m  s    z'_find_package_roots.<locals>.<dictcomp>)sorted_remove_nested)r   rL   rI   	pkg_rootsr2   r/  r3   r   h  s   r   rM   c                 C   s4   t | }|j}| rt| S t| |j S )z(Works for packages and top-level modules)r   rj   ra   r;   re   rq   )rM   Zpath_rj   r2   r2   r3   r.  u  s
   r.  r2  c                 c   sv    | D ]5}d|vr
q| d}tt|d ddD ]}d|d| }tt|| d}| r4|| vr7|V  qqdS )a8  By carefully designing ``package_dir``, it is possible to implement the logical
    structure of PEP 420 in a package without the corresponding directories.

    Moreover a parent package can be purposefully/accidentally skipped in the discovery
    phase (e.g. ``find_packages(include=["mypkg.*"])``, when ``mypkg.foo`` is included
    by ``mypkg`` itself is not).
    We consider this case to also be a virtual namespace (ignoring the original
    directory) to emulate a non-editable installation.

    This function will try to find these kinds of namespaces.
    rb      r   Nr?   )r  ranger  rN   r   r   ra   )r2  r  partsiZpartial_namerM   r2   r2   r3   r    s   
r  c                 c   sB    | D ]}t ||d}t| rt|d s||gfV  qd S )Nr?   z__init__.py)r   r   ra   )r   r2  r  rM   r2   r2   r3   r     s   r   c                    sP   t |  }tt|  D ]\ t fdd|  D r%| q|S )Nc                 3   s*    | ]\}}|kot  ||V  qd S r@   )
_is_nested)r   other
other_pathrM   r  r2   r3   r     s
    
z!_remove_nested.<locals>.<genexpr>)r   copyreversedr   r   anyr   )r2  r   r2   r;  r3   r1    s   
r1  r  r  rj   parent_pathc                 C   sD   t |}| |dddd}| |o!|t t|g|R  kS )a  
    Return ``True`` if ``pkg`` is nested inside ``parent`` both logically and in the
    file system.
    >>> _is_nested("a.b", "path/a/b", "a", "path/a")
    True
    >>> _is_nested("a.b", "path/a/b", "a", "otherpath/a")
    False
    >>> _is_nested("a.b", "path/a/b", "c", "path/c")
    False
    >>> _is_nested("a.a", "path/a/a", "a", "path/a")
    True
    >>> _is_nested("b.a", "path/b/a", "a", "path/a")
    False
    r?   r3  rb   )r  r   stripr  
startswithr   )r  r  rj   r?  Znorm_pkg_pathrestr2   r2   r3   r8    s
   
r8  filenamec                 C   s6   t jdkrtj| n| }tjtjtj|S )z1Normalize a file/dir name for comparison purposescygwin)sysplatformrJ   rM   abspathnormcaserealpathnormpath)rC  r   r2   r2   r3   r    s   r  dir_c                 C   s   t j| dd t|  | S )zFCreate a directory ensured to be empty. Existing files may be removed.T)ignore_errors)r   rmtreerJ   makedirs)rK  r2   r2   r3   r     s   
r   rq   c                 C   s   t dd| }| sJ |S )zMake a string safe to be used as Python identifier.
    >>> _make_identifier("12abc")
    '_12abc'
    >>> _make_identifier("__editable__.myns.pkg-78.9.3_local")
    '__editable___myns_pkg_78_9_3_local'
    z
\W|^(?=\d)r-  )resubisidentifier)rq   safer2   r2   r3   r    s   r  c                   @   s$   e Zd Zdd Zdd Zdd ZdS )rf   c                 C   s(   || _ || _|| _|| _g | _d| _d S )NF)rH   rI   rg   editable_namer   dry_run)rE   rH   rg   rS  rI   r2   r2   r3   r     s   
z_NamespaceInstaller.__init__c                 C   s   t j| j| jS )zInstallation target.)rJ   rM   rN   rg   rS  rD   r2   r2   r3   _get_target  s   z_NamespaceInstaller._get_targetc                 C   s   t t| jS )z1Where the modules/packages should be loaded from.)reprr;   rI   rD   r2   r2   r3   	_get_root  s   z_NamespaceInstaller._get_rootN)r5   r6   r7   r   rU  rW  r2   r2   r2   r3   rf     s    rf   a<	  import sys
from importlib.machinery import ModuleSpec
from importlib.machinery import all_suffixes as module_suffixes
from importlib.util import spec_from_file_location
from itertools import chain
from pathlib import Path

MAPPING = {mapping!r}
NAMESPACES = {namespaces!r}
PATH_PLACEHOLDER = {name!r} + ".__path_hook__"


class _EditableFinder:  # MetaPathFinder
    @classmethod
    def find_spec(cls, fullname, path=None, target=None):
        for pkg, pkg_path in reversed(list(MAPPING.items())):
            if fullname == pkg or fullname.startswith(f"{{pkg}}."):
                rest = fullname.replace(pkg, "", 1).strip(".").split(".")
                return cls._find_spec(fullname, Path(pkg_path, *rest))

        return None

    @classmethod
    def _find_spec(cls, fullname, candidate_path):
        init = candidate_path / "__init__.py"
        candidates = (candidate_path.with_suffix(x) for x in module_suffixes())
        for candidate in chain([init], candidates):
            if candidate.exists():
                return spec_from_file_location(fullname, candidate)


class _EditableNamespaceFinder:  # PathEntryFinder
    @classmethod
    def _path_hook(cls, path):
        if path == PATH_PLACEHOLDER:
            return cls
        raise ImportError

    @classmethod
    def _paths(cls, fullname):
        # Ensure __path__ is not empty for the spec to be considered a namespace.
        return NAMESPACES[fullname] or MAPPING.get(fullname) or [PATH_PLACEHOLDER]

    @classmethod
    def find_spec(cls, fullname, target=None):
        if fullname in NAMESPACES:
            spec = ModuleSpec(fullname, None, is_package=True)
            spec.submodule_search_locations = cls._paths(fullname)
            return spec
        return None

    @classmethod
    def find_module(cls, fullname):
        return None


def install():
    if not any(finder == _EditableFinder for finder in sys.meta_path):
        sys.meta_path.append(_EditableFinder)

    if not NAMESPACES:
        return

    if not any(hook == _EditableNamespaceFinder._path_hook for hook in sys.path_hooks):
        # PathEntryFinder is needed to create NamespaceSpec without private APIS
        sys.path_hooks.append(_EditableNamespaceFinder._path_hook)
    if PATH_PLACEHOLDER not in sys.path:
        sys.path.append(PATH_PLACEHOLDER)  # Used just to trigger the path hook
r   r   c                 C   s(   t t| dd d}tj| ||dS )z_Create a string containing the code for the``MetaPathFinder`` and
    ``PathEntryFinder``.
    c                 S   s   | d S )Nr   r2   )r   r2   r2   r3   <lambda>?  s    z"_finder_template.<locals>.<lambda>)r  rq   r   r   )r   r0  r   _FINDER_TEMPLATEformatrY  r2   r2   r3   r  9  s   r  c                   @      e Zd ZdZdS )r   zCurrently there is no clear way of displaying messages to the users
    that use the setuptools backend directly via ``pip``.
    The only thing that might work is a warning, although it is not the
    most appropriate tool for the job...
    Nr5   r6   r7   r8   r2   r2   r2   r3   r   C      r   c                   @   r\  )r  zCFile system does not seem to support either symlinks or hard links.Nr]  r2   r2   r2   r3   r  K  r^  r  )Wr8   loggingrJ   rO  r   rE  rX   r-   
contextlibr   enumr   inspectr   	itertoolsr   pathlibr   tempfiler   typingr   r	   r
   r   r   r   r   r   r   r   
setuptoolsr   r   r   r   Zsetuptools.command.build_pyr   r   Zsetuptools.discoveryr   Zsetuptools.distr   r   r   version_infor   Ztyping_extensionsabcr   r;   r   r    	getLoggerr5   r   r"   r   r   r<   r   r   r   r   boolr   r   r  r   r   r   r.  r  r   r1  r8  r  r   r  Z	Installerrf   rZ  r  UserWarningr   Z	FileErrorr  r2   r2   r2   r3   <module>   s    0

$  G%

,	




"	H


