Example #1
0
    def _find_sane_parent(self, fullname):
        """
        Iteratively search :data:`sys.modules` for the least indirect parent of
        `fullname` that is loaded and contains a :data:`__path__` attribute.

        :return:
            `(parent_name, path, modpath)` tuple, where:

                * `modname`: canonical name of the found package, or the empty
                   string if none is found.
                * `search_path`: :data:`__path__` attribute of the least
                   indirect parent found, or :data:`None` if no indirect parent
                   was found.
                * `modpath`: list of module name components leading from `path`
                   to the target module.
        """
        path = None
        modpath = []
        while True:
            pkgname, _, modname = str_rpartition(to_text(fullname), u'.')
            modpath.insert(0, modname)
            if not pkgname:
                return [], None, modpath

            pkg = sys.modules.get(pkgname)
            path = getattr(pkg, '__path__', None)
            if pkg and path:
                return pkgname.split('.'), path, modpath

            LOG.debug('%r: %r lacks __path__ attribute', self, pkgname)
            fullname = pkgname
Example #2
0
    def find(self, fullname):
        if fullname not in sys.modules:
            # Don't attempt this unless a module really exists in sys.modules,
            # else we could return junk.
            return

        pkgname, _, modname = str_rpartition(to_text(fullname), u'.')
        pkg = sys.modules.get(pkgname)
        if pkg is None or not hasattr(pkg, '__file__'):
            LOG.debug('%r: %r is not a package or lacks __file__ attribute',
                      self, pkgname)
            return

        pkg_path = [os.path.dirname(pkg.__file__)]
        try:
            fp, path, (suffix, _, kind) = imp.find_module(modname, pkg_path)
        except ImportError:
            e = sys.exc_info()[1]
            LOG.debug('%r: imp.find_module(%r, %r) -> %s', self, modname,
                      [pkg_path], e)
            return None

        if kind == imp.PKG_DIRECTORY:
            return self._found_package(fullname, path)
        else:
            return self._found_module(fullname, path, fp)
Example #3
0
    def activate(self, pool, service_name, msg):
        mod_name, _, class_name = str_rpartition(service_name, '.')
        if msg and not self.is_permitted(mod_name, class_name, msg):
            raise mitogen.core.CallError(self.not_active_msg, service_name)

        module = mitogen.core.import_module(mod_name)
        klass = getattr(module, class_name)
        service = klass(router=pool.router)
        pool.add(service)
        return service
Example #4
0
    def _forward_one_module(self, context, fullname):
        path = []
        while fullname:
            path.append(fullname)
            fullname, _, _ = str_rpartition(fullname, u'.')

        stream = self._router.stream_by_id(context.context_id)
        for fullname in reversed(path):
            self._send_module_and_related(stream, fullname)
            self._send_forward_module(stream, context, fullname)
Example #5
0
 def _iter_parents(fullname):
     """
     >>> list(ParentEnumerationMethod._iter_parents('a'))
     [('', 'a')]
     >>> list(ParentEnumerationMethod._iter_parents('a.b.c'))
     [('a.b', 'c'), ('a', 'b'), ('', 'a')]
     """
     while fullname:
         fullname, _, modname = str_rpartition(fullname, u'.')
         yield fullname, modname
Example #6
0
 def _get_module_package(self):
     """
     Since Ansible 2.9 __package__ must be set in accordance with an
     approximation of the original package hierarchy, so that relative
     imports function correctly.
     """
     pkg, sep, modname = str_rpartition(self.py_module_name, '.')
     if not sep:
         return None
     if mitogen.core.PY3:
         return pkg
     return pkg.encode()
Example #7
0
 def load_module(self, fullname):
     path, is_pkg = self._by_fullname[fullname]
     source = ansible_mitogen.target.get_small_file(self._context, path)
     code = compile(source, path, 'exec', 0, 1)
     mod = sys.modules.setdefault(fullname, imp.new_module(fullname))
     mod.__file__ = "master:%s" % (path, )
     mod.__loader__ = self
     if is_pkg:
         mod.__path__ = []
         mod.__package__ = str(fullname)
     else:
         mod.__package__ = str(str_rpartition(to_text(fullname), '.')[0])
     exec(code, mod.__dict__)
     self._loaded.add(fullname)
     return mod
Example #8
0
    def _get_module_via_parent_enumeration(self, fullname):
        """
        Attempt to fetch source code by examining the module's (hopefully less
        insane) parent package. Required for older versions of
        ansible.compat.six and plumbum.colors.
        """
        if fullname not in sys.modules:
            # Don't attempt this unless a module really exists in sys.modules,
            # else we could return junk.
            return

        pkgname, _, modname = str_rpartition(to_text(fullname), u'.')
        pkg = sys.modules.get(pkgname)
        if pkg is None or not hasattr(pkg, '__file__'):
            return

        pkg_path = os.path.dirname(pkg.__file__)
        try:
            fp, path, ext = imp.find_module(modname, [pkg_path])
            try:
                path = self._py_filename(path)
                if not path:
                    fp.close()
                    return

                source = fp.read()
            finally:
                if fp:
                    fp.close()

            if isinstance(source, mitogen.core.UnicodeType):
                # get_source() returns "string" according to PEP-302, which was
                # reinterpreted for Python 3 to mean a Unicode string.
                source = source.encode('utf-8')
            return path, source, False
        except ImportError:
            e = sys.exc_info()[1]
            LOG.debug('imp.find_module(%r, %r) -> %s', modname, [pkg_path], e)
Example #9
0
    def _forward_one_module(self, context, fullname):
        forwarded = self._forwarded_by_context.get(context)
        if forwarded is None:
            forwarded = set()
            self._forwarded_by_context[context] = forwarded

        if fullname in forwarded:
            return

        path = []
        while fullname:
            path.append(fullname)
            fullname, _, _ = str_rpartition(fullname, u'.')

        stream = self._router.stream_by_id(context.context_id)
        if stream is None:
            LOG.debug('%r: dropping forward of %s to no longer existent '
                      '%r', self, path[0], context)
            return

        for fullname in reversed(path):
            self._send_module_and_related(stream, fullname)
            self._send_forward_module(stream, context, fullname)
Example #10
0
 def generate_parent_names(self, fullname):
     while '.' in fullname:
         fullname, _, _ = str_rpartition(to_text(fullname), u'.')
         yield fullname