
    3iQ                       U 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	Z	ddl
Z
ddlZddlmZ ddlmZ ddlmZmZmZmZ erddlmZmZ dd	lmZ dd
lmZ  G d de      Z ej:                  e      Zde d<   d dZ! e!       Z"de d<   dZ#de d<    ejH                  dejJ                        Z&de d<    G d d      Z' e(h d      Z)de d<   	 d!dZ*d"dZ+edk(  r e+        yy)#zdConcrete Python interpreter information, also used as subprocess interrogation script (stdlib only).    )annotationsN)OrderedDict)digits)TYPE_CHECKINGClassVarFinal
NamedTuple)	GeneratorMapping   )PyInfoCache)
PythonSpecc                  @    e Zd ZU ded<   ded<   ded<   ded<   ded<   y)	VersionInfointmajorminormicrostrreleaselevelserialN)__name__
__module____qualname____annotations__     L/var/www/opsc/venv/lib/python3.12/site-packages/python_discovery/_py_info.pyr   r      s    JJJKr   r   zFinal[logging.Logger]_LOGGERc            	         t        t        j                  dgt        j                  j                  dd      j                         j                  t        j                                    S )N PATHEXT)	listr   fromkeysosenvirongetlowersplitpathsepr   r   r   _get_path_extensionsr+   $   sJ    $$b%c2::>>)R+H+N+N+P+V+VWYWaWa+b%cdeer   zFinal[list[str]]
EXTENSIONS   z
Final[int]_32BIT_POINTER_SIZEzB
    \{ \w+  }   # sysconfig variable placeholder like {base}
    zFinal[re.Pattern[str]]_CONF_VAR_REc                     e Zd ZU dZd3dZd3dZd3dZd3dZd3dZe	d4d       Z
d5dZd6d	Zd7d
Ze	d8d       Zed9d       Zed9d       Zed9d       Zed:d       Zed:d       Zdej,                  fd;dZed9d       Zed9d       Zed9d       Zd9dZd9dZed9d       Zed9d       Zed<d       Z d=dZ!d>dZ"d>dZ#d>dZ$dZ%dZ&ed?d@d       Z'ed?d@d        Z(d9d!Z)dAd"Z*e	 d?d#d$d#dd%	 	 	 	 	 	 	 	 	 	 	 	 	 dBd&       Z+edCd'       Z,edDd(       Z-edEd)       Z.i Z/d*e0d+<   d#dd,	 	 	 	 	 	 	 	 	 dFd-Z1	 	 	 	 	 	 	 	 	 	 	 	 	 	 dGd.Z2e	dHd/       Z3dId0Z4dJd1Z5dKd2Z6y)L
PythonInfoz.Contains information for a Python interpreter.c                    | j                          | j                          | j                          | j                          y N)_init_identity_init_prefixes_init_schemes_init_sysconfigselfs    r   __init__zPythonInfo.__init__5   s2    r   c                .   t         j                  | _        t        j                         | _        | j                  dk(  rt	        t         j
                        | _        t        t         j                   | _        t        j                  d      t        k(  rdnd| _        t        j                         | _        t        j                  d      | _        t         j"                  | _        t$        j&                  | _        t        j                  d      dk(  | _        y )NPyPyP    @   py_version_nodotPy_GIL_DISABLEDr   )sysplatformpython_implementationimplementationtuplepypy_version_infor   version_infostructcalcsizer.   architecture	sysconfigget_platformsysconfig_platformget_config_varversion_nodotversionr%   namefree_threadedr8   s    r   r4   zPythonInfo._init_identity;   s    &<<>&(%*3+@+@%AD"')9)9:"(//#"6:M"MBSU"+"8"8":&556HI{{''&556GHAMr   c                   dd} |t        t        dd             | _         |t        t        dd             | _         |t        t        dd             | _         |t        t        dd             | _         |t        t        dd             | _         |t        j                        | _         || j                        | _        | j                         | _
        	 t        d       d}|| _        t        j                  | _        t        j                         | _        t        t        j"                  d
d       | _        y # t        $ r d	}Y cw xY w)Nc                H    | d S t         j                  j                  |       S r3   )r%   pathabspath)values    r   abs_pathz+PythonInfo._init_prefixes.<locals>.abs_pathK   s     =4Dbggooe.DDr   prefixbase_prefixreal_prefixbase_exec_prefixexec_prefixvenvTFencoding)rX   
str | Nonereturnra   )getattrrB   rZ   r[   r\   r]   r^   
executableoriginal_executable_fast_get_system_executablesystem_executable
__import__ImportErrorhas_venvrV   getfilesystemencodingfile_system_encodingstdoutstdout_encoding)r9   rY   hass      r   r5   zPythonInfo._init_prefixesJ   s   	E wsHd;<#GC$EF#GC$EF (6H$)O P#GC$EF"3>>2#+DOO#< !%!A!A!C	vC HH	$'$=$=$?!&szz:tD  	C	s   D< <E
	E
