
NwòVÇ4  ã               @   sª   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 Gd 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            	   @   sK  e  Z d  Z d Z d Z d Z d Z d Z f  Z i  Z	 d d d d d d d d d „ Z
 d d „  Z d	 d
 „  Z d d „  Z d d „  Z e d d „  ƒ Z d d 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& d' „ Z d S)(ÚInterpreterNÚpythonFÚcpythonc             C   s  t  ƒ  } | d =| d =t | t ƒ rc x² | j ƒ  D]) }	 | |	 d  k r3 t | |	 ƒ | |	 <q3 Wnx | rÛ | j d d ƒ j ƒ  r› | r› t | ƒ | d <n@ x= |  j | ƒ j	 ƒ  D]& \ }	 }
 | |	 d  k r± |
 | |	 <q± Wx* | j	 ƒ  D] \ }	 }
 t
 |  |	 |
 ƒ qè Wd  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 ri | ri | j  d ƒ r1 d |  j d <n | j  d ƒ rM d |  j d <d | k r d |  j d <n$ | d	 k r | d  k	 r t | ƒ } | d k r¾ | d  k r¾ t t | ƒ |  j | <n | |  j | <d  S)Nr   r   r   r   Úpypyz-dbgTr   r   r   )znamezimplzdebugzoptions)Ú
startswithÚ__dict__r   r   r   )r	   r   r
   r   r   r   Ú__setattr__Z   s    zInterpreter.__setattr__c             C   sL   |  j  p d } | |  j |  j ƒ 7} |  j rH | 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   s_   |  j  d k r |  j S| rX t | ƒ |  j k rX |  j rG d 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   sO   t  j |  ƒ } | s i  S| j ƒ  } d | k rK t | 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   s—   t  | p |  j ƒ } |  j d k r- d } n@ | t  d ƒ >rJ d | } n# | t  d ƒ >rg d | } n d } | r} d | } | r“ d	 | | 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   s¥   t  | p |  j ƒ } d |  j k r* d n d } | t  d ƒ k rJ | | St | ƒ \ } } | j d ƒ su | 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 } | rr | d j | ƒ 7} | rr | d j | ƒ 7} |  j r¤ |  j d k r¤ | t  d ƒ >r¤ | 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   sT   t  | p |  j ƒ } |  j d k r8 | t  d ƒ >r8 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   sH   t  | p |  j ƒ } |  j d k r8 | t  d ƒ >r8 d S|  j 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   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   s^   t  | p |  j ƒ } y |  j | ƒ \ } } Wn) t k
 rY t j d d d ƒd SYn X| S)zReturn multiarch tag.zcannot get multiarchÚexc_infoTr   )r   r   r>   Ú	ExceptionÚlogr   )r	   r   r?   r@   r   r   r   r@   ø   s    	zInterpreter.multiarchc             C   sH   t  | p |  j ƒ } |  j d k rD | t  d ƒ ?rD d j | j ƒ Sd  S)Nr   z3.2zabi{})r   r   r   r+   Úmajor)r	   r   r   r   r   Ú	stableabi  s    zInterpreter.stableabic             C   s^   t  | p |  j ƒ } y |  j | ƒ \ } } Wn) t k
 rY t j d d d ƒd SYn 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 soabirE   Tr   )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 ru d St |  d | ƒ} | d r¶ d j | d d	 | d d ƒ | _ | j ré | d
 sà d | d pÚ d k ré d | _ y | j	 ƒ  \ } } Wn) t
 k
 r*t j d d d ƒd SYn X| d } | j d k rp| j d ?rp| j d ƒ rp| d d … } | d s€| rÈd j | | d p–| ƒ } | d s¬| rÈd j | | d pÂ| ƒ } | d 7} | | k râd St | | ƒ 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/multiarchrE   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 s] |  j d k rf | d ?rG | d >s] | d ?s] | d k rf d } n d } | d 7} |  j | | ƒ j d	 ƒ } y t j d
 | d <Wn t k
 rº Yn 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 ƒ ƒ } | rb | |  j j k rb |  j j | St | ƒ } | d d k r« t 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)Ú__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   