o
    NZh                     @  s  d Z ddlm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	m
Z
mZ ddlmZ ddlmZ ddlmZ ddlmZ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 ddl m!Z!m"Z"m#Z#m$Z$m%Z%m&Z& ddl#m'Z' ddl(m)Z)m*Z* ddl+m,Z, ddl-m.Z. ddl/m0Z0m1Z1 ddl2m2Z3 ddl4m4Z5 ddl6m6Z7 ddl8m8Z9 ddl:m:Z; ddl<m<Z= erddl>m?Z? ddl@mAZA ede'dZBeCeDZEG dd  d eZFd!ZGd"ZHG d#d$ d$e!ZIG d%d& d&eZJG d'd( d(ZKG d)d* d*eKZLG d+d, d,ZMdmd1d2ZNdnd6d7ZOdod>d?ZPd@dA ZQdpdEdFZRdpdGdHZSdqdKdLZTdrdNdOZUdsdQdRZVdtdUdVZWdudWdXZXdvd]d^ZYdwd`daZZG dbdc dce&j[Z\ddZ]dxdidjZ^G dkdl dle%j_Z`d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``.
    )annotationsN)IterableIteratorMapping)suppress)Enum)cleandoc)chainstarmap)Path)TemporaryDirectory)TracebackType)TYPE_CHECKINGProtocolTypeVarcast   )Command_normalization_path_shutilerrors
namespaces)StrPath)py310py312find_package_path)Distribution)InformationOnlySetuptoolsDeprecationWarning   )build)build_py)	dist_info)egg_info)install)install_scripts)Self	WheelFile_P)boundc                   @  s*   e Zd ZdZdZdZdZed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
str | Nonereturnc                 C  sN   |st jS | }|t jvrtd|d|dkr#tjdddd t | S )NzInvalid editable mode: z. Try: 'strict'.COMPATzCompat editable installsa
  
                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.
                zuserguide/development_mode.html)Zsee_docs)r-   LENIENTupper__members__r   OptionErrorr    emit)clsr1   _mode r<   P/var/www/auris/lib/python3.10/site-packages/setuptools/command/editable_wheel.pyconvert@   s   
z_EditableMode.convertN)r1   r2   r3   r-   )	__name__
__module____qualname____doc__STRICTr5   r4   classmethodr>   r<   r<   r<   r=   r-   4   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d5ddZ	d5ddZ
dd Zdd Zd6ddZd7ddZdd  Zd8d"d#Zd9d%d&Zd5d'd(Zd:d*d+Zd,d- Zd;d/d0Zd<d3d4ZdS )=editable_wheelzBuild 'editable' wheel for development.
    This command is private and reserved for internal use of setuptools,
    users should rely on ``setuptools.build_meta`` APIs.
    zBDO NOT CALL DIRECTLY, INTERNAL ONLY: create 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_dirr1   selfr<   r<   r=   initialize_optionsu   s   
z!editable_wheel.initialize_optionsr3   Nonec                 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curdirrL   package_dirr   rJ   pathjoin)rN   rQ   r<   r<   r=   finalize_options{   s    zeditable_wheel.finalize_optionsc              
   C  s   z#| j jdd |   | d | d}|| j | | W d S  tyC } z| j	j
p3| j	 }t|d| d  d }~ww )NT)exist_okbdist_wheelz3An error occurred when building editable wheel for zl.
See debugging tips in: https://setuptools.pypa.io/en/latest/userguide/development_mode.html#debugging-tips)rJ   mkdir_ensure_dist_inforeinitialize_commandget_finalized_commandZwrite_wheelfilerK   _create_wheel_file	ExceptionrR   nameget_namer   Zadd_note)rN   r[   exprojectr<   r<   r=   run   s    