c           	        t        j                         }d|v rWd| _        t        j                         D ci c]%  }|t        j                  |d| j                        ' c}| _        i | _        y t        j                  d d dk(  r[d|v rWd| _        t        j                         D ci c]%  }|t        j                  |d| j                        ' c}| _        i | _        y d | _        t        j                         D ci c]  }|t        j                  |d       c}| _        | j                         j                         | _        y c c}w c c}w c c}w )	Nr_   F)expandscheme   )   
   
deb_systemposix_prefix)rq   )rL   get_scheme_namessysconfig_schemeget_path_namesget_pathsysconfig_pathsdistutils_installrB   rH   _distutils_installcopy)r9   scheme_namesis      r   r6   zPythonInfo._init_schemesb   s.    113\!$*D!^g^v^v^x$YZ9%%ad>S>STT$D  &(D"bq!W,1M$2D!^g^v^v^x$YZ9%%ad>S>STT$D  &(D"$(D!T]TlTlTn#oqAy'9'9!E'J$J#oD %)%<%<%>%C%C%ED"$$ $ps   *E	'*E>Ec           	        t        t        dt        t        dd             }d| |       nd ffD ci c]
  \  }}||| c}}| _        t               }| j                  j	                         D ]-  }|j                  d t        j                  |      D               / |j                  d       |j                  d       |D ci c]  }|t        j                  |xs d       c}| _
        dt        j                  v r| j                         \  | _        | _        nd	\  | _        | _        | j                  j!                         D ci c]?  \  }}|t#        |t$              r'|j'                  | j(                        r| j*                  n|A }}}| j-                  d
