2

I am implementing an import hook that automatically installs missing modules using pip.

So far it is working OK with simple modules (that have only one level), for instance unipath. However if I try to use it with multilevel imports, such as zope.interface the importer only gets the first part (zope). That causes it to fail as zope does not exist in PyPI.

Any idea of how to achieve getting the full module's name when importing it?

Here some code:

class PipLoader(object):
    def __init__(self):
        self.module = None

    def find_module(self, name, path):
        print "Will install module {}".format(name)
        self.module = None
        sys.meta_path.remove(self)
        try:
            pip_install(name)
            self.module = importlib.import_module(name)
        finally:
            sys.meta_path.append(self)
        return self

    def load_module(self, name):
        if not self.module:
            raise ImportError("Unable to load module")
        module = self.module
        sys.modules[name] = module
        return module

def install():
    sys.meta_path.append(PipLoader())
chaos.ct
  • 1,001
  • 1
  • 7
  • 18
  • Ouch, terrible idea. Don't auto-install; what if there are version incompatibilities? – Martijn Pieters Oct 25 '13 at 18:08
  • 3
    Don't worry @MartijnPieters ! I assure you that the rest of the application is much more unsafe :P It's just for fun. – chaos.ct Oct 25 '13 at 19:31
  • If you replace `__import__` then you get the module globals that of the module imports and much more information. – User Oct 25 '13 at 20:50
  • Thanks @User ! that did the trick. Do you want to write an answer so I can accept it? If not I will just write one myself. – chaos.ct Oct 25 '13 at 23:51
  • I wrote an answer but if you post your code in your answer that would be good. – User Oct 26 '13 at 11:18

1 Answers1

2

If you replace __import__ then you get the module globals that of the module imports and much more information.

User
  • 14,131
  • 2
  • 40
  • 59
  • Thanks! For the record, the actual code using this technique can be found here: https://github.com/chaosct/pipimport/blob/79120eea4aed66743b5dbab47ba18a2d49c19638/pipimport/__init__.py – chaos.ct Oct 27 '13 at 23:09