zeditable_wheel.runc                 C  sj   | j d u rtt| d}| j|_|  |  |j | _ d S t| j 	ds)J t
| j d s3J d S )Nr$   z
.dist-infoMETADATA)rK   r   dist_info_clsr^   rJ   
output_dirensure_finalizedrf   strendswithr   exists)rN   r$   r<   r<   r=   r]      s   
z editable_wheel._ensure_dist_infoc                 C  sD   | j }|jsd S t| j| jdd }t||||}|  d S )NrH   .)	rR   namespace_packagesr   rL   rV   getresolve_NamespaceInstallerZinstall_namespaces)rN   installation_dirZ
pth_prefixrQ   rS   	installerr<   r<   r=   _install_namespaces   s   z"editable_wheel._install_namespacesr2   c                 C  s2   | j r	t| j jnt }tt|d}t|d S )Nz
*.egg-info)rK   r   parentmaprk   globnext)rN   
parent_dir
candidatesr<   r<   r=   _find_egg_info_dir   s   
z!editable_wheel._find_egg_info_dirrb   rk   unpacked_wheelr   	build_libtmp_dirc                 C  sL  | j }t|}t|}tt|| dd}tt|| dd}tt|| dd}	tt|jddd}
t||
_d|
_tt|jddd}tt	|jd	dd}| |_
 |_|_| |_ |_|_|	 |_|_||_||_|d
}d|_tt|d}d|_t||_t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scriptsr%   T)Zreinit_subcommandsr"   r&   build_scriptspythonr'   r#   FN)rR   rk   r   r   egg_info_clsr^   Zegg_baseZignore_egg_info_in_manifest	build_clsinstall_clsZbuild_platlibZbuild_purelibr~   Zinstall_purelibZinstall_platlibZinstall_libr'   r   Zinstall_headersZinstall_dataget_command_obj
executableinstall_scripts_clsZno_epZ
build_tempbuild_py_clscompiler|   Zexisting_egg_info_dir_set_editable_moderj   )rN   rb   r}   r~   r   rQ   wheelr   r   r   r%   r"   r&   r   r'   r#   r<   r<   r=   _configure_build   sF   




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-commandsr"   editable_modeTinplaceN)rR   r   get_sub_commandshasattrr   r   )rN   rQ   r"   cmd_namecmdr<   r<   r=   r      s   



z!editable_wheel._set_editable_mode tuple[list[str], dict[str, str]]c                 C  sj   g }i }|  d}| D ]#}|  |}t|dr"|| p g  t|dr0|| p.i  q||fS )Nr"   get_outputsget_output_mapping)r_   r   r   extendr   updater   )rN   filesmappingr"   r   r   r<   r<   r=   _collect_build_outputs   s   



z%editable_wheel._collect_build_outputs	dist_namec                 C  sJ   |  |||| |   |  \}}| d | d | d ||fS )Nr   r   r   )r   _run_build_subcommandsr   _run_install)rN   r   r}   r~   r   r   r   r<   r<   r=   _run_build_commands  s   


z"editable_wheel._run_build_commandsc                 C  sP   |  d}| D ]}|  |}|dkr t|tu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.
        r"   r#   N)r_   r   typer   _safely_runrun_command)rN   r"   rb   r   r<   r<   r=   r     s   

z%editable_wheel._run_build_subcommandsr   c                 C  sF   z|  |W S  ty"   tddt  d| d| d Y d S w )Nz0Customization incompatible with editable installz
                z

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

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

                For the time being `setuptools` will silence this error and ignore
                the faulty command, but this behavior will change in future versions.
                )r   ra   r    r9   	traceback
format_exc)rN   r   r<   r<   r=   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}|	}|
s}|a}t|t| jj}t| 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)Zwheel.wheelfiler*   r_   rb   rX   Zget_tagr   rJ   rm   unlinkr   rK   shutilcopytreeru   r   _select_strategyZwrite_files)rN   r[   r*   r$   r   tag	build_tagarchive_name
wheel_pathr}   r~   Z	build_tmpunpackedlibtmpZunpacked_dist_infor   r   ZstrategyZ	wheel_objr<   r<   r=   r`   I  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_)getattrrR   _loggerinfor   )rN   r   Zhas_categoryr<   r<   r=   r   e  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   r"   rH   rn   )r   rL   r-   r>   r1   rC   
_empty_dir	_LinkTreerR   _find_packages_simple_layoutrV   r4   setrp   
_StaticPth_TopLevelFinder)rN   rb   r   r~   Z
build_namerL   r1   auxiliary_dirpackagesZhas_simple_layoutZis_compat_modesrc_dirr<   r<   r=   r   k  s   



zeditable_wheel._select_strategyr3   rP   )r3   r2   )rb   rk   r}   r   r~   r   r   r   )r3   r   )
r   rk   r}   r   r~   r   r   r   r3   r   )r   rk   )r   rk   )rb   rk   r   rk   r~   r   r3   r   )r?   r@   rA   rB   descriptionr   r-   Zuser_optionsrO   rY   rf   r]   ru   r|   r   r   r   r   r   r   r`   r   r   r<   r<   r<   r=   rE   g   s,    




