o
    5‘ði.ˆ  ã                   @  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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l0m1Z1m2Z2 ddl3m3Z4 ddl5m5Z6 ddl7m7Z8 ddl9m9Z: ddl;m;Z< ddl=m=Z> erÆddl?m@Z@ ddlAmBZB ede(d�ZCe DeE¡ZFG dd „ d eƒZGd!ZHd"ZIG d#d$„ d$e"ƒZJG d%d&„ d&eƒZKG d'd(„ d(ƒZLG d)d*„ d*eLƒZMG d+d,„ d,ƒZNdmd1d2„ZOdnd6d7„ZPdod>d?„ZQd@dA„ ZRdpdEdF„ZSdpdGdH„ZTdqdKdL„ZUdrdNdO„ZVdsdQdR„ZWdtdUdV„ZXdudWdX„ZYdvd]d^„ZZdwd`da„Z[G dbdc„ dce'j\ƒZ]ddZ^dxdidj„Z_G dkdl„ dle&j`ƒZad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)Úsee_docs)r-   ÚLENIENTÚupperÚ__members__r   ÚOptionErrorr    Úemit)Úclsr1   Ú_mode© r=   ú`/root/parts/websockify/install/lib/python3.10/site-packages/setuptools/command/editable_wheel.pyÚconvertA   s   
