o
    年f4                     @   sx   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
dejZe
dejZe eZG d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                   @   s   e Zd ZdZdZdZdZdZdZi Z			d)ddZ
dd	 Zd
d Zdd Zdd Zed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+ddZd+d d!Zd+d"d#Zd+d$d%Zd,d'd(ZdS )-InterpreterNpythonFcpython c                 C   s   t  }|d= |d= t|tr#| D ]}	||	 d u r!t||	||	< qn)|rL|dd r6|s6t||d< n| |	 D ]\}	}
||	 d u rK|
||	< q=|	 D ]
\}	}
t
| |	|
 qPd S )Nselfvalue. version)locals
isinstancer   keysgetattrreplaceisdigitr   parseitemssetattr)r
   r   pathnamer   debugimploptionsparamskeyvalr	   r	   +/usr/share/python3/debpython/interpreter.py__init__E   s&   
zInterpreter.__init__c                 C   s   |dkr%|r%| drd| jd< n
| drd| jd< d|v r$d| jd< n|d	kr1|d ur1t|}|d
v rC|d u rCt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   r	   r	   r    __setattr__Z   s   



zInterpreter.__setattr__c                 C   s8   | j pd}|| | j7 }| jr|dd| j 7 }|S )Nr    )r   _vstrr   r   r   )r
   resultr	   r	   r    __repr__j   s
   
zInterpreter.__repr__c                 C   s   |  | jS N)r'   r   )r
   r	   r	   r    __str__q   s   zInterpreter.__str__c                 C   sF   | j dkr| jS |r t|| jvr | jrd|S | jt| S | jS )Nr"   zpython{}-dbg)r   r   strr   formatr
   r   r	   r	   r    r'   t   s   

zInterpreter._vstrc                 C   s:   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(   r	   r	   r    r   ~   s   
zInterpreter.parsec                 C   sn   t |p| j}| jdkrd}n|t d> rd| }n|t d> r%d| }nd}|r-d| }|r5d	||f }|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/%s%s)r   r   r   )r
   gdbpackager   r   r	   r	   r    sitedir   s   


zInterpreter.sitedirc                 C   sv   t |p| j}d| jv rdnd}|t dkr|| S t|\}}|ds)|d7 }t|dd|dd	 | ||f 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__z
%s.%s.py%sN)r   r   r   r   endswithr   	magic_tag)r
   fpathr   	last_charfdirfnamer	   r	   r    
cache_file   s   
zInterpreter.cache_filec                 C   s~   t |p| j}| |\}}|ddd }|r(|d|7 }|r(|d|7 }| jr:| jdkr:|t d> r:|d7 }d	|S )
z5Return extension name with soname and multiarch tags.r      r   z.{}z-{}r   3_dz{}.so)r   r   _get_configr   r-   r   r   )r
   r   r   soabi	multiarchr(   r	   r	   r    ext_file   s   

zInterpreter.ext_filec                 C   s<   t |p| j}| jdkr|t d> rdS | d|}t|S )zReturn magic number.r   rE   r   z"import imp; print(imp.get_magic()))r   r   r   _executeeval)r
   r   r(   r	   r	   r    magic_number   s
   zInterpreter.magic_numberc                 C   s4   t |p| j}| jdkr|t d> 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   rK   r.   r	   r	   r    r>      s   zInterpreter.magic_tagc                 C   sF   t |p| j}z
| |\}}W |S  ty"   tjddd Y dS w )zReturn multiarch tag.zcannot get multiarchTexc_infor   r   r   rG   	Exceptionlogr   r
   r   rH   rI   r	   r	   r    rI      s   zInterpreter.multiarchc                 C   s8   t |p| j}| jdkr|t d? rd|jS d S d S )Nr   rN   zabi{})r   r   r   r-   majorr.   r	   r	   r    	stableabi  s   zInterpreter.stableabic                 C   sF   t |p| j}z
| |\}}W |S  ty"   tjddd Y dS w )zReturn SOABI flag (used to in .so files).

        >>> i = Interpreter('python')
        >>> i.soabi(version=Version('3.3'))
        'cpython-33m'
        zcannot get soabiTrO   r   rQ   rT   r	   r	   r    rH   	  s   zInterpreter.soabic           	      C   sl  t |p| j}d|v r|dd\}}nd}t|}|sdS | }|d r)dS t| |d}|d rBd|d d	 |d d |_|jsT|d
 sQd|d pOdv rTd|_z|	 \}}W n t
ym   tjddd Y dS w |d }|jdkr|jd? r|dr|dd }|d s|rd||d p|}|d s|rd||d p|}|d7 }||krd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'
        /rD   r   NrV   )r   verz{}.{}r   r   dflagsTzcannot get soabi/multiarchrO   r   r   rN   moduleirH   rI   z{}-{}z.so)r   r   rsplit
EXTFILE_REr0   r1   r   r-   r   rG   rR   rS   r   r=   r   )	r
   rB   r   rA   infoirH   rI   r(   r	   r	   r    check_extname  s@   


zInterpreter.check_extnamec                 C   s   t |p| j}| jdks!| jdkr$|d? r|d> s!|d? s!|dkr$d}nd}|d7 }| ||d	}z
tjd
 |d< W |S  tyG   Y |S w )Nr"   r   r4   rE   r:   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_MULTIARCHrD   )r   r   r   rK   r   osenvironKeyError)r
   r   cmd	conf_varsr	   r	   r    rG   K  s(   zInterpreter._get_configTc                 C   s   t |p| j}d| ||dd}|r"|| jjv r"| jj| S t|}|d dkr=t	|d  t
d||d |d  }t|dkrM|d }|rU|| jj|< |S )	Nz
{} -c '{}''
returncoder   stderrz{} failed with status code {}stdoutrD   )r   r   r-   r'   r   	__class___cacher   rS   r   rR   
splitlineslen)r
   commandr   cacheoutputr(   r	   r	   r    rK   ^  s   zInterpreter._execute)NNNNNNN)FNNr*   )NT)__name__
__module____qualname__r   r   r   r   r   r   rm   r!   r%   r)   r+   r'   staticmethodr   r7   rC   rJ   rM   r>   rI   rV   rH   r`   rG   rK   r	   r	   r	   r    r   <   s8    




&







1r   )loggingrc   reos.pathr   r   	debpythonr   debpython.versionr   compileVERBOSEr/   r]   	getLoggerrs   rS   r   r	   r	   r	   r    <module>   s   