?




rE   c                   @  s*   e Zd Zdd	d
ZdddZdddZdS )r   r   r*   r   	list[str]r   Mapping[str, str]r3   objectc                 C     d S rI   r<   rN   r   r   r   r<   r<   r=   __call__  s   zEditableStrategy.__call__r(   c                 C  r   rI   r<   rM   r<   r<   r=   	__enter__  s    zEditableStrategy.__enter__	_exc_typetype[BaseException] | None
_exc_valueBaseException | None
_tracebackTracebackType | Nonec                 C  r   rI   r<   rN   r   r   r   r<   r<   r=   __exit__  s   zEditableStrategy.__exit__N)r   r*   r   r   r   r   r3   r   r3   r(   )r   r   r   r   r   r   r3   r   )r?   r@   rA   r   r   r   r<   r<   r<   r=   r     s    

r   c                   @  s4   e Zd Zdd	d
ZdddZdddZd ddZdS )!r   rQ   r   rb   rk   path_entries
list[Path]r3   rP   c                 C  s   || _ || _|| _d S rI   )rQ   rb   r   )rN   rQ   rb   r   r<   r<   r=   __init__  s   
z_StaticPth.__init__r   r*   r   r   r   r   c                 C  s>   d dd | jD }t| d}|d| j d| d S )N
c                 s  s    | ]	}t | V  qd S rI   )rk   rq   ).0pr<   r<   r=   	<genexpr>      z&_StaticPth.__call__.<locals>.<genexpr>r   .pth)rX   r   _encode_pthwritestrrb   )rN   r   r   r   entriescontentsr<   r<   r=   r     s   z_StaticPth.__call__r(   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	
        )listrw   rT   fspathr   r   warning_LENIENT_WARNINGrN   msgr<   r<   r=   r     s
   z_StaticPth.__enter__r   r   r   r   c                 C  r   rI   r<   r   r<   r<   r=   r     s   z_StaticPth.__exit__N)rQ   r   rb   rk   r   r   r3   rP   r   r*   r   r   r   r   r   r   r   r   r   r   r   r3   rP   )r?   r@   rA   r   r   r   r   r<   r<   r<   r=   r     s
    


r   c                      sd   e Zd ZdZd* fddZd+ fddZd,ddZd-d.ddZd/dd Zd0d"d#Z	d1d(d)Z
  ZS )2r   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.
    rQ   r   rb   rk   r   r   r~   r3   rP   c                   s>   t || _t | | _|dj| _t ||| jg d S )Nr#   )	r   r   rq   r~   r   	copy_file_filesuperr   )rN   rQ   rb   r   r~   	__class__r<   r=   r     s   
z_LinkTree.__init__r   r*   r   r   r   r   c                   s    |  || t ||| d S rI   )_create_linksr   r   r   r   r<   r=   r     s   z_LinkTree.__call__filer2   c                 C  sR   t t t| | j}t|tj	dW  d    S 1 s"w   Y  d S )N/)
r   
ValueErrorr   rq   relative_tor~   rk   replacerT   sep)rN   r   rW   r<   r<   r=   _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   rv   is_dirr\   r   )rN   r   r   r   destr<   r<   r=   _create_file  s   

