U
    „zk^Ç4  ã                   @   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d0dd„Zd1d d!„Zd2d"d#„Zd3d$d%„Zd4d'd(„ZdS )5ÚInterpreterNÚpythonFÚcpython© c                 C   sº   t ƒ }|d= |d= t|tƒrF| ¡ D ]}	||	 d kr$t||	ƒ||	< q$nR|r˜| dd¡ ¡ rl|slt|ƒ|d< n,|  |¡ 	¡ D ]\}	}
||	 d krz|
||	< qz| 	¡ D ]\}	}
t
| |	|
ƒ q d S )NÚselfÚvalueÚ.Ú Úversion)ÚlocalsÚ
isinstancer   ÚkeysÚgetattrÚreplaceÚisdigitr   ÚparseÚitemsÚsetattr)r
   r   ÚpathÚnamer   ÚdebugÚimplÚoptionsZparamsÚkeyÚvalr	   r	   ú+/usr/share/python3/debpython/interpreter.pyÚ__init__E   s    

zInterpreter.__init__c                 C   s’   |dkrJ|rJ|  d¡r"d| jd< n|  d¡r6d| jd< d|krbd| jd< n|d	krb|d k	rbt|ƒ}|d
kr„|d kr„tt|ƒ| j|< n
|| 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r4|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kr@| jr2d |¡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|kr6t|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   )Zshebangr'   r	   r	   r   r   ~   s    
zInterpreter.parsec                 C   sn   t |p
| jƒ}| jdkrd}n0|t dƒ> r4d| }n|t dƒ> rJd| }nd}|rZd| }|rjd	||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
   ZgdbÚpackager   r   r	   r	   r   Úsitedir—   s    


zInterpreter.sitedirc                 C   sv   t |p
| jƒ}d| jkrdnd}|t dƒkr4|| S t|ƒ\}}| d¡sR|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
   Zfpathr   Z	last_charÚfdirÚfnamer	   r	   r   Ú
cache_file½   s    
ÿzInterpreter.cache_filec                 C   s~   t |p
| jƒ}|  |¡\}}| dd¡d }|rP|d |¡7 }|rP|d |¡7 }| jrt| jdkrt|t dƒ> rt|d7 }d	 |¡S )
z5Return extension name with soname and multiarch tags.r   é   r   z.{}z-{}r   Ú3Z_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   r?   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 )z«Return 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   rD   r,   r	   r	   r   r:   ì   s    zInterpreter.magic_tagc                 C   sJ   t |p
| jƒ}z|  |¡\}}W n$ tk
rD   tjddd� Y dS X |S )zReturn multiarch tag.zcannot get multiarchT©Úexc_infor   ©r   r   r@   Ú	ExceptionÚlogr   ©r
   r   rA   rB   r	   r	   r   rB   ø   s    zInterpreter.multiarchc                 C   s4   t |p
| jƒ}| jdkr0|t dƒ? r0d |j¡S d S )Nr   rG   zabi{})r   r   r   r+   Úmajorr,   r	   r	   r   Ú	stableabi  s    zInterpreter.stableabic                 C   sJ   t |p
| jƒ}z|  |¡\}}W n$ tk
rD   tjddd� Y dS X |S )z›Return SOABI flag (used to in .so files).

        >>> i = Interpreter('python')
        >>> i.soabi(version=Version('3.3'))
        'cpython-33m'
        zcannot get soabiTrH   r   rJ   rM   r	   r	   r   rA   	  s    zInterpreter.soabic           	      C   s‚  t |p
| jƒ}d|kr(| dd¡\}}nd}t |¡}|s>dS | ¡ }|d rRdS t| |d�}|d r„d |d d	 |d d ¡|_|js¨|d
 s¢d|d pždkr¨d|_z| 	¡ \}}W n$ t
k
rÜ   tjddd� Y dS X |d }|jdk�r|jd? �r| d¡�r|dd… }|d �s&|�rbd ||d �p8|¡}|d �sL|�rbd ||d �p^|¡}|d7 }||k�rxd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'
        ú/r>   r   NrO   )r   Zverz{}.{}r   r   ÚdÚflagsTzcannot get soabi/multiarchrH   r   r   rG   ÚmoduleiúÿÿÿrA   rB   z{}-{}z.so)r   r   ÚrsplitÚ
EXTFILE_REr.   r/   r   r+   r   r@   rK   rL   r   r9   r   )	r
   r<   r   r;   ÚinfoÚirA   rB   r'   r	   r	   r   Úcheck_extname  s>    

$
zInterpreter.check_extnamec                 C   s’   t |p
| jƒ}| jdksB| jdkrH|d? r2|d> sB|d? sB|dkrHd}nd}|d7 }|  ||¡ d	¡}ztjd
 |d< W n tk
rŒ   Y nX |S )Nr!   r   r1   r?   r6   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")))Z__SEP__ZDEB_HOST_MULTIARCHr>   )r   r   r   rD   r   ÚosÚenvironÚKeyError)r
   r   ÚcmdZ	conf_varsr	   r	   r   r@   K  s&    ÿÿþþzInterpreter._get_configTc                 C   s®   t |p
| jƒ}d |  |¡| dd¡¡}|rD|| jjkrD| jj| S t|ƒ}|d dkrzt 	|d ¡ t
d ||d ¡ƒ‚|d  ¡ }t|ƒdkrš|d }|rª|| jj|< |S )	Nz
{} -c '{}'ú'Ú
returncoder   Ústderrz{} failed with status code {}Ústdoutr>   )r   r   r+   r&   r   Ú	__class__Ú_cacher   rL   r   rK   Ú
splitlinesÚlen)r
   Zcommandr   ÚcacheÚoutputr'   r	   r	   r   rD   ^  s    zInterpreter._execute)NNNNNNN)FNN)N)N)N)N)N)N)N)N)N)NT)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   rb   r    r$   r(   r)   r&   Ústaticmethodr   r3   r=   rC   rF   r:   rB   rO   rA   rX   r@   rD   r	   r	   r	   r   r   <   s:         ÿ



&







1
r   )ZloggingrY   ÚreÚos.pathr   r   Z	debpythonr   Zdebpython.versionr   ÚcompileÚVERBOSEr-   rU   Z	getLoggerrg   rL   r   r	   r	   r	   r   Ú<module>   s   õð
