17db96d56Sopenharmony_ci:mod:`modulefinder` --- Find modules used by a script
27db96d56Sopenharmony_ci=====================================================
37db96d56Sopenharmony_ci
47db96d56Sopenharmony_ci.. module:: modulefinder
57db96d56Sopenharmony_ci   :synopsis: Find modules used by a script.
67db96d56Sopenharmony_ci
77db96d56Sopenharmony_ci.. sectionauthor:: A.M. Kuchling <amk@amk.ca>
87db96d56Sopenharmony_ci
97db96d56Sopenharmony_ci**Source code:** :source:`Lib/modulefinder.py`
107db96d56Sopenharmony_ci
117db96d56Sopenharmony_ci--------------
127db96d56Sopenharmony_ci
137db96d56Sopenharmony_ciThis module provides a :class:`ModuleFinder` class that can be used to determine
147db96d56Sopenharmony_cithe set of modules imported by a script. ``modulefinder.py`` can also be run as
157db96d56Sopenharmony_cia script, giving the filename of a Python script as its argument, after which a
167db96d56Sopenharmony_cireport of the imported modules will be printed.
177db96d56Sopenharmony_ci
187db96d56Sopenharmony_ci
197db96d56Sopenharmony_ci.. function:: AddPackagePath(pkg_name, path)
207db96d56Sopenharmony_ci
217db96d56Sopenharmony_ci   Record that the package named *pkg_name* can be found in the specified *path*.
227db96d56Sopenharmony_ci
237db96d56Sopenharmony_ci
247db96d56Sopenharmony_ci.. function:: ReplacePackage(oldname, newname)
257db96d56Sopenharmony_ci
267db96d56Sopenharmony_ci   Allows specifying that the module named *oldname* is in fact the package named
277db96d56Sopenharmony_ci   *newname*.
287db96d56Sopenharmony_ci
297db96d56Sopenharmony_ci
307db96d56Sopenharmony_ci.. class:: ModuleFinder(path=None, debug=0, excludes=[], replace_paths=[])
317db96d56Sopenharmony_ci
327db96d56Sopenharmony_ci   This class provides :meth:`run_script` and :meth:`report` methods to determine
337db96d56Sopenharmony_ci   the set of modules imported by a script. *path* can be a list of directories to
347db96d56Sopenharmony_ci   search for modules; if not specified, ``sys.path`` is used.  *debug* sets the
357db96d56Sopenharmony_ci   debugging level; higher values make the class print debugging messages about
367db96d56Sopenharmony_ci   what it's doing. *excludes* is a list of module names to exclude from the
377db96d56Sopenharmony_ci   analysis. *replace_paths* is a list of ``(oldpath, newpath)`` tuples that will
387db96d56Sopenharmony_ci   be replaced in module paths.
397db96d56Sopenharmony_ci
407db96d56Sopenharmony_ci
417db96d56Sopenharmony_ci   .. method:: report()
427db96d56Sopenharmony_ci
437db96d56Sopenharmony_ci      Print a report to standard output that lists the modules imported by the
447db96d56Sopenharmony_ci      script and their paths, as well as modules that are missing or seem to be
457db96d56Sopenharmony_ci      missing.
467db96d56Sopenharmony_ci
477db96d56Sopenharmony_ci   .. method:: run_script(pathname)
487db96d56Sopenharmony_ci
497db96d56Sopenharmony_ci      Analyze the contents of the *pathname* file, which must contain Python
507db96d56Sopenharmony_ci      code.
517db96d56Sopenharmony_ci
527db96d56Sopenharmony_ci   .. attribute:: modules
537db96d56Sopenharmony_ci
547db96d56Sopenharmony_ci      A dictionary mapping module names to modules. See
557db96d56Sopenharmony_ci      :ref:`modulefinder-example`.
567db96d56Sopenharmony_ci
577db96d56Sopenharmony_ci
587db96d56Sopenharmony_ci.. _modulefinder-example:
597db96d56Sopenharmony_ci
607db96d56Sopenharmony_ciExample usage of :class:`ModuleFinder`
617db96d56Sopenharmony_ci--------------------------------------
627db96d56Sopenharmony_ci
637db96d56Sopenharmony_ciThe script that is going to get analyzed later on (bacon.py)::
647db96d56Sopenharmony_ci
657db96d56Sopenharmony_ci   import re, itertools
667db96d56Sopenharmony_ci
677db96d56Sopenharmony_ci   try:
687db96d56Sopenharmony_ci       import baconhameggs
697db96d56Sopenharmony_ci   except ImportError:
707db96d56Sopenharmony_ci       pass
717db96d56Sopenharmony_ci
727db96d56Sopenharmony_ci   try:
737db96d56Sopenharmony_ci       import guido.python.ham
747db96d56Sopenharmony_ci   except ImportError:
757db96d56Sopenharmony_ci       pass
767db96d56Sopenharmony_ci
777db96d56Sopenharmony_ci
787db96d56Sopenharmony_ciThe script that will output the report of bacon.py::
797db96d56Sopenharmony_ci
807db96d56Sopenharmony_ci   from modulefinder import ModuleFinder
817db96d56Sopenharmony_ci
827db96d56Sopenharmony_ci   finder = ModuleFinder()
837db96d56Sopenharmony_ci   finder.run_script('bacon.py')
847db96d56Sopenharmony_ci
857db96d56Sopenharmony_ci   print('Loaded modules:')
867db96d56Sopenharmony_ci   for name, mod in finder.modules.items():
877db96d56Sopenharmony_ci       print('%s: ' % name, end='')
887db96d56Sopenharmony_ci       print(','.join(list(mod.globalnames.keys())[:3]))
897db96d56Sopenharmony_ci
907db96d56Sopenharmony_ci   print('-'*50)
917db96d56Sopenharmony_ci   print('Modules not imported:')
927db96d56Sopenharmony_ci   print('\n'.join(finder.badmodules.keys()))
937db96d56Sopenharmony_ci
947db96d56Sopenharmony_ciSample output (may vary depending on the architecture)::
957db96d56Sopenharmony_ci
967db96d56Sopenharmony_ci    Loaded modules:
977db96d56Sopenharmony_ci    _types:
987db96d56Sopenharmony_ci    copyreg:  _inverted_registry,_slotnames,__all__
997db96d56Sopenharmony_ci    re._compiler:  isstring,_sre,_optimize_unicode
1007db96d56Sopenharmony_ci    _sre:
1017db96d56Sopenharmony_ci    re._constants:  REPEAT_ONE,makedict,AT_END_LINE
1027db96d56Sopenharmony_ci    sys:
1037db96d56Sopenharmony_ci    re:  __module__,finditer,_expand
1047db96d56Sopenharmony_ci    itertools:
1057db96d56Sopenharmony_ci    __main__:  re,itertools,baconhameggs
1067db96d56Sopenharmony_ci    re._parser:  _PATTERNENDERS,SRE_FLAG_UNICODE
1077db96d56Sopenharmony_ci    array:
1087db96d56Sopenharmony_ci    types:  __module__,IntType,TypeType
1097db96d56Sopenharmony_ci    ---------------------------------------------------
1107db96d56Sopenharmony_ci    Modules not imported:
1117db96d56Sopenharmony_ci    guido.python.ham
1127db96d56Sopenharmony_ci    baconhameggs
1137db96d56Sopenharmony_ci
1147db96d56Sopenharmony_ci
115