z_LinkTree._create_fileoutput_mappingc           	        s    j jddd t j rdnd} fdd| D }dd |D }|D ]} |}|r8||vr8 || q%| D ]\}} j|||d	 q=d S )
NT)r   rZ   symZhardc                 3  s"    | ]\}}  ||fV  qd S rI   )r   r   kvrM   r<   r=   r     s     z*_LinkTree._create_links.<locals>.<genexpr>c                 S  s   i | ]\}}|d ur||qS rI   r<   r  r<   r<   r=   
<dictcomp>  s    z+_LinkTree._create_links.<locals>.<dictcomp>r   )r   r\   _can_symlink_filesitemsr   r   )	rN   outputsr  Z	link_typeZ
normalisedZmappingsoutputZrelativesrcr<   rM   r=   r     s   
z_LinkTree._create_linksr(   c                 C     d}t |t  | S )Nz=Strict editable install will be performed using a link tree.
)r   r   _STRICT_WARNINGr   r<   r<   r=   r        z_LinkTree.__enter__r   r   r   r   c                 C  s   d| j  d}td| 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.
        Editable installation.)r   r   r9   rN   r   r   r   r   r<   r<   r=   r     s   z_LinkTree.__exit__)
rQ   r   rb   rk   r   r   r~   r   r3   rP   r   )r   rk   r3   r2   rI   )r   rk   r   rk   )r  r   r   r   )r?   r@   rA   rB   r   r   r   r   r   r   r   __classcell__r<   r<   r   r=   r     s    



r   c                   @  sH   e Z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 S )'r   rQ   r   rb   rk   r3   rP   c                 C  s   || _ || _d S rI   )rQ   rb   )rN   rQ   rb   r<   r<   r=   r     s   
z_TopLevelFinder.__init__5tuple[str, str, dict[str, str], dict[str, list[str]]]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 } fddj jp>g D }i  |}dj d}t|}||||fS )Nc                 s  s    | ]}|g fV  qd S rI   r<   )r   nsr<   r<   r=   r   	  s    z0_TopLevelFinder.template_vars.<locals>.<genexpr>c                   s"   i | ]}|t | jjpd qS )rH   )r   rQ   rS   r   pkgrootsrN   r<   r=   r    s    z1_TopLevelFinder.template_vars.<locals>.<dictcomp>r   z.finder)rQ   rS   rT   rU   r	   r   _find_top_level_modulesrV   _find_package_rootsdict_find_namespacesr   _find_virtual_namespacesro   rb   r   Zsafe_identifier)	rN   rS   Z	top_levelrV   namespaces_Zlegacy_namespacesr   rb   finderr<   r  r=   template_vars   s"   

z_TopLevelFinder.template_varsIterator[tuple[str, bytes]]c                 c  sb    |   \}}}}tt|||d}| d|fV  td| d| d}d| j d|fV  d S )Nutf-8z.pyzimport z; z
.install()r   r   )r  bytes_finder_templater   rb   )rN   r  rb   r   r  contentr<   r<   r=   get_implementation  s   z"_TopLevelFinder.get_implementationr   r*   r   r   r   r   c                 C  s"   |   D ]
\}}||| qd S rI   )r%  r   )rN   r   r   r   r   r$  r<   r<   r=   r   $  s   z_TopLevelFinder.__call__r(   c                 C  r  )Nz=Editable install will be performed using a meta path finder.
)r   r   r   r   r<   r<   r=   r   (  r  z_TopLevelFinder.__enter__r   r   r   r   c                 C  s   d}t d| 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   r9   r  r<   r<   r=   r   -  s   z_TopLevelFinder.__exit__N)rQ   r   rb   rk   r3   rP   )r3   r  )r3   r   r   r   r   )	r?   r@   rA   r   r  r%  r   r   r   r<   r<   r<   r=   r     s    



	
r   r$  rk   r3   r"  c                 C  s`   t  "}t j|tjd}||  |  |d | W  d   S 1 s)w   Y  dS )a  
    Prior to Python 3.13 (see https://github.com/python/cpython/issues/77102),
    .pth files are always read with 'locale' encoding, the recommendation
    from the cpython core developers is to write them as ``open(path, "w")``
    and ignore warnings (see python/cpython#77102, pypa/setuptools#3937).
    This function tries to simulate this behavior without having to create an
    actual file, in a way that supports a range of active Python versions.
    (There seems to be some variety in the way different version of Python handle
    ``encoding=None``, not all of them use ``locale.getpreferredencoding(False)``
    or ``locale.getencoding()``).
    encodingr   N)	ioBytesIOTextIOWrapperr   ZPTH_ENCODINGwriteflushseekread)r$  bufferwrapperr<   r<   r=   r   :  s   


