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
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)
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
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)
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
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()
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
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)
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)
def generate_parent_names(self, fullname): while '.' in fullname: fullname, _, _ = str_rpartition(to_text(fullname), u'.') yield fullname