B €/g^ûYc @sdZddlZddlZddlZddlZddlZddlZddlZddl Z e   ¡e   de ¡ddl Z WdQRXejdZejdZejdZejdZeefZejZiZdd „ZiZd d „ZGd d „d ƒZGdd„dƒZdd„Zedkry eƒZWnek redƒYnXdS)z3Find modules used by a script, using introspection.éNZignoreÚ LOAD_CONSTÚ IMPORT_NAMEÚ STORE_NAMEÚ STORE_GLOBALcCst |g¡ |¡dS©N)ÚpackagePathMapZ setdefaultÚappend)Z packagenameÚpath©r ú$/usr/lib64/python3.7/modulefinder.pyÚAddPackagePathór cCs |t|<dSr)ÚreplacePackageMap)ZoldnameÚnewnamer r r ÚReplacePackage*r rc@seZdZddd„Zdd„ZdS)ÚModuleNcCs(||_||_||_d|_i|_i|_dSr)Ú__name__Ú__file__Ú__path__Ú__code__Ú globalnamesÚ starimports)ÚselfÚnameZfilerr r r Ú__init__0s zModule.__init__cCsLd|jf}|jdk r&|d|jf}|jdk r@|d|jf}|d}|S)Nz Module(%rz, %rz))rrr)rZsr r r Ú__repr__=s   zModule.__repr__)NN)rÚ __module__Ú __qualname__rrr r r r r.s rc@sèeZdZddggfdd„Zdd„Zdd„Zd d „Zd d „Zd d„Zd6dd„Z d7dd„Z dd„Z dd„Z d8dd„Z dd„Zdd„Zdd„Zd d!„Zd9d"d#„Zd$d%„Zd&d'„Zd(d)„Zd*d+„Zd:d,d-„Zd.d/„Zd0d1„Zd2d3„Zd4d5„ZdS);Ú ModuleFinderNrcCsB|dkrtj}||_i|_i|_||_d|_||_||_g|_dS)Nr) ÚsysrÚmodulesÚ badmodulesÚdebugÚindentÚexcludesÚ replace_pathsÚprocessed_paths)rrr!r#r$r r r rHszModuleFinder.__init__cGs^||jkrZxt|jƒD]}tdddqWt|ddx|D]}tt|ƒddqr?r@rA)rrBÚdirrZextrCrDr r r Ú load_fileos   zModuleFinder.load_fileéÿÿÿÿc Cs\| dd||||¡|j||d}| ||¡\}}| ||¡}|sF|S|jrX| ||¡dS)NéÚ import_hook©r,)r1Údetermine_parentÚfind_head_packageÚ load_tailrÚensure_fromlist) rrÚcallerÚfromlistr,ÚparentÚqÚtailÚmr r r rKvs  zModuleFinder.import_hookcCsN| dd||¡|r|dkr,| dd¡dS|j}|dkrÄ|jrH|d8}|dkrx|j|}||ksft‚| dd|¡|S| d¡|krŽtdƒ‚d |  d¡d| …¡}|j|}| dd|¡|S|jrò|j|}||ksàt‚| dd|¡|Sd|kr>|  d¡}|d|…}|j|}|j|ks,t‚| dd|¡|S| dd¡dS) NérMrzdetermine_parent -> Noner3zdetermine_parent ->Ú.zrelative importpath too deep) r6r8rrrZAssertionErrorZcountÚ ImportErrorÚjoinrFÚrfind)rrQr,ZpnamerSr/r r r rMsB            zModuleFinder.determine_parentcCsâ| dd||¡d|kr@| d¡}|d|…}||dd…}n|}d}|r\d|j|f}n|}| |||¡}|rŒ| dd||f¡||fS|rÄ|}d}| |||¡}|rÄ| dd||f¡||fS| dd|¡td |ƒ‚dS) NrWrNrXr3r;ú%s.%szfind_head_package ->ú"raise ImportError: No module namedúNo module named )r6ÚfindrÚ import_moduler8rY)rrSrr/ÚheadrUZqnamerTr r r rN¤s.  zModuleFinder.find_head_packagecCs¢| dd||¡|}xz|rŽ| d¡}|dkr4t|ƒ}|d|…||dd…}}d|j|f}| |||¡}|s| dd|¡td|ƒ‚qW| dd |¡|S) NrWrOrXrr3r\r]r^z load_tail ->)r6r_Úlenrr`r8rY)rrTrUrVr/raZmnamer r r rO¿s zModuleFinder.load_tailcCs„| dd|||¡xl|D]d}|dkrF|s|| |¡}|r|| ||d¡qt||ƒsd|j|f}| |||¡}|std|ƒ‚qWdS)NrWrPÚ*r3r\r^)r1Úfind_all_submodulesrPZhasattrrr`rY)rrVrRZ recursiveÚsubZallÚsubnameZsubmodr r r rPÎs   zModuleFinder.ensure_fromlistc Csø|js dSi}g}|tjjdd…7}|tjjdd…7}|tjjdd…7}x |jD]–}yt |¡}Wn$tk rŒ|  dd|¡wVYnXx\|D]T}d}x6|D].}t |ƒ} || d…|kr¢|d| …}Pq¢W|r”|dkr”|||<q”WqVW|  ¡S)Nr9zcan't list directoryr) rÚ importlibZ machineryZEXTENSION_SUFFIXESZSOURCE_SUFFIXESZBYTECODE_SUFFIXESrEZlistdirZOSErrorr1rbÚkeys) rrVrZsuffixesrGÚnamesrZmodZsuffZnr r r rdÜs.    z ModuleFinder.find_all_submodulescCs| dd|||¡y|j|}Wntk r4YnX| dd|¡|S||jkrb| dd¡dS|r€|jdkr€| dd¡dSy| ||o|j|¡\}}}Wn"tk rÀ| ddd¡dSXz| ||||¡}Wd|rä|  ¡X|röt |||ƒ| dd|¡|S)NrJr`zimport_module ->zimport_module -> None) r6rZKeyErrorr8r rÚ find_modulerYrAÚcloseZsetattr)rZpartnameÚfqnamerSrVrCrBrDr r r r`øs6     zModuleFinder.import_modulec Cs2|\}}}| dd||od|¡|tjkrH| ||¡}| dd|¡|S|tjkrht| ¡d|dƒ} n~|tjkrây| ¡} t j   | |i¡Wn:t k rÈ} z| ddt | ƒ|¡‚Wdd} ~ XYnXt t| ƒdd…¡} nd} | |¡}||_| r |jr| | ¡} | |_| | |¡| dd|¡|S) Nr9rArCzload_module ->Z Zexeczraise ImportError: i)r6r?Z PKG_DIRECTORYÚ load_packager8r@ZcompileZreadZ PY_COMPILEDrgZ_bootstrap_externalZ _classify_pycrYr-ÚmarshalZloadsZ memoryviewÚ add_modulerr$Úreplace_paths_in_coderÚ scan_code) rrlrCrBZ file_infoZsuffixZmodeÚtyperVÚcoZdataZexcr r r rAs4        zModuleFinder.load_modulecCs<||jkri|j|<|r*d|j||j<nd|j|d<dS)Nr3z-)r r)rrrQr r r Ú_add_badmodule4s   zModuleFinder._add_badmodulec Cs||jkr| ||¡dSy|j|||dWn@tk rn}z"| ddt|ƒ¡| ||¡Wdd}~XYn”X|rxŠ|D]‚}||jkr˜| ||¡q|y|j|||g|dWq|tk rü}z.| ddt|ƒ¡|d|}| ||¡Wdd}~XYq|Xq|WdS)NrLr9z ImportError:rX)r rtrKrYr1r-)rrrQrRr,r1reÚfullnamer r r Ú_safe_import_hook<s&      zModuleFinder._safe_import_hookc csø|j}|j}|j}dd„t |¡Dƒ}xÌt|ƒD]À\}\}}|tkrVd||ffVq0|tkr0|dkr0||dd||ddkr’tkr0nq0|||dd} |||dd} | dkrÚd| ||ffVq0d| | ||ffVq0q0WdS) NcSs"g|]\}}}|tkr||f‘qSr )Ú EXTENDED_ARG)Ú.0Z_Úopr0r r r ú Xsz-ModuleFinder.scan_opcodes..Ústorer9r3rÚabsolute_importÚrelative_import) Úco_codeÚco_namesÚ co_constsÚdisZ_unpack_opargsZ enumerateÚ STORE_OPSrr) rrsÚcoderiÚconstsZopargsr/ryZopargr,rRr r r Ú scan_opcodesSs 0zModuleFinder.scan_opcodescCs–|j}|j}xT||ƒD]F\}}|dkr<|\}d|j|<q|dkr|\}}d} |dk rtd|krfd} dd„|Dƒ}|j|||dd| r`d} |jr¬|j |jd |¡} | dkrÀ|j |¡} | dk rú|j | j¡|j  | j ¡| j dkrød|j |<n d|j |<q|d krX|\} }}|r4|j|||| dn"|j || d} |j| jd|ddqt |ƒ‚qWx,|j D]"} t| t|ƒƒrl| | |¡qlWdS) Nr{r3r|rrccSsg|]}|dkr|‘qS)rcr )rxÚfr r r rzusz*ModuleFinder.scan_code..rLrXr})r~r…rrvrrÚgetrZupdaterrrMZ RuntimeErrorr€Ú isinstancerrrq)rrsrVrƒZscannerZwhatr.rrRZ have_starZmmr,rSZcr r r rqhsH          zModuleFinder.scan_codecCs˜| dd||¡t |¡}|r"|}| |¡}||_|g|_|jt |g¡|_| d|j¡\}}}z"| ||||¡|  dd|¡|S|r’|  ¡XdS)Nr9rmrzload_package ->) r6r r‡rorrrrjrAr8rk)rrlrBrrVrCZbufrDr r r rm™s  zModuleFinder.load_packagecCs*||jkr|j|St|ƒ|j|<}|Sr)rr)rrlrVr r r ro®s  zModuleFinder.add_modulecCsr|dk r|jd|}n|}||jkr<| dd|¡t|ƒ‚|dkrf|tjkr`ddddtjffS|j}t  ||¡S)NrXrJzfind_module -> Excludedr;) rr#r8rYrZbuiltin_module_namesr?Z C_BUILTINrrj)rrrrSrur r r rj´s  zModuleFinder.find_modulecCs"tƒtddƒtddƒt|j ¡ƒ}xJ|D]B}|j|}|jrTtdddn tdddtd||jppd ƒq2W| ¡\}}|rÊtƒtd ƒx2|D]*}t|j| ¡ƒ}td |d d  |¡ƒqœW|rtƒtdddtdƒx2|D]*}t|j| ¡ƒ}td |d d  |¡ƒqðWdS)z’Print a report to stdout, listing the found modules with their paths, as well as modules that are missing, or seem to be missing. z %-25s %s)ZNameZFile)ú----r‰ZPr'r(rVz%-25sr;zMissing modules:z?z imported fromz, z7Submodules that appear to be missing, but could also bez#global names in the parent package:N) r*ZsortedrrhrrÚany_missing_mayber rZ)rrhZkeyrVÚmissingÚmayberZmodsr r r ÚreportÅs0         zModuleFinder.reportcCs| ¡\}}||S)z½Return a list of modules that appear to be missing. Use any_missing_maybe() if you want to know which modules are certain to be missing, and which *may* be missing. )rŠ)rr‹rŒr r r Ú any_missingçs zModuleFinder.any_missingcCsØg}g}x¶|jD]¬}||jkr q| d¡}|dkr>| |¡q||dd…}|d|…}|j |¡}|dk r²||j|krˆ| |¡q¼||jkr”q¼|jr¦| |¡q¼| |¡q| |¡qW| ¡| ¡||fS)a®Return two lists, one with modules that are certainly missing and one with modules that *may* be missing. The latter names could either be submodules *or* just global names in the package. The reason it can't always be determined is that it's impossible to tell which names are imported when "from module import *" is done with an extension module, short of actually importing it. rXrr3N) r r#r[rrr‡rrZsort)rr‹rŒrr/rfZpkgnameZpkgr r r rŠïs0           zModuleFinder.any_missing_maybecCstj |j¡}}x2|jD](\}}| |¡r||t|ƒd…}PqW|jr’||jkr’||krt|  dd||f¡n|  dd|f¡|j  |¡t |j ƒ}x8t t|ƒƒD](}t||t|ƒƒrª| ||¡||<qªWt |j|j|j|j|j|jt|ƒ|j|j||j|j|j|j|j ¡S)Nr9zco_filename %r changed to %rz co_filename %r remains unchanged)!rErZnormpathZ co_filenamer$Z startswithrbr!r%r8rZlistr€r)rˆrrrpÚtypesZCodeTypeZ co_argcountZco_kwonlyargcountZ co_nlocalsZ co_stacksizeZco_flagsr~ZtuplerZ co_varnamesZco_nameZco_firstlinenoZ co_lnotabZ co_freevarsZ co_cellvars)rrsZ new_filenameZoriginal_filenamer†r<r„r/r r r rps,        z"ModuleFinder.replace_paths_in_code)NNrI©rI)rrr)rrrrr1r6r8r:rHrKrMrNrOrPrdr`rArtrvr…rqrmrorjrrŽrŠrpr r r r rFs2   #  1 ".rc CsÄddl}y| tjdd…d¡\}}Wn,|jk rR}z t|ƒdSd}~XYnXd}d}g}g}xb|D]Z\}} |dkr‚|d}|dkrŽd}|dkr¦||  tj¡}|dkr²d}|dkrj| | ¡qjW|sÒd } n|d} tj dd…} tj   | ¡| d<|| } |dkr0td ƒx| D]} td t | ƒƒqWt | ||ƒ} xp|dd…D]`}|dkr`d}qJ|rž|d d…d kr’|   |dd …ddg¡n |   |¡n |  |¡qJW|  | ¡|  ¡| S)Nrr3zdmp:qx:z-dz-mz-pz-qz-xzhello.pyzpath:r&iþÿÿÿz.*rc)ÚgetoptrZargvZerrorr*rFrEZpathseprrZdirnamer+rrKrHr:r)r‘Zoptsr.r1r!ZdomodsZaddpathZexcludeZoZaZscriptrZitemÚmfr0r r r Útest:sX      r“r=z [interrupted]) Z__doc__rZimportlib._bootstrap_externalrgZimportlib.machineryrnrErrZwarningsZcatch_warningsZ simplefilterZDeprecationWarningr?Zopmaprrrrr‚rwrr r rrrr“rr’ZKeyboardInterruptr*r r r r Zs@      w;