module_paths.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. """Utility functions for finding modules
  2. Utility functions for finding modules on sys.path.
  3. `find_mod` finds named module on sys.path.
  4. `get_init` helper function that finds __init__ file in a directory.
  5. `find_module` variant of imp.find_module in std_lib that only returns
  6. path to module and not an open file object as well.
  7. """
  8. #-----------------------------------------------------------------------------
  9. # Copyright (c) 2011, the IPython Development Team.
  10. #
  11. # Distributed under the terms of the Modified BSD License.
  12. #
  13. # The full license is in the file COPYING.txt, distributed with this software.
  14. #-----------------------------------------------------------------------------
  15. #-----------------------------------------------------------------------------
  16. # Imports
  17. #-----------------------------------------------------------------------------
  18. from __future__ import print_function
  19. # Stdlib imports
  20. import imp
  21. import os
  22. # Third-party imports
  23. # Our own imports
  24. #-----------------------------------------------------------------------------
  25. # Globals and constants
  26. #-----------------------------------------------------------------------------
  27. #-----------------------------------------------------------------------------
  28. # Local utilities
  29. #-----------------------------------------------------------------------------
  30. #-----------------------------------------------------------------------------
  31. # Classes and functions
  32. #-----------------------------------------------------------------------------
  33. def find_module(name, path=None):
  34. """imp.find_module variant that only return path of module.
  35. The `imp.find_module` returns a filehandle that we are not interested in.
  36. Also we ignore any bytecode files that `imp.find_module` finds.
  37. Parameters
  38. ----------
  39. name : str
  40. name of module to locate
  41. path : list of str
  42. list of paths to search for `name`. If path=None then search sys.path
  43. Returns
  44. -------
  45. filename : str
  46. Return full path of module or None if module is missing or does not have
  47. .py or .pyw extension
  48. """
  49. if name is None:
  50. return None
  51. try:
  52. file, filename, _ = imp.find_module(name, path)
  53. except ImportError:
  54. return None
  55. if file is None:
  56. return filename
  57. else:
  58. file.close()
  59. if os.path.splitext(filename)[1] in [".py", ".pyc"]:
  60. return filename
  61. else:
  62. return None
  63. def get_init(dirname):
  64. """Get __init__ file path for module directory
  65. Parameters
  66. ----------
  67. dirname : str
  68. Find the __init__ file in directory `dirname`
  69. Returns
  70. -------
  71. init_path : str
  72. Path to __init__ file
  73. """
  74. fbase = os.path.join(dirname, "__init__")
  75. for ext in [".py", ".pyw"]:
  76. fname = fbase + ext
  77. if os.path.isfile(fname):
  78. return fname
  79. def find_mod(module_name):
  80. """Find module `module_name` on sys.path
  81. Return the path to module `module_name`. If `module_name` refers to
  82. a module directory then return path to __init__ file. Return full
  83. path of module or None if module is missing or does not have .py or .pyw
  84. extension. We are not interested in running bytecode.
  85. Parameters
  86. ----------
  87. module_name : str
  88. Returns
  89. -------
  90. modulepath : str
  91. Path to module `module_name`.
  92. """
  93. parts = module_name.split(".")
  94. basepath = find_module(parts[0])
  95. for submodname in parts[1:]:
  96. basepath = find_module(submodname, [basepath])
  97. if basepath and os.path.isdir(basepath):
  98. basepath = get_init(basepath)
  99. return basepath