B \4@sxddlZddlZddlZddlmZmZddlmZddlm Z e dej Z e dej Z eeZGdddZdS) 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@seZdZdZdZdZdZdZdZiZ d)ddZ dd Z d d Z d d Z ddZeddZd*ddZd+ddZd,ddZd-ddZd.ddZd/ddZd0ddZd1d d!Zd2d"d#Zd3d$d%Zd4d'd(ZdS)5 InterpreterNpythonFcpythonc Cst}|d=|d=t|trJx|D]} || dkr&t|| || <q&WnV|r|ddrp|spt||d<n0x.|| D]\} } || dkr| || <qWx | D]\} } t || | qWdS)Nselfvalue.version) locals isinstancerkeysgetattrreplaceisdigitrparseitemssetattr) r r pathnamerdebugimploptionsZparamskeyvalr r +/usr/share/python3/debpython/interpreter.py__init__Es    zInterpreter.__init__cCs|dkrJ|rJ|dr"d|jd<n|dr6d|jd<d|krbd|jd<n|d krb|dk rbt|}|d kr|dkrtt||j|<n ||j|<dS) Nrrrrpypyz-dbgTrr)rrrr) startswith__dict__rrr)r rr r r r __setattr__Zs      zInterpreter.__setattr__cCs8|jpd}|||j7}|jr4|dd|j7}|S)Nr  )r_vstrrrr)r resultr r r__repr__js  zInterpreter.__repr__cCs ||jS)N)r&r)r r r r__str__qszInterpreter.__str__cCsF|jdkr|jS|r@t||jkr@|jr2d|S|jt|S|jS)Nr!z python{}-dbg)rrstrrformat)r rr r rr&ts  zInterpreter._vstrcCs:t|}|siS|}d|kr6t|d|d<|S)aReturn 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_REsearch groupdicttupler)Zshebangr'r r rr~s zInterpreter.parsecCsnt|p |j}|jdkrd}n0|td>r4d|}n|td>rJd|}nd}|rZd|}|rjd ||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)rrr)r Zgdbpackagerrr r rsitedirs      zInterpreter.sitedircCsvt|p |j}d|jkrdnd}|tdkr4||St|\}}|dsR|d7}t|dd|dd |||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)rrrrendswithr magic_tag)r ZfpathrZ last_charfdirfnamer r r cache_files   zInterpreter.cache_filecCs~t|p |j}||\}}|ddd}|rP|d|7}|rP|d|7}|jrt|jdkrt|td>rt|d7}d |S) z5Return extension name with soname and multiarch tags.r rz.{}z-{}r3Z_dz{}.so)rr _get_configrr+rr)r rrsoabi multiarchr'r r rext_files zInterpreter.ext_filecCs<t|p |j}|jdkr(|td>r(dS|d|}t|S)zReturn magic number.rr<r z"import imp; print(imp.get_magic()))rrr_executeeval)r rr'r r r magic_numbers  zInterpreter.magic_numbercCs4t|p |j}|jdkr(|td>r(dS|d|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()))rrrrA)r rr r rr7szInterpreter.magic_tagcCsHt|p |j}y||\}}Wn"tk rBtjddddSX|S)zReturn multiarch tag.zcannot get multiarchT)exc_infor )rrr= Exceptionlogr)r rr>r?r r rr?szInterpreter.multiarchcCs4t|p |j}|jdkr0|td?r0d|jSdS)Nrz3.2zabi{})rrrr+major)r rr r r stableabiszInterpreter.stableabicCsHt|p |j}y||\}}Wn"tk rBtjddddSX|S)zReturn SOABI flag (used to in .so files). >>> i = Interpreter('python') >>> i.soabi(version=Version('3.3')) 'cpython-33m' zcannot get soabiT)rDr )rrr=rErFr)r rr>r?r r rr> szInterpreter.soabic Cst|p |j}d|kr(|dd\}}nd}t|}|s>dS|}|drRdSt||d}|drd|dd |dd|_|js|d sd |d pdkrd |_y| \}}Wn"t k rt jdd ddSX|d}|j dkr|jd?r| dr|dd}|ds$|r`d||dp6|}|dsJ|r`d||dp\|}|d7}||krvdSt||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 NrH)rZverz{}.{}rrdflagsTzcannot get soabi/multiarch)rDrrz3.2moduleir>r?z{}-{}z.so)rrrsplit EXTFILE_REr-r.rr+rr=rErFrr6r) r r9rr8infoir>r?r'r r r check_extnames>   $  zInterpreter.check_extnamecCst|p |j}|jdksB|jdkrH|d?r2|d>sB|d?sB|dkrHd}nd}|d7}|||d }ytjd |d <Wntk rYnX|S) Nr!rz2.6r<z3.1zimport 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__ZDEB_HOST_MULTIARCHr;)rrrrArosenvironKeyError)r rcmdZ conf_varsr r rr=KszInterpreter._get_configTcCst|p |j}d|||dd}|rD||jjkrD|jj|St|}|ddkrzt |dt d||d|d }t |dkr|d}|r||jj|<|S) Nz {} -c '{}'' returncoderstderrz{} failed with status code {}stdoutr;) rrr+r&r __class___cacherrFrrE splitlineslen)r Zcommandrcacheoutputr'r r rrA^s     zInterpreter._execute)NNNNNNN)FNN)N)N)N)N)N)N)N)N)N)NT)__name__ __module__ __qualname__rrrrrrr[r r$r(r)r& staticmethodrr1r:r@rCr7r?rHr>rQr=rAr r r rr<s2   &      1 r)ZloggingrRreos.pathrrZ debpythonrZdebpython.versionrcompileVERBOSEr,rNZ getLoggerr`rFrr r r rs