øz_EditableMode.convertN)r1   r2   r3   r-   )	Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚSTRICTr6   r4   Úclassmethodr?   r=   r=   r=   r>   r-   5   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_wheelz®Build '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_optionsv   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ÚcurdirrM   Úpackage_dirr   rK   ÚpathÚjoin)rO   rR   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)rK   ÚmkdirÚ_ensure_dist_infoÚreinitialize_commandÚget_finalized_commandÚwrite_wheelfilerL   Ú_create_wheel_fileÚ	ExceptionrS   ÚnameÚget_namer   Úadd_note)rO   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)rL   r   Údist_info_clsr_   rK   Ú
output_dirÚensure_finalizedri   ÚstrÚendswithr   Úexists)rO   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 )NrI   Ú.)	rS   Únamespace_packagesr   rM   rW   ÚgetÚresolveÚ_NamespaceInstallerÚinstall_namespaces)rO   Úinstallation_dirÚ
pth_prefixrR   rT   Ú	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)rL   r   ÚparentÚmaprn   ÚglobÚnext)rO   Ú
parent_dirÚ
candidatesr=   r=   r>   Ú_find_egg_info_dir¬   s   
z!editable_wheel._find_egg_info_dirrd   rn   Ú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)Úreinit_subcommandsr"   r&   Úbuild_scriptsÚpythonr'   r#   FN)rS   rn   r   r   Úegg_info_clsr_   Úegg_baseÚignore_egg_info_in_manifestÚ	build_clsÚinstall_clsÚbuild_platlibÚbuild_purelibrƒ   Úinstall_purelibÚinstall_platlibÚinstall_libr'   r‰   Úinstall_headersÚinstall_dataÚget_command_objÚ
executableÚinstall_scripts_clsÚno_epÚ
build_tempÚbuild_py_clsÚcompiler�   Úexisting_egg_info_dirÚ_set_editable_moderm   )rO   rd   r‚   rƒ   r„   rR   Ú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)rS   r—   Úget_sub_commandsÚhasattrr¢   r£   )rO   rR   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ª   )rO   Ú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)rO   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)rO   r"   rd   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¶   rc   r    r:   Ú	tracebackÚ
format_exc)rO   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 s�w   Y  W d   ƒ n1 sœw   Y  W d   ƒ n1 s«w   Y  W d   ƒ n1 sºw   Y  W d   ƒ |S W d   ƒ |S 1 sÒw   Y  |S )Nr   r)   r$   ú-z
0.editablez.whl)Úsuffixz
.build-libz.build-tempÚw)Úwheel.wheelfiler*   r`   rd   rY   Úget_tagr   rK   rp   Úunlinkr   rL   ÚshutilÚcopytreerz   r³   Ú_select_strategyÚwrite_files)rO   r\   r*   r$   r°   ÚtagÚ	build_tagÚarchive_nameÚ
wheel_pathr‚   rƒ   Ú	build_tmpÚunpackedÚlibÚtmpÚunpacked_dist_infor­   r®   ÚstrategyÚ	wheel_objr=   r=   r>   rb   J  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 )NÚhas_zInstalling z as non editableÚinstall_)ÚgetattrrS   Ú_loggerÚinfor¶   )rO   rÎ   Úhas_categoryr=   r=   r>   r²   f  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"   rI   rq   )r   rM   r-   r?   r1   rD   Ú
_empty_dirÚ	_LinkTreerS   Ú_find_packagesÚ_simple_layoutrW   r4   Úsetrs   Ú
_StaticPthÚ_TopLevelFinder)rO   rd   rÃ   rƒ   Ú
build_namerM   r1   Úauxiliary_dirÚpackagesÚhas_simple_layoutÚis_compat_modeÚsrc_dirr=   r=   r>   rÁ   l  s   



zeditable_wheel._select_strategy©r3   rQ   )r3   r2   )rd   rn   r‚   r   rƒ   r   r„   r   )r3   r¨   )
r°   rn   r‚   r   rƒ   r   r„   r   r3   r¨   )r¦   rn   )rÎ   rn   )rd   rn   rÃ   rn   rƒ   r   r3   rÕ   )r@   rA   rB   rC   Údescriptionr   r-   Úuser_optionsrP   rZ   ri   r^   rz   r�   r¡   rŸ   r¯   r³   r±   rµ   rb   r²   rÁ   r=   r=   r=   r>   rF   h   s,    ý




?




rF   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 rJ   r=   ©rO   r    r­   r®   r=   r=   r>   Ú__call__ˆ  s   zEditableStrategy.__call__r(   c                 C  rê   rJ   r=   rN   r=   r=   r>   Ú	__enter__‹  s    zEditableStrategy.__enter__Ú	_exc_typeútype[BaseException] | NoneÚ
_exc_valueúBaseException | NoneÚ
_tracebackúTracebackType | Nonec                 C  rê   rJ   r=   ©rO   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@   rA   rB   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Ü   rR   r   rd   rn   Úpath_entriesú
list[Path]r3   rQ   c                 C  s   || _ || _|| _d S rJ   )rR   rd   r÷   )rO   rR   rd   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 rJ   )rn   rt   )Ú.0Úpr=   r=   r>   Ú	<genexpr>�  ó   € z&_StaticPth.__call__.<locals>.<genexpr>rÖ   ú.pth)rY   r÷   Ú_encode_pthÚwritestrrd   )rO   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	
        )Úlistr|   rU   Úfspathr÷   rÒ   ÚwarningÚ_LENIENT_WARNING©rO   Úmsgr=   r=   r>   rí   ¡  s
   þz_StaticPth.__enter__rî   ré   rð   rò   c                 C  rê   rJ   r=   rô   r=   r=   r>   rõ   ©  s   z_StaticPth.__exit__N)rR   r   rd   rn   r÷   rø   r3   rQ   ©r    r*   r­   rç   r®   rè   r3   rQ   rö   ©rî   ré   rð   ré   rò   ré   r3   rQ   )r@   rA   rB   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.
    rR   r   rd   rn   rß   r   rƒ   r3   rQ   c                   s>   t |ƒ| _t |ƒ ¡ | _| d¡j| _tƒ  ||| jg¡ d S )Nr#   )	r   rß   rt   rƒ   r—   Ú	copy_fileÚ_fileÚsuperrù   )rO   rR   rd   rß   rƒ   ©Ú	__class__r=   r>   rù   ½  s   
z_LinkTree.__init__r    r*   r­   rç   r®   rè   c                   s    |   ||¡ tƒ  |||¡ d S rJ   )Ú_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   rt   Úrelative_torƒ   rn   ÚreplacerU   Úsep)rO   r  rX   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ß   r{   Úis_dirr]   r  )rO   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  r[   ÚsymÚhardc                 3  s"   � | ]\}}ˆ   |¡|fV  qd S rJ   )r  ©rû   ÚkÚvrN   r=   r>   rý   ß  s   €  z*_LinkTree._create_links.<locals>.<genexpr>c                 S  s   i | ]\}}|d ur||“qS rJ   r=   r$  r=   r=   r>   Ú
<dictcomp>á  s    z+_LinkTree._create_links.<locals>.<dictcomp>r  )rß   r]   Ú_can_symlink_filesÚitemsr  r   )	rO   Úoutputsr!  Ú	link_typeÚ
normalisedÚmappingsÚoutputÚrelativeÚsrcr=   rN   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   r:   ©rO   rî   rð   rò   r	  r=   r=   r>   rõ   ð  s   þz_LinkTree.__exit__)
rR   r   rd   rn   rß   r   rƒ   r   r3   rQ   r
  )r  rn   r3   r2   rJ   )r  rn   r  rn   )r!  rè   rö   r  )r@   rA   rB   rC   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Ý   rR   r   rd   rn   r3   rQ   c                 C  s   || _ || _d S rJ   )rR   rd   )rO   rR   rd   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 rJ   r=   )rû   Únsr=   r=   r>   rý     s   € z0_TopLevelFinder.template_vars.<locals>.<genexpr>c                   s"   i | ]}|t |ˆ ˆjjpd ƒ“qS )rI   )r   rR   rT   ©rû   Úpkg©ÚrootsrO   r=   r>   r'    s    ÿÿz1_TopLevelFinder.template_vars.<locals>.<dictcomp>rÖ   z.finder)rR   rT   rU   rV   r	   rÙ   Ú_find_top_level_modulesrW   Ú_find_package_rootsÚdictÚ_find_namespacesrà   Ú_find_virtual_namespacesrr   rd   r   Úsafe_identifier)	rO   rT   Ú	top_levelrW   Únamespaces_Úlegacy_namespacesr®   rd   Ú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ÿ   )rG  ÚbytesÚ_finder_templater   rd   )rO   rF  rd   r®   rD  Úcontentr=   r=   r>   Úget_implementation   s   €z"_TopLevelFinder.get_implementationr    r*   r­   rç   r®   rè   c                 C  s"   |   ¡ D ]
\}}| ||¡ qd S rJ   )rM  r  )rO   r    r­   r®   r  rL  r=   r=   r>   rì   )  s   ÿz_TopLevelFinder.__call__r(   c                 C  r1  )Nz=Editable install will be performed using a meta path finder.
)rÒ   r  r  r  r=   r=   r>   rí   /  r3  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.
        r4  )r   r:   r5  r=   r=   r>   rõ   4  s   z_TopLevelFinder.__exit__N)rR   r   rd   rn   r3   rQ   )r3   r7  )r3   rH  r
  rö   r  )	r@   rA   rB   rù   rG  rM  rì   rí   rõ   r=   r=   r=   r>   rÝ      s    



	
rÝ   rL  rn   r3   rJ  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   ÚPTH_ENCODINGÚwriteÚflushÚseekÚread)rL  ÚbufferÚwrapperr=   r=   r>   r   A  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.txtÚfile1rI  rN  Tz�File system does not seem to support either symlinks or hard links. Strict editable installs require one of them to be supported.F)r   rn   rt   r   Ú
write_textr   ÚAttributeErrorÚNotImplementedErrorÚOSErrorrU   ÚsymlinkÚ
is_symlinkÚ	read_textr  rc   ÚLinksNotSupported)rZ  rÊ   Úpath1Úpath2rg   r	  r=   r=   r>   r(  V  s*   ýý€ÿ
€û$ðr(  rà   úIterable[str]rW   údict[str, str]rM   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   r9  )rW   rM   r=   r>   r'  ‰  s    z"_simple_layout.<locals>.<dictcomp>rI   c                 3  s2   � | ]\}}t  tˆ g| d ¡¢R Ž |¡V  qdS ©rq   N)r   Ú	same_pathr   Úsplit)rû   ÚkeyÚvalue)r{   r=   r>   rý   �  s
   € ÿ
ÿz!_simple_layout.<locals>.<genexpr>)rÛ   rU   rX   Ú
commonpathr
   Ú_parent_pathr)  Úall)rà   rW   rM   Úlayoutr=   )rW   r{   rM   r>   rÚ   j  s   þrÚ   c                 C  s   |  | ¡}| 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'
    r  )ÚremovesuffixÚrstriprU   r  )r:  Úpkg_pathr{   r=   r=   r>   rp  “  s   

rp  rR   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 ©rq   r=   ©rû   Úmodr=   r=   r>   Ú
<listcomp>¥  s    z"_find_packages.<locals>.<listcomp>c                 S  s   g | ]
}d |j v r|j ‘qS rw  ©rd   ©rû   Úxr=   r=   r>   rz  ª  s    rq   )Úiterrà   Ú
py_modulesÚext_packageÚext_modulesÚ
rpartition)rR   r  Únested_modulesr�  Ú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 rj  r=   rx  r=   r=   r>   rý   ³  rþ   z*_find_top_level_modules.<locals>.<genexpr>c                 s  s    � | ]}d |j vr|j V  qdS rj  r{  r|  r=   r=   r>   rý   ·  s   € )r  r€  r�  )rR   r  r�  r=   r=   r>   r=  ±  s   €

þr=  rè   rT   c                   s    ‡ ‡fdd„t | ƒD ƒ}t|ƒS )Nc                   s   i | ]}|t t|ˆ ˆƒƒ“qS r=   )Ú_absolute_rootr   r9  ©rW   rT   r=   r>   r'  ¿  s    ÿÿz'_find_package_roots.<locals>.<dictcomp>)ÚsortedÚ_remove_nested)rà   rW   rT   Ú	pkg_rootsr=   rˆ  r>   r>  º  s   þr>  rX   c                 C  s4   t | ƒ}|j}| ¡ rt| ¡ ƒS t| ¡ |j ƒS )z(Works for packages and top-level modules)r   r{   rp   rn   rt   rd   )rX   Úpath_r{   r=   r=   r>   r‡  Ç  s
   r‡  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.
    rq   r!   r   éÿÿÿÿNrI   )rl  ÚrangeÚlenrY   r   r   rp   )r‹  r:  ÚpartsÚiÚpartial_namerX   r=   r=   r>   rA  Ò  s   €
€ûürA  rç   úIterator[tuple[str, list[str]]]c                 c  sB   � | D ]}t ||dƒ}t|ƒ ¡ rt|dƒ ¡ s||gfV  qd S )NrI   z__init__.py)r   r   rp   )rà   r‹  r:  rX   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 rJ   )Ú
_is_nested)rû   ÚotherÚ
other_path©rX   r:  r=   r>   rý   ÷  s
   € ÿ
ÿz!_remove_nested.<locals>.<genexpr>)r?  ÚcopyÚreversedr  r)  ÚanyÚpop)r‹  r.  r=   r—  r>   rŠ  ó  s   þ
€rŠ  r:  ru  r{   Ú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
    rI   r!   rq   )r   Únormpathr  Ústriprl  Ú
startswithr   )r:  ru  r{   rœ  Únorm_pkg_pathÚrestr=   r=   r>   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   ÚrmtreerU   Úmakedirs)r¢  r=   r=   r>   r×     s   
r×   c                   @  s&   e Zd Zd
dd„Zdd„ Zdd„ Zd	S )ru   r3   rQ   c                 C  s"   || _ || _|| _|| _g | _d S rJ   )rS   rT   rw   Úeditable_namer*  )rO   rS   rw   r¦  rT   r=   r=   r>   rù     s
   
z_NamespaceInstaller.__init__c                 C  s   t j | j| j| j ¡S )zInstallation target.)rU   rX   rY   rw   r¦  Ú	nspkg_extrN   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.)Úreprrn   rT   rN   r=   r=   r>   Ú	_get_root)  s   z_NamespaceInstaller._get_rootNrä   )r@   rA   rB   rù   r¨  rª  r=   r=   r=   r>   ru     s    
ru   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
rd   r®   r   údict[str, list[str]]c                 C  s*   t t| ¡ t d¡d�ƒ}tj| ||d�S )z_Create a string containing the code for the``MetaPathFinder`` and
    ``PathEntryFinder``.
    r   )rm  ©rd   r®   r   )r?  r‰  r)  ÚoperatorÚ
itemgetterÚ_FINDER_TEMPLATEÚformatr¬  r=   r=   r>   rK  ‡  s   rK  c                   @  s   e Zd ZdZdS )re  zCFile system does not seem to support either symlinks or hard links.N)r@   rA   rB   rC   r=   r=   r=   r>   re  ‘  s    re  )rL  rn   r3   rJ  )rZ  r   r3   r[  )rà   rh  rW   ri  rM   r   r3   r[  )rR   r   r3   rv  )rà   rh  rW   rè   rT   r   r3   ri  )rX   r   r3   rn   )r‹  ri  r3   rv  )rà   rç   r‹  ri  r3   r“  )r‹  ri  r3   ri  )
r:  rn   ru  rn   r{   rn   rœ  rn   r3   r[  )r¢  r+   r3   r+   )rd   rn   r®   rè   r   r«  r3   rn   )brC   Ú
__future__r   rP  Úloggingr­  rU   r¿   r·   Úcollections.abcr   r   r   Ú
contextlibr   Úenumr   Úinspectr   Ú	itertoolsr	   r
   Úpathlibr   Útempfiler   Útypesr   Útypingr   r   r   r   rI   r   r   r   r   r   r   r   r0   r   r   Ú	discoveryr   rR   r   Úwarningsr   r    r"   rŽ   r#   rœ   r$   rk   r%   r‹   r&   r�   r'   r™   Útyping_extensionsr(   Ú_vendor.wheel.wheelfiler*   r+   Ú	getLoggerr@   rÒ   r-   r2  r  rF   rÕ   rÜ   rØ   rÝ   r   r(  rÚ   rp  rÙ   r=  r>  r‡  rA  r@  rŠ  r”  r×   Ú	Installerru   r¯  rK  Ú	FileErrorre  r=   r=   r=   r>   Ú<module>   sz     
)  !N
A

)


	



	


Y