$r   base_dirr   boolc                 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!  r&  TzFile system does not seem to support either symlinks or hard links. Strict editable installs require one of them to be supported.F)r   rk   rq   r   
write_textr   AttributeErrorNotImplementedErrorOSErrorrT   symlink
is_symlink	read_textr   ra   LinksNotSupported)r1  r   Zpath1Zpath2rd   r   r<   r<   r=   r  O  s*   
$r  r   Iterable[str]rV   dict[str, str]rL   r   c                   sZ    fdd| D }|st  i dhfv S tjtt| 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 r<   r   r  )rV   rL   r<   r=   r    s    z"_simple_layout.<locals>.<dictcomp>rH   c                 3  s2    | ]\}}t t g|d R  |V  qdS rn   N)r   Z	same_pathr   split)r   keyvalue)rv   r<   r=   r     s
    
z!_simple_layout.<locals>.<genexpr>)r   rT   rW   
commonpathr
   _parent_pathr  all)r   rV   rL   Zlayoutr<   )rV   rv   rL   r=   r   c  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   )rl   lenrstriprT   r   )r  pkg_pathrv   r<   r<   r=   rC    s    
rC  rQ   r   Iterator[str]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 rn   r<   r   modr<   r<   r=   
<listcomp>  s    z"_find_packages.<locals>.<listcomp>c                 S  s   g | ]
}d |j v r|j qS rI  rb   r   xr<   r<   r=   rL    s    rn   )iterr   
py_modulesext_packageext_modules
rpartition)rQ   rQ  Znested_modulesrS  modulepackage_r<   r<   r=   r     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>  r<   rJ  r<   r<   r=   r     r   z*_find_top_level_modules.<locals>.<genexpr>c                 s  s     | ]}d |j vr|j V  qdS r>  rM  rN  r<   r<   r=   r     s    )rQ  rR  rS  )rQ   rQ  rS  r<   r<   r=   r    s   

r  r   rS   c                   s     fddt | D }t|S )Nc                   s   i | ]}|t t| qS r<   )_absolute_rootr   r  rV   rS   r<   r=   r    s    z'_find_package_roots.<locals>.<dictcomp>)sorted_remove_nested)r   rV   rS   	pkg_rootsr<   rY  r=   r    s   r  rW   c                 C  s4   t | }|j}| rt| S t| |j S )z(Works for packages and top-level modules)r   rv   rm   rk   rq   rb   )rW   Zpath_rv   r<   r<   r=   rX    s
   rX  r\  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.
    rn   r!   r   NrH   )r?  rangerE  rX   r   r   rm   )r\  r  partsiZpartial_namerW   r<   r<   r=   r    s   
r  r   Iterator[tuple[str, list[str]]]c                 c  sB    | D ]}t ||d}t| rt|d s||gfV  qd S )NrH   z__init__.py)r   r   rm   )r   r\  r  rW   r<   r<   r=   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 rI   )
_is_nested)r   other
other_pathrW   r  r<   r=   r     s
    
z!_remove_nested.<locals>.<genexpr>)r  copyreversedr   r  anypop)r\  r
  r<   re  r=   r[    s   
r[  r  rG  rv   parent_pathc                 C  sH   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
    rH   r!   rn   )r   normpathr   stripr?  
startswithr   )r  rG  rv   rj  Znorm_pkg_pathrestr<   r<   r=   rb    s
   
