3
Ĥ[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j
dejZej
dejZe j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f 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d0dd Zd1d!d"Zd2d#d$Zd3d&d'ZdS )4InterpreterNpythonFcpythonc             C   s   t  }|d= |d= t|trJx|j D ]}	||	 d kr&t||	||	< q&W nX|r|jddj rr| rrt||d< n0x.| j|j	 D ]\}	}
||	 d kr|
||	< qW x |j	 D ]\}	}
t
| |	|
 qW d S )Nselfvalue. version)locals
isinstancer   keysgetattrreplaceisdigitr   parseitemssetattr)r	   r
   pathnamer   debugimploptionsZparamskeyval r   +/usr/share/python3/debpython/interpreter.py__init__E   s    
zInterpreter.__init__c             C   s   |dkrJ|rJ|j dr"d| jd< n|j dr6d| jd< d|krbd| jd< n|d	krb|d k	rbt|}|dkr|d krtt|| j|< n
|| j|< d S )Nr   r   r   r   pypyz-dbgTr   r   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| j7 }| jr4|ddj| j 7 }|S )Nr    )r   _vstrr   r   r   )r	   resultr   r   r   __repr__j   s
    
zInterpreter.__repr__c             C   s   | j | 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j|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 j| }|si S |j }d|kr6t|d j |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/z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|\}}|jdsR|d7 }t|dd|dd
 | j||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cz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}| j|\}}|jddd }|rP|dj|7 }|rP|dj|7 }| jrt| jdkrt|t d> rt|d7 }d	j|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 | j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 | j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   z3.2r   z import imp; print(imp.get_tag()))r   r   r   rB   )r	   r   r   r   r   r8      s    zInterpreter.magic_tagc             C   sH   t |p
| j}y| j|\}}W n" tk
rB   tjddd dS X |S )zReturn multiarch tag.zcannot get multiarchT)exc_infor   )r   r   r>   	Exceptionlogr   )r	   r   r?   r@   r   r   r   r@      s    zInterpreter.multiarchc             C   s4   t |p
| j}| jdkr0|t d? r0dj|jS d S )Nr   z3.2zabi{})r   r   r   r+   major)r	   r   r   r   r   	stableabi  s    zInterpreter.stableabic             C   sH   t |p
| j}y| j|\}}W n" tk
rB   tjddd dS X |S )zReturn SOABI flag (used to in .so files).

        >>> i = Interpreter('python')
        >>> i.soabi(version=Version('3.3'))
        'cpython-33m'
        zcannot get soabiT)rE   r   )r   r   r>   rF   rG   r   )r	   r   r?   r@   r   r   r   r?   	  s    zInterpreter.soabic       	      C   s  t |p
| j}d|kr(|jdd\}}nd}tj|}|s>dS |j }|d rRdS t| |d}|d rdj|d d	 |d d |_|j r|d
 sd|d pdkrd|_y|j	 \}}W n" t
k
r   tjddd dS X |d }|jdkr|jd? r|jdr|dd }|d s&|rbdj||d p8|}|d sL|rbdj||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   NrI   )r   verz{}.{}r   r   dflagsTzcannot get soabi/multiarch)rE   r   r   z3.2module   r?   r@   z{}-{}z.soi)r   r   rsplit
EXTFILE_REr-   r.   r   r+   r   r>   rF   rG   r   r7   r   )	r	   r:   r   r9   infoir?   r@   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 }| j||jd	}ytjd
 |d< W n tk
r   Y nX |S )Nr!   r   z2.6r=   z3.1z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   rB   r   osenvironKeyError)r	   r   cmdZ	conf_varsr   r   r   r>   K  s    zInterpreter._get_configTc             C   s   t |p
| j}dj| j||jdd}|rD|| jjkrD| jj| S t|}|d dkrztj	|d  t
dj||d |d j }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   rG   r   rF   
splitlineslen)r	   commandr   cacheoutputr'   r   r   r   rB   ^  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   r^   r    r$   r(   r)   r&   staticmethodr   r1   r;   rA   rD   r8   r@   rI   r?   rT   r>   rB   r   r   r   r   r   <   s2    


&







1
r   )loggingrU   reos.pathr   r   	debpythonr   debpython.versionr   compileVERBOSEr,   rQ   	getLoggerrd   rG   r   r   r   r   r   <module>   s   


