
    f4                         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y)	    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y)InterpreterNpythonFcpython c                    t               }|d= |d= t        |t              r+|j                         D ]  }	||	   	t	        ||	      ||	<    ne|rc|j                  dd      j                         r|st        |      |d<   n2| j                  |      j                         D ]  \  }	}
||	   |
||	<    |j                         D ]  \  }	}
t        | |	|
        y )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#;&")%"5F3K6 }}S"%--/$+ENy! $

5 1 7 7 9 *HCc{*&)s*  	$HCD#s#	$    c                 F   |dk(  rW|rU|j                  d      rd| j                  d<   n |j                  d      rd| j                  d<   d|v r"d| j                  d<   n|d	k(  r|t        |      }|d
v r |t        t        |      | j                  |<   y || j                  |<   y )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ENE77EM")+t"<DMM$"'DMM$r%   c                     | j                   xs d}|| j                  | j                        z  }| j                  r!|ddj	                  | j                        z   z  }|S )Nr    )r   _vstrr   r   r   )r   results     r#   __repr__zInterpreter.__repr__j   sN    b$**T\\**<<cCHHT\\222Fr%   c                 8    | j                  | j                        S N)r-   r   )r   s    r#   __str__zInterpreter.__str__q   s    zz$,,''r%   c                     | j                   dk(  r| j                  S |rLt        |      | j                  vr5| j                  rdj	                  |      S | j                  t        |      z   S | j                  S )Nr'   zpython{}-dbg)r   r   strr   formatr   r   s     r#   r-   zInterpreter._vstrt   s_    9999s7|4994zz%,,W5599s7|++yyr%   c                     t         j                  |       }|si S |j                         }d|v r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   )shebangr.   s     r#   r   zInterpreter.parse~   sT      ""7+I!!# %fY&7&=&=&? @F9r%   c                     t        |xs | j                        }| j                  dk(  rd}n*|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   sz    & '1T\\2 991D&5?D&5?D4D%,D$+T2Dr%   c           	         t        |xs | j                        }d| j                  v rdnd}|t        d      k  r||z   S t        |      \  }}|j	                  d      s|dz  }t        |d|dd d	| j                  |      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4<</CS	gen$9$$Ele~~e$UNED-3BZ!8)*E F 	Fr%   c                 \   t        |xs | j                        }| j                  |      \  }}|j                  dd      d   }|r*|dj	                  |      z  }|r|dj	                  |      z  }| j
                  r"| j                  dk(  r|t        d      z  r|dz  }d	j	                  |      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++G4yC#A&ell5))F%,,y11::$))y0ws|+dNF~~f%%r%   c                     t        |xs | j                        }| j                  dk(  r|t        d      z  ry| j                  d|      }t	        |      S )zReturn magic number.r
   rQ   r   z9import importlib.util; print(importlib.util.MAGIC_NUMBER))r   r   r   _executeeval)r   r   r.   s      r#   magic_numberzInterpreter.magic_number   sK    '1T\\299	!g&=Z\cdF|r%   c                     t        |xs | j                        }| j                  dk(  r|t        d      z  ry| 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
   3.2r   z/import sys; print(sys.implementation.cache_tag))r   r   r   rX   r6   s     r#   rI   zInterpreter.magic_tag   sD     '1T\\299	!g&?}}NPWXXr%   c                     t        |xs | j                        }	 | j                  |      \  }}|S # t        $ r t        j                  dd       Y yw xY w)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   s\    '1T\\2	#//8E9
 	  	II,tI<	   1  AAc                     t        |xs | j                        }| j                  dk(  r*|t        d      z	  rdj                  |j                        S y y )Nr
   r\   zabi{})r   r   r   r5   majorr6   s     r#   	stableabizInterpreter.stableabi  sH    '1T\\299	!g&?>>'--00 '@!r%   c                     t        |xs | j                        }	 | j                  |      \  }}|S # t        $ r t        j                  dd       Y yw xY w)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	  s]     '1T\\2	#//8E9
 	  	II(4I8	rd   c                    t        |xs | j                        }d|v r|j                  dd      \  }}nd}t        j	                  |      }|sy|j                         }|d   ryt        | |      }|d   r#dj                  |d   d	   |d   d         |_        |j                  s|d
   sd|d   xs dv rd|_        	 |j                         \  }}|d   }|j                  dk(  r%|j                  dz	  r|j                  d      r|dd }|d   s|r9dj                  ||d   xs |      }|d   s|rdj                  ||d   xs |      }|dz  }||k(  ryt        ||      S # t        $ r t        j                  dd       Y yw xY w)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%<,,sA.KD%D  '~~g.;tE{1~tE{1~FAIwwDMST']5Hb-IAG	 }}E9 f66Y199#5&//(:SCR[F=E^^FDM,BUCFK I [0A0NYO%F?D&!!  	II2TIB	s   =E    FFc                 @   t        |xs | 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  }| j                  ||      j	                  d	      }	 t
        j                  d
   |d<   |S # t        $ r Y |S w xY w)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 99$))y"85 W^e#w#~*C9C D 	DMM#w/55i@		::&:;IaL   		s   8B 	BBc                    t        |xs | j                        }| j                  |      d|f}|r1|| j                  j                  v r| j                  j                  |   S t        |      }|d   dk7  r6t        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 {}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::g&g6W 5 55>>((11!,1$IIfX&';BB7FS_L`abb!,,.v;!AYF-3DNN!!'*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2&
Y	1"/"b&r%   r   )loggingrw   reos.pathr   r   	debpythonr   debpython.versionr   compileVERBOSEr8   rp   	getLoggerr   rb   r   r   r%   r#   <module>r      sw   *  	 	   %RZZ  

 RZZ   jj!
" g!u ur%   