rb  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   rmtreerT   makedirs)ro  r<   r<   r=   r     s   
r   c                   @  s&   e Zd Zd
ddZdd Zdd Zd	S )rr   r3   rP   c                 C  s(   || _ || _|| _|| _g | _d| _d S )NF)rR   rS   rs   editable_namer	  dry_run)rN   rR   rs   rs  rS   r<   r<   r=   r     s   
z_NamespaceInstaller.__init__c                 C  s   t j| j| j| j S )zInstallation target.)rT   rW   rX   rs   rs  Z	nspkg_extrM   r<   r<   r=   _get_nspkg_file  s   z#_NamespaceInstaller._get_nspkg_filec                 C  s   t t| jS )z1Where the modules/packages should be loaded from.)reprrk   rS   rM   r<   r<   r=   	_get_root#  s   z_NamespaceInstaller._get_rootNr   )r?   r@   rA   r   ru  rw  r<   r<   r<   r=   rr     s    
rr   a  from __future__ import annotations
import sys
from importlib.machinery import ModuleSpec, PathFinder
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: dict[str, str] = {mapping!r}
NAMESPACES: dict[str, list[str]] = {namespaces!r}
PATH_PLACEHOLDER = {name!r} + ".__path_hook__"


class _EditableFinder:  # MetaPathFinder
    @classmethod
    def find_spec(cls, fullname: str, path=None, target=None) -> ModuleSpec | None:  # type: ignore
        # Top-level packages and modules (we know these exist in the FS)
        if fullname in MAPPING:
            pkg_path = MAPPING[fullname]
            return cls._find_spec(fullname, Path(pkg_path))

        # Handle immediate children modules (required for namespaces to work)
        # To avoid problems with case sensitivity in the file system we delegate
        # to the importlib.machinery implementation.
        parent, _, child = fullname.rpartition(".")
        if parent and parent in MAPPING:
            return PathFinder.find_spec(fullname, path=[MAPPING[parent]])

        # Other levels of nesting should be handled automatically by importlib
        # using the parent path.
        return None

    @classmethod
    def _find_spec(cls, fullname: str, candidate_path: Path) -> ModuleSpec | None:
        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)
        return None


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

    @classmethod
    def _paths(cls, fullname: str) -> list[str]:
        paths = NAMESPACES[fullname]
        if not paths and fullname in MAPPING:
            paths = [MAPPING[fullname]]
        # Always add placeholder, for 2 reasons:
        # 1. __path__ cannot be empty for the spec to be considered namespace.
        # 2. In the case of nested namespaces, we need to force
        #    import machinery to query _EditableNamespaceFinder again.
        return [*paths, PATH_PLACEHOLDER]

    @classmethod
    def find_spec(cls, fullname: str, target=None) -> ModuleSpec | None:  # type: ignore
        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) -> None:
        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
rb   r   r   dict[str, list[str]]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   r<   )r   r<   r<   r=   <lambda>  s    z"_finder_template.<locals>.<lambda>)r@  rb   r   r   )r  rZ  r  _FINDER_TEMPLATEformatrz  r<   r<   r=   r#    s   r#  c                   @  s   e Zd ZdZdS )r;  zCFile system does not seem to support either symlinks or hard links.N)r?   r@   rA   rB   r<   r<   r<   r=   r;    s    r;  )r$  rk   r3   r"  )r1  r   r3   r2  )r   r<  rV   r=  rL   r   r3   r2  )rQ   r   r3   rH  )r   r<  rV   r   rS   r   r3   r=  )rW   r   r3   rk   )r\  r=  r3   rH  )r   r   r\  r=  r3   ra  )r\  r=  r3   r=  )
r  rk   rG  rk   rv   rk   rj  rk   r3   r2  )ro  r+   r3   r+   )rb   rk   r   r   r   rx  r3   rk   )arB   
__future__r   r(  loggingrT   r   r   collections.abcr   r   r   
contextlibr   enumr   inspectr   	itertoolsr	   r
   pathlibr   tempfiler   typesr   typingr   r   r   r   rH   r   r   r   r   r   r   r   r0   r   r   Z	discoveryr   rQ   r   warningsr   r    r"   r   r#   r   r$   rh   r%   r   r&   r   r'   r   Ztyping_extensionsr(   Z_vendor.wheel.wheelfiler*   r+   	getLoggerr?   r   r-   r  r   rE   r   r   r   r   r   r  r   rC  r   r  r  rX  r  r  r[  rb  r   Z	Installerrr   r{  r#  Z	FileErrorr;  r<   r<   r<   r=   <module>   sx     
)  !L
?

)


	



	


Y
