
    ґ2d4                         d dl Z d dlZd dlZd dlmZmZ d dlmZ d dlm	Z	  ej
        dej                  Z ej
        dej                  Z e j        e          Z G d d          ZdS )	    N)joinsplit)execute)Versionz
    (?:\#!\s*){0,1}  # shebang prefix
    (?P<path>
        .*?/bin/.*?)?
    (?P<name>
        python|pypy)
    (?P<version>
        \d[\.\d]*)?
    (?P<debug>
        -dbg)?
    (?P<options>.*)
    a-  
    (?P<name>.*?)
    (?:\.
        (?P<stableabi>abi\d+)
     |(?:\.
        (?P<soabi>
            (?P<impl>cpython|pypy)
            -
            (?P<ver>\d{2})
            (?P<flags>[a-z]*?)
        )
        (?:
            -(?P<multiarch>[^/]*?)
        )?
    ))?
    (?P<debug>_d)?
    \.so$c                       e Zd ZdZdZdZdZdZdZi Z		 	 ddZ
d Zd Zd	 Zd
 Zed             ZddZddZddZddZddZddZddZddZddZddZddZdS )InterpreterNpythonFcpython c                    t                      }|d= |d= t          |t                    r3|                                D ]}	||	         t	          ||	          ||	<   ny|rw|                    dd                                          r|st          |          |d<   n:|                     |          	                                D ]\  }	}
||	         |
||	<   |	                                D ]\  }	}
t          | |	|
           d S )Nselfvalue. version)locals
isinstancer   keysgetattrreplaceisdigitr   parseitemssetattr)r   r   pathnamer   debugimploptionsparamskeyvals              +/usr/share/python3/debpython/interpreter.py__init__zInterpreter.__init__E   s$   6N7Oe[)) 
	*{{}} 6 6#;&")%"5"5F3K6  	*}}S"%%--// * *$+ENNy!! $

5 1 1 7 7 9 9 * *HCc{*&)s 	$ 	$HCD#s####	$ 	$    c                 >   |dk    rP|rN|                     d          rd| j        d<   n|                     d          r
d| j        d<   d|v r
d| j        d<   n|d	k    r|t          |          }|d
v r!|t          t          |          | j        |<   d S || j        |<   d S )Nr   r	   r
   r   pypyz-dbgTr   r   )r   r   r   r   )
startswith__dict__r   r   r   )r   r   r   s      r#   __setattr__zInterpreter.__setattr__Z   s    6>>e>)) /(1f%%!!&)) /(.f%)-g&Y5#4ENNE777EM")+t"<"<DM$"'DM$r%   c                     | j         pd}||                     | j                  z  }| j        r |dd                    | j                  z   z  }|S )Nr    )r   _vstrr   r   r   )r   results     r#   __repr__zInterpreter.__repr__j   sQ    b$**T\***< 	3cCHHT\2222Fr%   c                 6    |                      | j                  S N)r-   r   )r   s    r#   __str__zInterpreter.__str__q   s    zz$,'''r%   c                     | j         dk    r| j        S |rIt          |          | j        vr3| j        rd                    |          S | j        t          |          z   S | j        S )Nr'   zpython{}-dbg)r   r   strr   formatr   r   s     r#   r-   zInterpreter._vstrt   sj    99 	,s7||4944z 6%,,W5559s7||++yr%   c                     t                               |           }|si S |                                }d|v r*t          |d                                                   |d<   |S )a  Return dict with parsed shebang

        >>> sorted(Interpreter.parse('pypy').items())
        [('debug', None), ('name', 'pypy'), ('options', ()), ('path', None), ('version', None)]
        >>> sorted(Interpreter.parse('/usr/bin/python3.3-dbg').items())
        [('debug', '-dbg'), ('name', 'python'), ('options', ()), ('path', '/usr/bin/'), ('version', '3.3')]
        >>> sorted(Interpreter.parse('#! /usr/bin/pypy --foo').items())
        [('debug', None), ('name', 'pypy'), ('options', ('--foo',)), ('path', '/usr/bin/'), ('version', None)]
        >>> sorted(Interpreter.parse('#! /usr/bin/python3.2').items())
        [('debug', None), ('name', 'python'), ('options', ()), ('path', '/usr/bin/'), ('version', '3.2')]
        >>> sorted(Interpreter.parse('/usr/bin/python3.2-dbg --foo --bar').items())
        [('debug', '-dbg'), ('name', 'python'), ('options', ('--foo', '--bar')), ('path', '/usr/bin/'), ('version', '3.2')]
        r   )
