def testGetModuleFromZipPath(self):
        with files.TemporaryDirectory() as t:
            Touch(os.path.join(t, 'foo.py'), 'class Foo(): VALUE=5')
            Touch(os.path.join(t, '__init__.py'), '"""Package marker."""')
            os.makedirs(os.path.join(t, 'pkg'))
            Touch(os.path.join(t, 'pkg', '__init__.py'),
                  '"""Package marker."""')
            Touch(os.path.join(t, 'pkg', 'bar.py'), 'class Bar(): VALUE=7')

            with files.TemporaryDirectory() as zip_tmp_dir:
                zip_pkg = MakeZip(t, zip_tmp_dir, 'pkg')
                foo_mod = pkg_resources.GetModuleFromPath(
                    'my.foo.mod', os.path.join(zip_pkg, 'foo'))
                self.assertIn('my.foo.mod', sys.modules)
                del sys.modules['my.foo.mod']
                self.assertEqual(5, foo_mod.Foo.VALUE)
                self.assertEqual('my.foo.mod', foo_mod.__name__)

                bar_mod = pkg_resources.GetModuleFromPath(
                    'my.bar.mod', os.path.join(zip_pkg, 'pkg', 'bar'))
                self.assertIn('my.bar.mod', sys.modules)
                del sys.modules['my.bar.mod']
                self.assertEqual(7, bar_mod.Bar.VALUE)
                self.assertEqual('my.bar.mod', bar_mod.__name__)
                self.assertEqual('my.bar.mod', bar_mod.Bar.__module__)

                with self.assertRaises(ImportError):
                    pkg_resources.GetModuleFromPath(
                        'my.baz.mod', os.path.join(zip_pkg, 'pkg', 'baz'))
def _GetModuleFromPath(impl_file, path, construction_id):
    """Import the module and dig into it to return the namespace we are after.

  Import the module relative to the top level directory.  Then return the
  actual module corresponding to the last bit of the path.

  Args:
    impl_file: str, The path to the file this was loaded from (for error
      reporting).
    path: [str], A list of group names that got us down to this command group
      with respect to the CLI itself.  This path should be used for things
      like error reporting when a specific element in the tree needs to be
      referenced.
    construction_id: str, A unique identifier for the CLILoader that is
      being constructed.

  Returns:
    The imported module.
  """
    # Make sure this module name never collides with any real module name.
    # Use the CLI naming path, so values are always unique.
    name_to_give = '__calliope__command__.{construction_id}.{name}'.format(
        construction_id=construction_id, name='.'.join(path).replace('-', '_'))
    try:
        return pkg_resources.GetModuleFromPath(name_to_give, impl_file)
    # pylint:disable=broad-except, We really do want to catch everything here,
    # because if any exceptions make it through for any single command or group
    # file, the whole CLI will not work. Instead, just log whatever it is.
    except Exception as e:
        _, _, exc_traceback = sys.exc_info()
        raise CommandLoadFailure('.'.join(path), e), None, exc_traceback
Exemplo n.º 3
0
    def _GetModuleFromPath(self, module_dir, module_path, path,
                           construction_id):
        """Import the module and dig into it to return the namespace we are after.

    Import the module relative to the top level directory.  Then return the
    actual module corresponding to the last bit of the path.

    Args:
      module_dir: str, The path to the tools directory that this command or
        group lives within.
      module_path: [str], The command group names that brought us down to this
        command group or command from the top module directory.
      path: [str], The same as module_path but with the groups named as they
        will be in the CLI.
      construction_id: str, A unique identifier for the CLILoader that is
        being constructed.

    Returns:
      The imported module.
    """
        # Make sure this module name never collides with any real module name.
        # Use the CLI naming path, so values are always unique.
        name_to_give = '__calliope__command__.{construction_id}.{name}'.format(
            construction_id=construction_id,
            name='.'.join(path).replace('-', '_'))
        try:
            return pkg_resources.GetModuleFromPath(
                name_to_give, os.path.join(module_dir, *module_path))
        # pylint:disable=broad-except, We really do want to catch everything here,
        # because if any exceptions make it through for any single command or group
        # file, the whole CLI will not work. Instead, just log whatever it is.
        except Exception as e:
            _, _, exc_traceback = sys.exc_info()
            raise CommandLoadFailure('.'.join(path), e), None, exc_traceback