pX4@sddlZddlZddlZddlmZmZddlmZddlm Z ej dej Z ej dej Z ejeZGdddZdS) N)joinsplit)execute)Versionz (?:\#!\s*){0,1} # shebang prefix (?P .*?/bin/.*?)? (?P python|pypy) (?P \d[\.\d]*)? (?P -dbg)? (?P.*) a- (?P.*?) (?:\. (?Pabi\d+) |(?:\. (?P (?Pcpython|pypy) - (?P\d{2}) (?P[a-z]*?) ) (?: -(?P[^/]*?) )? ))? (?P_d)? \.so$c @sKeZdZdZdZdZdZdZfZiZ dddddddddZ ddZ d d Z d d Z d dZeddZdddddZdddZdddZdddZdddZdddZdddZddd Zdd!d"Zdd#d$Zdd%d&d'ZdS)( InterpreterNpythonFcpythonc Cs t}|d=|d=t|trcx|jD])} || dkr3t|| || >> 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_REsearch groupdicttupler)Zshebangr'rrrr~s  zInterpreter.parsecCst|p|j}|jdkr-d}n@|td>rJd|}n#|td>rgd|}nd}|r}d|}|rd ||f}|S) aReturn 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/z2.6z /usr/lib/python%s/site-packages/z3.0z /usr/lib/python%s/dist-packages/z/usr/lib/python3/dist-packages/z/usr/lib/debug%sz debian/%s%s)rr r)r Zgdbpackager rrrrsitedirs    zInterpreter.sitedircCst|p|j}d|jkr*dnd}|tdkrJ||St|\}}|jdsu|d7}t|dd|dd |j||fS) aGiven 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-Oocz3.1z.py __pycache__z %s.%s.py%sN)rr rrendswithr magic_tag)r Zfpathr Z last_charfdirfnamerrr cache_files  zInterpreter.cache_filecCst|p|j}|j|\}}|jddd}|rr|dj|7}|rr|dj|7}|jr|jdkr|td>r|d7}d j|S) z5Return extension name with soname and multiarch tags.r rz.{}z-{}r3Z_dz{}.so)rr _get_configrr+rr)r rr soabi multiarchr'rrrext_files zInterpreter.ext_filecCsTt|p|j}|jdkr8|td>r8dS|jd|}t|S)zReturn magic number.rr=r z"import imp; print(imp.get_magic()))rr r_executeeval)r r r'rrr magic_numbers zInterpreter.magic_numbercCsHt|p|j}|jdkr8|td>r8dS|jd|S)zReturn Python magic tag (used in __pycache__ dir to tag files). >>> i = Interpreter('python') >>> i.magic_tag(version='3.2') 'cpython-32' rz3.2r z import imp; print(imp.get_tag()))rr rrB)r r rrrr8szInterpreter.magic_tagc Cs^t|p|j}y|j|\}}Wn)tk rYtjddddSYnX|S)zReturn multiarch tag.zcannot get multiarchexc_infoTr )rr r> Exceptionlogr)r r r?r@rrrr@s  zInterpreter.multiarchcCsHt|p|j}|jdkrD|td?rDdj|jSdS)Nrz3.2zabi{})rr rr+major)r r rrr stableabiszInterpreter.stableabic Cs^t|p|j}y|j|\}}Wn)tk rYtjddddSYnX|S)zReturn SOABI flag (used to in .so files). >>> i = Interpreter('python') >>> i.soabi(version=Version('3.3')) 'cpython-33m' zcannot get soabirETr )rr r>rFrGr)r r r?r@rrrr? s  zInterpreter.soabic Cst|p|j}d|kr<|jdd\}}nd}tj|}|s[dS|j}|drudSt|d|}|drdj|dd |dd|_|j r|d sd |d pdkrd |_y|j \}}Wn)t k r*t jddd dSYnX|d}|j dkrp|jd?rp|j drp|dd}|ds|rdj||dp|}|ds|rdj||dp|}|d7}||krdSt||S)aReturn 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 NrIr verz{}.{}rrdflagsTzcannot get soabi/multiarchrErrz3.2moduler?r@z{}-{}z.soi)rr rsplit EXTFILE_REr-r.rr+rr>rFrGrr7r) r r:r r9infoir?r@r'rrr check_extnames>     %*    +  zInterpreter.check_extnamec Cst|p|j}|jdks]|jdkrf|d?rG|d>s]|d?s]|dkrfd}nd}|d7}|j||jd }ytjd |d Ks   zInterpreter._get_configTcCst|p|j}dj|j||jdd}|rb||jjkrb|jj|St|}|ddkrtj |dt dj||d|dj }t |dkr|d}|r||jj|<|S) Nz {} -c '{}'' returncoderstderrz{} failed with status code {}stdoutr<) rr r+r&r __class___cacherrGrrF splitlineslen)r commandr cacheoutputr'rrrrB^s'  zInterpreter._execute)__name__ __module__ __qualname__rrr rrrr^r r$r(r)r& staticmethodrr1r;rArDr8r@rIr?rTr>rBrrrrr<s2      &  1r)loggingrUreos.pathrr debpythonrdebpython.versionrcompileVERBOSEr,rQ getLoggerrdrGrrrrrs