SHEBANG_REsearch	groupdicttupler   )shebangr.   s     r#   r   zInterpreter.parse~   sh      ""7++ 	I!!## %fY&7&=&=&?&? @ @F9r%   c                     t          |p| j                  }| j        dk    rd}n2|t          d          z  rd|z  }n|t          d          z  rd|z  }nd}|rd|z  }|rd	||}|S )
a  Return path to site-packages directory.

        Note that returned path is not the final location of .py files

        >>> i = Interpreter('python')
        >>> i.sitedir(version='3.1')
        '/usr/lib/python3/dist-packages/'
        >>> i.sitedir(version='2.5')
        '/usr/lib/python2.5/site-packages/'
        >>> i.sitedir(version=Version('2.7'))
        '/usr/lib/python2.7/dist-packages/'
        >>> i.sitedir(version='3.1', gdb=True, package='python3-foo')
        'debian/python3-foo/usr/lib/debug/usr/lib/python3/dist-packages/'
        >>> i.sitedir(version=Version('3.2'))
        '/usr/lib/python3/dist-packages/'
        >>> Interpreter('pypy').sitedir(version='2.0')
        '/usr/lib/pypy/dist-packages/'
        r'   z/usr/lib/pypy/dist-packages/2.6z /usr/lib/python%s/site-packages/z3.0z /usr/lib/python%s/dist-packages/z/usr/lib/python3/dist-packages/z/usr/lib/debug%szdebian/)r   r   r   )r   gdbpackager   r   s        r#   sitedirzInterpreter.sitedir   s    & '1T\22 91DD& 	55?DD& 	55?DD4D 	-%,D 	3 	3$+GTT2Dr%   c           	      8   t          |p| j                  }d| j        v rdnd}|t          d          k    r||z   S t          |          \  }}|                    d          s|dz  }t          |d|dd         d	|                     |          d|          S )
a  Given path to a .py file, return path to its .pyc/.pyo file.

        This function is inspired by Python 3.2's imp.cache_from_source.

        :param fpath: path to file name
        :param version: Python version

        >>> i = Interpreter('python')
        >>> i.cache_file('foo.py', Version('3.1'))
        'foo.pyc'
        >>> i.cache_file('bar/foo.py', '3.2')
        'bar/__pycache__/foo.cpython-32.pyc'
        z-Ooc3.1z.py__pycache__Nr   )r   r   r   r   endswithr   	magic_tag)r   fpathr   	last_charfdirfnames         r#   