|      | _        | j-                  d|      | _        t        t2        dt        t2        dd             | _        d | _        y c c}}w c c}w c c}}w )Nget_makefile_filename_get_makefile_filenamemakefile_filenamec              3  &   K   | ]	  }|d d   yw)r   Nr   ).0ks     r   	<genexpr>z-PythonInfo._init_sysconfig.<locals>.<genexpr>   s     "Rq1Qr7"Rs   PYTHONFRAMEWORK)Py_ENABLE_SHARED
INSTSONAMELIBDIRr!   TCL_LIBRARYNNstdlib
platstdlibmaxsizemaxint)rc   rL   setr|   valuesupdater/   findalladdrO   sysconfig_varsr%   r&   _get_tcl_tk_libstcl_libtk_libitems
isinstancer   
startswithrZ   system_prefixsysconfig_pathsystem_stdlibsystem_stdlib_platformrB   max_size	_creators)r9   makefiler   vconfig_var_keyselementr   confss           r   r7   zPythonInfo._init_sysconfigw   s   9&=wyRjlp?qr %H4HhjdS
1 }	 qD
 %++224 	SG"""RL4H4H4Q"RR	S-.KLM\]q)":":17"CC]BJJ&(,(=(=(?%DL$+(2%DL$+ ++113
1 jC&8Q\\$++=V""\]]
 
 "005A&*&9&9,&N#YXt0LM9
 ^
s   G+!G1	AG6c                 <   d\  } }	 ddl }	 |j                         }|j                  d      } 	 |j                  d      }|r t        j                  j                  |      rnd}||j                  d      }t        j                  j                  |       }|dj                  |j                  d      dd       |j                  d      d   g}|D ]  }t        j                  j                  |d	|       }t        j                  j                  |      sFt        j                  j                  t        j                  j                  |d
            s|} n | |fS # |j                  $ r d}Y w xY w# |j                  $ r Y | |fS w xY w# t        $ r Y | |fS w xY w)z.Detect the tcl and tk libraries using tkinter.r   r   Nzinfo libraryzset tk_libraryzpackage require Tk.rs   tkztk.tcl)tkinterTclevalr%   rV   isdirTclErrordirnamejoinr)   existsri   )	r   r   r   tcl
tk_version
tcl_parentversion_variantsrQ   tk_lib_paths	            r   r   zPythonInfo._get_tcl_tk_libs   s    %(	 #ffh((>2" XX&67F"''--"7!%
 >!$*>!?J!#!9J #!1!1#!6r!:;"((-a0($ $4 "&(ggll:G9~&N!ww}}[9$77>>"'',,{H*MN%0F!" 5 {{ "!F". ;; K  	N Q	sL   F !E4 5E #C/E4 E4 E1-E4 0E11E4 4F	F		FFc                J   | j                   s1| j                  | j                  | j                  k7  s| j                  S | j                   yt	        t
        dd      }|yt
        j                  |k(  ryt        j                  j                  |      r|S | j                  |      S )z?Try to get the system executable by just looking at properties.N_base_executable)r\   r[   rZ   re   rc   rB   rd   r%   rV   r   _try_posix_fallback_executable)r9   base_executables     r   rf   z&PythonInfo._fast_get_system_executable   s       T%5%5%AdFVFVZ^ZeZeFe+++ '!#'94@" >>_, 77>>/*"" 22?CCr   c           	        | j                   j                  | j                   j                  }}| j                  dk7  s||fdk  ryt        j                  j                  |      }d| d| d| g}| j                  dk(  r|j                  ddd| d| d| g       |D ]E  }t        j                  j                  ||      }t        j                  j                  |      sC|c S  y)	zJFind a versioned Python binary as fallback for POSIX virtual environments.posix)rt      Npythonr   r<   pypypypy3)
rH   r   r   r%   rV   r   rE   extendr   r   )r9   r   r   r   base_dir
candidates	candidate	full_paths           r   r   z)PythonInfo._try_posix_fallback_executable   s    ((..0A0A0G0Gu77g%'!9 77???3ug&&q(@A
&(vw$ug$ugQug@VWX# 	!IXy9Iww~~i(  	!
 r   c                n   | j                   j                  |      }|| j                  | j                  | j                  | j
                  f}| j                  j                         D ci c]  \  }}|||v rdn| }}}| j                  ||      j                  t        j                        }|S c c}}w )z
        Return the relative installation path for a given installation scheme *key*.

        :param key: sysconfig installation scheme key (e.g. ``"scripts"``, ``"purelib"``).
        r!   )
config_var)r}   r'   rZ   r^   r[   r]   r   r   r   lstripr%   sep)r9   keyresultprefixesr   r   r   s          r   install_pathzPythonInfo.install_path   s     ''++C0>{{D$4$4d6F6FH]H]]HDHDWDWD]D]D_`DAq!1=Ra7`J`(((DKKBFFSF as   )B1c            	        t        j                         5  t        j                  d       	 ddlm}  ddlm} 	 d d d         j                  ddi      }t        t        d      rd t        _        t        j                         5  t        j                  d       |j                  dd	
      }d d d        t        j                  _        |j!                          D ci c]2  }|t#        |d|       dd  j%                  t        j                        4 c}S # t        $ r i cY cd d d        S w xY w# 1 sw Y   xY w# 1 sw Y   xY wc c}w )Nignorer   )dist)SCHEME_KEYSscript_argsz--no-user-cfg
_frameworkinstallT)createinstall_r   )warningscatch_warningssimplefilter	distutilsr   distutils.command.installr   ri   DistributionhasattrrB   r   get_command_objr%   r   rZ   finalize_optionsrc   r   )r   r   distributionr   r   s        r   r~   zPythonInfo._distutils_install  s.   
 $$& 	!!(+*A		 ((?*
  3%!CN$$& 	K!!(+"229T2JG	K   "XcdQTgg#'78<DDRVVLLdd  		 	
	 		K 	K es:   D1D)D=7E	D."D1-D..D11D:=Ec                L    dj                  d | j                  dd D              S )zCThe full version as ``major.minor.micro`` string (e.g. ``3.13.2``).r   c              3  2   K   | ]  }t        |        y wr3   r   r   r   s     r   r   z)PythonInfo.version_str.<locals>.<genexpr>#       ?1A?   r   rt   r   rH   r8   s    r   version_strzPythonInfo.version_str   &     xx?(9(9!A(>???r   c                L    dj                  d | j                  dd D              S )z>The release version as ``major.minor`` string (e.g. ``3.13``).r   c              3  2   K   | ]  }t        |        y wr3   r   r   s     r   r   z1PythonInfo.version_release_str.<locals>.<genexpr>(  r   r   r   rs   r   r8   s    r   version_release_strzPythonInfo.version_release_str%  r   r   c                R    | j                   }d|j                   d|j                   S )zBThe python executable name as ``pythonX.Y`` (e.g. ``python3.13``).r   r   )rH   r   r   )r9   rH   s     r   python_namezPythonInfo.python_name*  s0     ((**+1\-?-?,@AAr   c                    | j                   duS )zW``True`` if this interpreter runs inside an old-style virtualenv (has ``real_prefix``).N)r\   r8   s    r   is_old_virtualenvzPythonInfo.is_old_virtualenv0       t++r   c                    | j                   duS )zN``True`` if this interpreter runs inside a PEP 405 venv (has ``base_prefix``).N)r[   r8   s    r   is_venvzPythonInfo.is_venv5  r   r   Nc                    | j                   j                  |      }|y|| j                  }n-| j                  j                         }|j	                  |       |} |j
                  di |j                  d|      S )ap  
        Return the sysconfig install path for a scheme *key*, optionally substituting config variables.

        :param key: sysconfig path key (e.g. ``"purelib"``, ``"include"``).
        :param config_var: replacement mapping for sysconfig variables; when ``None`` uses the interpreter's own values.
        :param sep: path separator to use in the result.
        r!   /r   )r|   r'   r   r   r   formatreplace)r9   r   r   r   patternbases         r   r   zPythonInfo.sysconfig_path:  sy     &&**3/?,,J&&++-DKK
#Jw~~+
+33C==r   c                (   | j                  d| j                  j                         D ci c]?  \  }}|t        |t              r'|j                  | j                        r| j                  n|A c}}      }t        j                  j                  |      swt        j                  j                  | j                  t        j                  j                  | j                  d                  }t        j                  j                  |      r|}|S c c}}w )z7The path to the system include directory for C headers.includeheaders)r   r   r   r   r   r   rZ   r   r%   rV   r   r   r   r   )r9   r   r   rV   fallbacks        r   system_includezPythonInfo.system_includeM  s     "" !//557Aq *Q*<dkkAZD&&`aa
 ww~~d#ww||DKKARARS\A]1^_Hww~~h's   ADc                R    | j                   xs | j                  xs | j                  S )z=The prefix of the system Python this interpreter is based on.)r\   r[   rZ   r8   s    r   r   zPythonInfo.system_prefix]  s$     B4#3#3Bt{{Br   c                R    | j                   xs | j                  xs | j                  S )zBThe exec prefix of the system Python this interpreter is based on.)r\   r]   r^   r8   s    r   system_exec_prefixzPythonInfo.system_exec_prefixb  s&     L4#8#8LD<L<LLr   c           
         dj                  | j                  j                  | j                  j	                         D ci c]  \  }}|j                  d      r|| c}}      S c c}}w )Nz{}({!r})_)r   	__class__r   __dict__r   r   )r9   r   r   s      r   __repr__zPythonInfo.__repr__g  sS      NN##"mm113Mda1<<;LQTM
 	
Ms   A%A%c                   dj                  | j                  j                  dj                  d d| j                  f| j
                  | j
                  | j                  k7  rdnd | j
                  f| j                  | j
                  | j                  hvrdnd | j                  fd| j                  fd| j                  fd	t        | j                        fd
| j                   d| j                   ffD                    S )Nz{}({})z, c              3  4   K   | ]  \  }}|	| d|   y w)N=r   )r   r   r   s      r   r   z%PythonInfo.__str__.<locals>.<genexpr>p  s-      Aq& =) #Qqc
   specsystemoriginalexerC   rQ   encoding_fs_io-)r   r	  r   r   r  rg   rd   re   rC   reprrQ   rl   rn   r8   s    r   __str__zPythonInfo.__str__m  s   NN##II  TYY'  11=$BXBX\`\k\kBk !!..	  33D<R<RTXTcTc;dd #!00	 DOO,/T\\ 23%$*C*C)DAdFZFZE['\]# 
 	
r   c                    | j                   }|y|dk(  ry|j                  dd      d   }|dk(  r"t        j                         j	                         }t        |      S )zZReturn the instruction set architecture (ISA) derived from :func:`sysconfig.get_platform`.unknownwin32x86r  r   r   
universal2)rN   rsplitrC   machiner(   normalize_isa)r9   platisas      r   r  zPythonInfo.machine  s`     &&<7?kk#q!"%,""$**,CS!!r   c                    dj                  | j                  dj                  d | j                  D              | j                  rdnd| j
                  | j                        S )zVA specification string identifying this interpreter (e.g. ``CPython3.13.2-64-arm64``).z{}{}{}-{}-{}r   c              3  2   K   | ]  }t        |        y wr3   r   r   s     r   r   z"PythonInfo.spec.<locals>.<genexpr>  s     7SV7r   tr!   )r   rE   r   rH   rS   rK   r  r8   s    r   r  zPythonInfo.spec  sU     $$HH7T%6%677%%C2LL
 	
r   c                T    ddl m}  ||       | j                  j                          y)zy
        Clear all cached interpreter information from *cache*.

        :param cache: the cache store to clear.
        r   )clearN)_cached_py_infor&  _cache_exe_discovery)clscacher&  s      r   clear_cachezPythonInfo.clear_cache  s      	+e  &&(r   c          	        |j                   r| j                  |      sy|r| j                  |      sy|j                  |j                  | j                  k7  ry|j                  |j                  | j                  k7  ry|j
                  |j
                  | j
                  k7  ry|j                  | j                  |      syt        d t        | j                  dd |j                  |j                  |j                  f      D              S )z
        Check if a given specification can be satisfied by this python interpreter instance.

        :param spec: the specification to check against.
        :param impl_must_match: when ``True``, the implementation name must match exactly.
        Fc              3  D   K   | ]  \  }}|d u xs |d u xs ||k(    y wr3   r   )r   ourreqs      r   r   z'PythonInfo.satisfies.<locals>.<genexpr>  s5      
S 4K43$;4#*4
s    r   rt   )rV   _satisfies_path_satisfies_implementationrK   r  rS   version_specifier_satisfies_version_specifierallziprH   r   r   r   )r9   r  impl_must_matchs      r   	satisfieszPythonInfo.satisfies  s     99T11$74#A#A$#G(T->->$BSBS-S<<#(D)d.@.@DDVDV.V!!-d6W6WX\6] 
 1 1!A 6TZZQUQ[Q[8\]
 
 	
r   c                   | j                   t        j                  j                  |j                        k(  ry|j                  ryt        j                  j                  | j                        }|j                  }t        j                  dk(  rFt        j                  j                  |      \  }}|r |j                  |      r|d t        |        n|}||k(  S )NTr  )rd   r%   rV   rW   is_absbasenamere   rB   rC   splitextendswithlen)r9   r  r:  	spec_pathsuffixs        r   r0  zPythonInfo._satisfies_path  s    ??bggoodii88;;77##D$<$<=II	<<7"!ww//9Hf5;	@R@RSY@Z	.S[L1`iI9$$r   c                    |j                   d u xs5 |j                   j                         | j                   j                         k(  S r3   )rE   r(   )r9   r  s     r   r1  z$PythonInfo._satisfies_implementation  s;    ""d*hd.A.A.G.G.ITM`M`MfMfMh.hhr   c                N   |j                   y| j                  }|j                   D ]  }|j                  J |j                  }dD ]  }||v s|j	                  |      d   } n |j                  d      dz   }dj                  d |j                  |j                  |j                  gd | D              }|j                  dk7  rN|dk(  s|j                  j                  3d	d
ddj                  |j                        x}r| | |j                   }|j                  |      r y y)NT)rcbar   r   r   c              3  2   K   | ]  }t        |        y wr3   r   )r   cs     r   r   z:PythonInfo._satisfies_version_specifier.<locals>.<genexpr>  s     x!s1vxr   finalrt   rD  rC  rB  )alphabetar   F)r2  rH   rQ   r   r)   countr   r   r   r   r   pre_typer'   r   contains)	r9   r  rH   	specifiernumeric_versionrZ   	precisionreleaser?  s	            r   r3  z'PythonInfo._satisfies_version_specifier  sD   !!)((// 	I$$000'33O* _,&5&;&;F&CA&FO (--c2Q6Ihhx0B0BLDVDVXdXjXj/klvmv/wxxG))W4!^y'8'8'A'A'M),cMQQR^RkRkllVl$IfXl.A.A-BC%%g.!	" r   c                    | j                   9| j                  t        j                  |dd      }|d}t	        |      || _         | j                   S )z
        Locate the current host interpreter information.

        :param cache: interpreter metadata cache; when ``None`` results are not cached.
        TFraise_on_errorresolve_to_hostz*failed to query current Python interpreter)_currentfrom_exerB   rd   RuntimeErrorr)  r*  r   msgs       r   currentzPythonInfo.current  sO     <<\\#..%^c\dF~B"3''!CL||r   c                    | j                   9| j                  t        j                  |dd      }|d}t	        |      || _         | j                   S )z
        Locate the current system interpreter information, resolving through any virtualenv layers.

        :param cache: interpreter metadata cache; when ``None`` results are not cached.
        TrR  z1failed to query current system Python interpreter)_current_systemrV  rB   rd   rW  rX  s       r   current_systemzPythonInfo.current_system  sT     &\\#..%^b\cF~I"3''"(C"""r   c                L    t        j                  | j                         d      S )z8Serialize this interpreter information to a JSON string.rs   )indent)jsondumpsto_dictr8   s    r   to_jsonzPythonInfo.to_json  s    zz$,,.33r   c                    t        |       D ci c]  }||dk7  rt        | |      nd }}|d   }t        |d      r|j                         n||d<   |S c c}w )z;Convert this interpreter information to a plain dictionary.r   NrH   _asdict)varsrc   r   re  )r9   vardatarH   s       r   rb  zPythonInfo.to_dict  sd    UYZ^U_`cC;,>gdC(DH``N+9@y9Y|335_k^ as   ATF)rS  ignore_cacherT  envc                  ddl m} |t        j                  n|} || |||||      }t	        |t
              r|r	 |j                  ||      }|S |S # t        $ r1}	|r t        j                  d|j                  |	       d}Y d}	~	|S d}	~	ww xY w)a  
        Get the python information for a given executable path.

        :param exe: path to the Python executable.
        :param cache: interpreter metadata cache; when ``None`` results are not cached.
        :param raise_on_error: raise on failure instead of returning ``None``.
        :param ignore_cache: bypass the cache and re-query the interpreter.
        :param resolve_to_host: resolve through virtualenv layers to the system interpreter.
        :param env: environment mapping; defaults to :data:`os.environ`.
        r   )rV  N)rj  rS  ri  z-ignore %s due cannot resolve system due to %r)r'  rV  r%   r&   r   r1   resolve_to_system	Exceptionr   infore   )
r)  r  r*  rS  ri  rT  rj  rV  proposed	exceptions
             r   rV  zPythonInfo.from_exe  s    * 	.KbjjSC^bnoh
+ #55eXF x   !LhNjNjluv s   A 	B&BBc                j    t        j                  |      }| j                  |j                               S )z
        Deserialize interpreter information from a JSON string.

        :param payload: JSON produced by :meth:`to_json`.
        )r`  loads	from_dictr   )r)  payloadraws      r   	from_jsonzPythonInfo.from_json;  s'     jj!}}SXXZ((r   c                `    t        di |d   |d<    |        }|j                         |_        |S )z
        Reconstruct a :class:`PythonInfo` from a plain dictionary.

        :param data: dictionary produced by :meth:`to_dict`.
        rH   r   )r   r   r
  )r)  rh  r   s      r   rs  zPythonInfo.from_dictE  s4      +BT.-AB^))+r   c                   |j                   }t               }|j                  $|j                  xs |j                  xs |j
                  }||v rt        |      dk(  r(t        j                  d|       |j                   |_        nt        |j                         d      D ]   \  }\  }}t        j                  d|||       " t        j                  dt        |      dz   ||       dj                  dj                  |j                                     }	t        |	      |||<   |j!                  ||d      }|j                  $|j                   |j                  k7  r | j#                  |j                  |      }
