U zk^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|trF|D]} || dkr$t|| || <q$nR|r|ddrl|slt||d<n,|| D]\} } || dkrz| || <qz| D]\} } t || | qdS)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)rrstrrformatr 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/2.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-Ooc3.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' r3.2r z import imp; print(imp.get_tag()))rrrrDr,r r rr:szInterpreter.magic_tagcCsJt|p |j}z||\}}Wn$tk rDtjdddYdSX|S)zReturn multiarch tag.zcannot get multiarchTexc_infor rrr@ Exceptionlogrr rrArBr r rrBszInterpreter.multiarchcCs4t|p |j}|jdkr0|td?r0d|jSdS)NrrGzabi{})rrrr+majorr,r r r stableabiszInterpreter.stableabicCsJt|p |j}z||\}}Wn$tk rDtjdddYdSX|S)zReturn SOABI flag (used to in .so files). >>> i = Interpreter('python') >>> i.soabi(version=Version('3.3')) 'cpython-33m' zcannot get soabiTrHr rJrMr r rrA szInterpreter.soabic Cst|p |j}d|kr(|dd\}}nd}t|}|s>dS|}|drRdSt||d}|drd|dd |dd|_|js|d sd |d pdkrd |_z| \}}Wn$t k rt jdd dYdSX|d}|j dkr|jd?r| dr|dd}|ds&|rbd||dp8|}|dsL|rbd||dp^|}|d7}||krxdSt||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 NrO)rZverz{}.{}rrdflagsTzcannot get soabi/multiarchrHrrrGmoduleirArBz{}-{}z.so)rrrsplit EXTFILE_REr.r/rr+rr@rKrLrr9r) r r<rr;infoirArBr'r r r check_extnames>   $  zInterpreter.check_extnamecCst|p |j}|jdksB|jdkrH|d?r2|d>sB|d?sB|dkrHd}nd}|d7}|||d }ztjd |d <Wntk rYnX|S) Nr!rr1r?r6zimport 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>)rrrrDrosenvironKeyError)r rcmdZ conf_varsr r rr@Ks&zInterpreter._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___cacherrLrrK splitlineslen)r Zcommandrcacheoutputr'r r rrD^s     zInterpreter._execute)NNNNNNN)FNN)N)N)N)N)N)N)N)N)N)NT)__name__ __module__ __qualname__rrrrrrrbr r$r(r)r& staticmethodrr3r=rCrFr:rBrOrArXr@rDr r r rr<s:    &      1 r)ZloggingrYreos.pathrrZ debpythonrZdebpython.versionrcompileVERBOSEr-rUZ getLoggerrgrLrr r r rs