cache_filezInterpreter.cache_file   s     '1T\224<//CCS	genn$$9$$Elle~~e$$ 	UNED-3B3ZZZ!8!8!8!8))*E F F 	Fr%   c                 z   t          |p| j                  }|                     |          \  }}|                    dd          d         }|r2|d                    |          z  }|r|d                    |          z  }| j        r"| j        dk    r|t          d          z  r|dz  }d	                    |          S )
z5Return extension name with soname and multiarch tags.r      r   z.{}z-{}r
   3_dz{}.so)r   r   _get_configr   r5   r   r   )r   r   r   soabi	multiarchr.   s         r#   ext_filezInterpreter.ext_file   s    '1T\22++G44yC##A& 	2ell5)))F 2%,,y111: 	$)y00ws||+ 1dNF~~f%%%r%   c                     t          |p| j                  }| j        dk    r|t          d          z  rdS |                     d|          }t	          |          S )zReturn magic number.r
   rQ   r   z"import imp; print(imp.get_magic()))r   r   r   _executeeval)r   r   r.   s      r#   magic_numberzInterpreter.magic_number   sX    '1T\229	!!g&=!2CWMMF||r%   c                     t          |p| j                  }| j        dk    r|t          d          z  rdS |                     d|          S )zReturn Python magic tag (used in __pycache__ dir to tag files).

        >>> i = Interpreter('python')
        >>> i.magic_tag(version='3.2')
        'cpython-32'
        r
   3.2r   z import imp; print(imp.get_tag()))r   r   r   rX   r6   s     r#   rI   zInterpreter.magic_tag   sO     '1T\229	!!g&?!2}}?IIIr%   c                     t          |p| j                  }	 |                     |          \  }}n-# t          $ r  t                              dd           Y dS w xY w|S )zReturn multiarch tag.zcannot get multiarchTexc_infor   r   r   rS   	Exceptionlogr   r   r   rT   rU   s       r#   rU   zInterpreter.multiarch   sv    '1T\22	#//88E99 	 	 	II,tI<<<22	    1 &AAc                     t          |p| j                  }| j        dk    r,|t          d          z	  rd                    |j                  S d S d S )Nr
   r\   zabi{})r   r   r   r5   majorr6   s     r#   	stableabizInterpreter.stableabi  sU    '1T\229	!!g&?!>>'-000 "!!!r%   c                     t          |p| j                  }	 |                     |          \  }}n-# t          $ r  t                              dd           Y dS w xY w|S )zReturn SOABI flag (used to in .so files).

        >>> i = Interpreter('python')
        >>> i.soabi(version=Version('3.3'))
        'cpython-33m'
        zcannot get soabiTr^   r   r`   rc   s       r#   rT   zInterpreter.soabi	  sw     '1T\22	#//88E99 	 	 	II(4I88822	 rd   c                    t          |p| j                  }d|v r|                    dd          \  }}nd}t                              |          }|sdS |                                }|d         rdS t          | |          }|d         r3d                    |d         d	         |d         d                   |_        |j        s|d
         sd|d         pdv rd|_        	 |	                                \  }}n-# t          $ r  t                              dd           Y dS w xY w|d         }|j        dk    r)|j        dz	  r|                    d          r
|dd         }|d         s|rFd                    ||d         p|          }|d         s|rd                    ||d         p|          }|dz  }||k    rdS t          ||          S )a  Return extension file name if file can be renamed.

        >>> i = Interpreter('python')
        >>> i.check_extname('foo.so', version='3.3') # doctest: +ELLIPSIS
        'foo.cpython-33m-....so'
        >>> i.check_extname('foo.abi3.so', version='3.3')
        >>> i.check_extname('foo/bar/bazmodule.so', version='3.3') # doctest: +ELLIPSIS
        'foo/bar/baz.cpython-33m-....so'
        /rP   r   Nrg   )r   verz{}.{}r   r   dflagsTzcannot get soabi/multiarchr^   r   r
   r\   moduleirT   rU   z{}-{}z.so)r   r   rsplit
EXTFILE_REr9   r:   r   r5   r   rS   ra   rb   r   rH   r   )	r   rM   r   rL   infoirT   rU   r.   s	            r#   check_extnamezInterpreter.check_extname  s    '1T\22%<<,,sA..KD%%D  '' 	F~~ 	Fg...; 	GtE{1~tE{1~FFAIw 	DM 	ST']5Hb-I-IAG	 }}E99 	 	 	II2TIBBBFF	 f6Y19#5&//(:S:SCRC[F= 	PE 	P^^FDM,BUCCFK  PI P [0A0NYOO%F??FD&!!!s   "C: :&D$#D$c                 <   t          |p| j                  }| j        dk    s | j        dk    r|dz	  r|dz  s|dz	  s|dk    rd}nd}|dz  }|                     ||                              d	          }	 t
          j        d
         |d<   n# t          $ r Y nw xY w|S )Nr'   r
   r>   rQ   rE   zimport sysconfig as s;z%from distutils import sysconfig as s;zOprint("__SEP__".join(i or "" for i in s.get_config_vars("SOABI", "MULTIARCH")))__SEP__DEB_HOST_MULTIARCHrP   )r   r   r   rX   r   osenvironKeyError)r   r   cmd	conf_varss       r#   rS   zInterpreter._get_configK  s    '1T\22 9$)y"8"85  #9%,^ #9e# #9'.#~~*CC9C D 	DMM#w//55i@@		:&:;IaLL 	 	 	D	s   6B 
BBTc                    t          |p| j                  }|                     |          d|f}|r || j        j        v r| j        j        |         S t          |          }|d         dk    rIt                              |d                    t          d	                    ||d                             |d         
                                }t          |          dk    r|d         }|r|| j        j        |<   |S )Nz-c
returncoder   stderrz{} failed with status code {}stdoutrP   )r   r   r-   	__class___cacher   rb   r   ra   r5   
splitlineslen)r   commandr   cacheoutputr.   s         r#   rX   zInterpreter._execute^  s    '1T\22::g&&g6 	2W 555>(11!!,1$$IIfX&''';BB7FS_L`aabbb!,,..v;;!AYF 	4-3DN!'*r%   )NNNNNNN)FNNr1   )NT)__name__
__module____qualname__r   r   r   r   r   r   r   r$   r*   r/   r2   r-   staticmethodr   rA   rN   rV   rZ   rI   rU   rg   rT   rs   rS   rX   r   r%   r#   r   r   <   s       DDGEDGFAE04$ $ $ $*( ( (   ( ( (     \0$ $ $ $LF F F F2& & & &   
J 
J 
J 
J	 	 	 	1 1 1 1   "/" /" /" /"b   &     r%   r   )loggingrw   reos.pathr   r   	debpythonr   debpython.versionr   compileVERBOSEr8   rp   	getLoggerr   rb   r   r   r%   r#   <module>r      s   *  				 				               % % % % % %RZ  
 
 RZ   j! 
" g!!u u u u u u u u u ur%   