|
|
}||_         |S )	z
        Walk virtualenv/venv prefix chains to find the underlying system interpreter.

        :param cache: interpreter metadata cache; when ``None`` results are not cached.
        :param target: the interpreter to resolve.
        r   z$%r links back to itself via prefixes)startz%d: prefix=%s, info=%rz prefixes are causing a circle {}|F)rZ   exact)rd   r   rg   r\   r[   rZ   r=  r   rn  	enumerater   errorr   r   keysrW  discover_exerV  )r)  r*  targetstart_executabler   rZ   atpr$  rY  resolveds              r   rl  zPythonInfo.resolve_to_systemQ  sj    ",,=&&.''N6+=+=NF!x=A%LL!GP/5/@/@F,"+HNN,<A"F FJBAMM":B1EF6H8I6SYZ8??@YZ"3''%HV((vU(KF &&.  8 88||F$<$<eDH#!,r   z,ClassVar[dict[tuple[str, bool], PythonInfo]]r(  )r{  rj  c          
        ||f}|| j                   v r6|r4t        j                  d||| j                   |          | j                   |   S t        j                  d| |       | j                         }| j	                  |      }g }|t
        j                  n|}|D ]7  }	|D ]0  }
| j                  ||	|
|||      }||| j                   |<   |c c S  9 |du r[|rY| j                  ||       }t
        j                  j                  |      }|| j                   |<   t        j                  d||       |S dj                  dj                  |      t
        j                  j                  |            }t        |      )aS  
        Discover a matching Python executable under a given *prefix* directory.

        :param cache: interpreter metadata cache.
        :param prefix: directory prefix to search under.
        :param exact: when ``True``, require an exact version match.
        :param env: environment mapping; defaults to :data:`os.environ`.
        z)discover exe from cache %s - exact %s: %rzdiscover exe for %s in %s)r{  FzFno exact match found, chosen most similar of %s within base folders %szfailed to detect {} in {}rz  )r(  r   debug_find_possible_exe_names_find_possible_foldersr%   r&   
_check_exe_select_most_likelyr*   r   r   rW  )r9   r*  rZ   r{  rj  r   possible_namespossible_folders
discoveredfolderrR   rn  foldersrY  s                 r   r  zPythonInfo.discover_exer  sr     em$+++MMEvuVZVoVopsVtu,,S1114@66866v>
KbjjS& 	 F&  ufdJSXY#59D--c2K	 	  E>j++J=Djjoo&67G-1D%%c*MMbdhjqrK)00.1I2::??[kKlm3r   c                  t         j                  j                  ||      }t         j                  j                  |      sy | j	                  ||dd|      }|y dD ]  }	t        ||	      }
t        | |	      }|
|k7  s!|	dk(  r0dj                  d |
D              dj                  d |D              }}
|j                  }t        j                  d||	|
|       |du r|j                  |        y  |S )	NF)rT  rS  rj  )rE   rK   r  rH   rH   r   c              3  2   K   | ]  }t        |        y wr3   r   r   s     r   r   z(PythonInfo._check_exe.<locals>.<genexpr>  s     .E!s1v.Er   c              3  2   K   | ]  }t        |        y wr3   r   r   s     r   r   z(PythonInfo._check_exe.<locals>.<genexpr>  s     Oi[\PSTUPVOir   z2refused interpreter %s because %s differs %s != %s)
r%   rV   r   r   rV  rc   rd   r   r  append)r9   r*  r  rR   r  rj  r{  exe_pathrn  itemfoundsearchedrd   s                r   r  zPythonInfo._check_exe  s     77<<-ww~~h'}}XueTY_b}c<Q 	DD$'EtT*H >)&)hh.Eu.E&EsxxOi`hOiGi8E!__
RT^`dfkmuvE>%%d+ 	 Kr   c                6    dfd}t        | |d      }|d   S )Nc           	        | j                   j                   k(  | j                  j                  j                  j                  k(  | j                  j                  j                  j                  k(  | j                  j                  k(  | j
                  j
                  k(  | j                  j                  j                  j                  k(  | j                  j                  j                  j                  k(  | j                  j                  j                  j                  k(  g}t        d t        t        |            D              S )Nc              3  4   K   | ]  \  }}|rd |z  nd  yw)r   r   Nr   )r   posmatchs      r   r   zBPythonInfo._select_most_likely.<locals>.sort_by.<locals>.<genexpr>  s     ajc5ESq0ar  )rE   rH   r   r   rK   r  r   r   r   sumr|  reversed)rn  matchesr  s     r   sort_byz/PythonInfo._select_most_likely.<locals>.sort_by  s    ##v'<'<<!!''6+>+>+D+DD!!''6+>+>+D+DD!!V%8%88.!!''6+>+>+D+DD!!..&2E2E2R2RR!!((F,?,?,F,FF	G aIhW^N_D`aaar   T)r   reverser   )rn  r1   rb   r   )sorted)r  r  r  sorted_discovereds    `  r   r  zPythonInfo._select_most_likely  s%    	b #:7DI ##r   c                P   t               }t               }d |t        j                  j                  | j                        <   d || j                  <   d |t        j                  j                  | j
                        <   d || j
                  <   |D ]^  }t        j                  j                  |      }|j                  | j                        s>|t        | j                        d  }d || | <   ` d ||<   |D cg c]$  }t        j                  j                  |      s#|& c}S c c}w r3   )r   r%   rV   realpathrd   re   r   r   rZ   r=  r   )r9   inside_foldercandidate_folderexecutablesr  r   relativer   s           r   r  z!PythonInfo._find_possible_folders  s    &=!m9=BGG$$T__56'+DOO$BFBGG$$T%=%=>?04D,,- 	FC77??3'Dt{{+DKK 0 23AE M?8*!=>		F +/'+Aarww~~a/@AAAs   7$D#D#c           
     |   t               }| j                         D ]  }dD ]  }dj                  d | j                  d | D              }dg}| j                  r|j                  d       |D ]4  }d| j                   dfD ]  }t        D ]  }| | | | | }	d ||	<      6   t        |j                               S )N)rt   rs   r   r   r   c              3  2   K   | ]  }t        |        y wr3   r   r   s     r   r   z6PythonInfo._find_possible_exe_names.<locals>.<genexpr>  s     "Ja3q6"Jr   r!   r$  r  )
r   _possible_baser   rH   rS   r  rK   r,   r#   r~  )
r9   name_candidaterR   r  rQ   modsmodarchextr   s
             r   r  z#PythonInfo._find_possible_exe_names  s    $'') 
	=D" 	=(("J43D3DSb3I"JJt%%KK$ =C#$T%6%6$7!8" = =#- =C+/&	#tfSE(JI8<N95===	=
	= N'')**r   c              #    K   t               }t        j                  j                  t        j                  j	                  | j
                              d   j                  t              }d ||<   d || j                  <   d|v r|d= d |d<   |D ]G  }|j                         }| ddl
m}  |       s%||k7  r| |j                         }||k7  sD| I y w)Nr   r   r   )fs_is_case_sensitive)r   r%   rV   r;  r:  rd   rstripr   rE   r(   _compatr  upper)r9   possible_baser:  r   r(   r  r  s          r   r  zPythonInfo._possible_base  s     #77##BGG$4$4T__$EFqIPPQWX"&h-1d))*}$h'"&h! 
	 DJJLEK5#%5=J

D=K
	 s   B-C0CCrb   None)rb   ztuple[str | None, str | None])rb   ra   )r   r   rb   ra   )r   r   rb   r   )rb   zdict[str, str])rb   r   )rb   bool)r   r   r   zdict[str, str] | Noner   r   rb   r   )r*  r   rb   r  )r  r   r6  r  rb   r  )r  r   rb   r  r3   )r*  PyInfoCache | Nonerb   r1   )rb   dict[str, object])r  r   r*  r  rS  r  ri  r  rT  r  rj  Mapping[str, str] | Nonerb   PythonInfo | None)rt  r   rb   r1   )rh  r  rb   r1   )r*  r  r  r1   rb   r1   )
r*  r   rZ   r   r{  r  rj  r  rb   r1   )r*  r  r  r   rR   r   r  list[PythonInfo]rj  zMapping[str, str]r{  r  rb   r  )r  r  r  r1   rb   r1   )r  r   rb   	list[str]rb   r  )rb   zGenerator[str, None, None])7r   r   r   __doc__r:   r4   r5   r6   r7   staticmethodr   rf   r   r   r~   propertyr   r   r   r   r   r%   r   r   r  r   r  r  r  r  r  classmethodr+  r7  r0  r1  r3  r\  rU  rZ  r]  rc  rb  rV  rv  rs  rl  r(  r   r  r  r  r  r  r  r   r   r   r1   r1   2   s   8NE0F*@ 0 0dD4& e e4 @ @ @ @ B B
 , , , , LP\^\b\b >&   C C M M

8 
" 
" 
 
 	) 	)
0
%i. OH  # #4  %)!
  $" $(,!! "!
 ! ! ! &! 
! !F ) ) 	 	  < JLFK (,& &  & 
 &  &&  
& P!  	
 %   
> $ $&B"+ r   r1   >	   r  i686arm64ppc64s390xx86_64ppc64leriscv64loongarch64zfrozenset[str]KNOWN_ARCHITECTURESc                P    | j                         }dddddj                  ||      S )Nr  r  r  )amd64aarch64i386i586)r(   r'   )r!  lows     r   r  r    s+    
))+C'5%PTTUXZ]^^r   c            
        t         j                  dd  } t        |       dk\  r| d   }| dd  } nd}t        |       dk\  r| d   }| dd  } nd}t         j                  d d | z   t         _        t               j	                         }t         j
                  j                  dj                  |d d d   ||d d d   f             t         j
                  j                          y )Nr   r   r!   r   )	rB   argvr=  r1   rc  rm   writer   flush)r  start_cookie
end_cookier   s       r   _mainr    s    88AB<D
4yA~AwABx
4yA~!W
ABx
xx|d"CH\!!#FJJRWWl4R40&*TrT:JKLMJJr   __main__r  )r!  r   rb   r   r  ),r  
__future__r   r`  loggingr%   rC   rerI   rB   rL   r   collectionsr   stringr   typingr   r   r   r	   collections.abcr
   r   _cacher   _py_specr   r   	getLoggerr   r   r   r+   r,   r.   compileVERBOSEr/   r1   	frozensetr  r  r  r   r   r   <module>r     s    j "   	  	  
   #  = =2#$*  "3!2!28!<	 <f  45
 5"# Z #'1rzz JJ	($ N  N b '0 
1 
' ^ 
 ?_
, z	G r   