def is_class_supported(object_: type) -> bool: return (is_stdlib_callable_supported(object_) and is_not_private(object_) and object_ not in unsupported.classes or not is_stdlib_object(object_) and has_module(object_) and is_supported(catalog.from_string(object_.__module__)))
def visit_ImportFrom(self, node: ast3.ImportFrom) -> None: parent_module_path = catalog.from_string(node.module) for name_alias in node.names: alias_path = to_alias_path(name_alias) actual_path = to_actual_path(name_alias) if actual_path == catalog.WILDCARD_IMPORT: for path, nodes in scoping.factory(parent_module_path).items(): self.batch_register_if_not_found(path, nodes) continue object_path = parent_module_path.join(actual_path) if is_module_path(object_path): for path, nodes in scoping.factory(object_path).items(): self.batch_register(alias_path.join(path), nodes) else: scope = scoping.factory(parent_module_path) target_nodes = scope[actual_path] while isinstance(target_nodes[-1], (ast3.Import, ast3.ImportFrom)): visit_target = (Reducer( scope=scope, module_path=parent_module_path).visit) for target_node in target_nodes: visit_target(target_node) target_nodes = scope[actual_path] self.scope.update(scope) self.scope[alias_path] = target_nodes
def evaluate_attribute(node: ast3.Attribute, *, scope: Scope, module_path: catalog.Path) -> Node: value_path = evaluate_node(node.value, scope=scope, module_path=module_path) return value_path.join(catalog.from_string(node.attr))
def visit_ClassDef(self, node: ast3.ClassDef) -> None: path = catalog.from_string(node.name) self.register(path, node) children_scope = {} visit_child = Registry(scope=children_scope, module_path=self.module_path).visit for child in node.body: visit_child(child) for child_path, child_nodes in children_scope.items(): self.batch_register(path.join(child_path), child_nodes)
def to_parent_module_path(object_: ast3.ImportFrom, *, parent_module_path: catalog.Path) -> catalog.Path: level = object_.level import_is_relative = level > 0 if not import_is_relative: return catalog.from_string(object_.module) depth = (len(parent_module_path.parts) + catalog.is_package(parent_module_path) - level) or None module_path_parts = filter( None, chain(parent_module_path.parts[:depth], (object_.module, ))) return catalog.Path(*module_path_parts)
def any_path_has_origin(*candidates: catalog.Path, candidates_module_path: catalog.Path, candidates_scope: Scope, origin_module_path: catalog.Path, origin_object_path: catalog.Path) -> bool: searcher = partial(search_nodes, scope=candidates_scope) if candidates_module_path == origin_module_path: return any(path == origin_object_path for path in candidates) for candidate in candidates: try: candidate_nodes = searcher(candidate) except KeyError: if catalog.is_attribute(candidate): parent_nodes = searcher(candidate.parent) if (isinstance(parent_nodes[-1], ast3.Import) and any(to_actual_path(name_alias) == origin_module_path for name_alias in parent_nodes[-1].names)): return (catalog.from_string(candidate.parts[-1]) == origin_object_path) else: origin_node = candidate_nodes[-1] if isinstance(origin_node, ast3.ImportFrom): if (catalog.from_string(origin_node.module) == origin_module_path): try: name_alias = next( name_alias for name_alias in reversed(origin_node.names) if to_alias_path(name_alias) == candidate) except StopIteration: pass else: return (to_actual_path(name_alias) == origin_object_path) return False
def _add(set_: Set[Any], module_name: str, name: str) -> None: module = modules.safe_import(module_name) if module is None: return path = catalog.from_string(name) try: object_ = _search_by_path(module, path) except KeyError: warnings.warn( 'Module "{module}" has no object with name "{name}".'.format( module=module_name, name=path.parts[0])) except AttributeError: warnings.warn( 'Module "{module}" has no object with path "{path}".'.format( module=module_name, path=path)) else: set_.add(object_)
def visit_ClassDef(self, node: ast3.ClassDef) -> None: path = catalog.from_string(node.name) bases = node.bases for base_index, base_node in enumerate(map(self.evaluator, bases)): if not is_link(base_node): base_scope = {} examination.conduct(base_node, scope=base_scope, module_path=self.module_path) for base_object_path, base_object_nodes in base_scope.items(): self.batch_register(base_object_path, base_object_nodes) base_class_path, = [ base_object_path for base_object_path in base_scope if not catalog.is_attribute(base_object_path) ] bases[base_index] = ast3.Name(str(base_class_path), ast3.Load()) else: try: base_nodes = search_nodes(base_node, scope=self.scope) except KeyError: while catalog.is_attribute(base_node): base_node = base_node.parent try: base_nodes = search_nodes(base_node, scope=self.scope) except KeyError: continue else: break else: raise self.visit(base_nodes[-1]) bases = complete_new_style_class_bases(bases) for base_node in map(self.evaluator, bases): base_scope = scoping.to_children_scope(base_node, scope=self.scope) for base_object_path, base_object_nodes in base_scope.items(): self.batch_register_if_not_found( base_object_path.with_parent(path), base_object_nodes) children_scope = {} visit_child = Reducer(scope=children_scope, module_path=path).visit for child in node.body: visit_child(child) for child_path, child_nodes in children_scope.items(): self.batch_register(path.join(child_path), child_nodes)
def to_actual_path(node: ast3.alias) -> catalog.Path: return catalog.from_string(node.name)
def visit_FunctionDef(self, node: ast3.FunctionDef) -> None: self.generic_visit(node) path = catalog.from_string(node.name) self.register(path, node)
def to_namespaces_with_non_empty_objects_paths( namespace: Namespace) -> Strategy[Tuple[Namespace, catalog.Path]]: return strategies.tuples(strategies.just(namespace), strategies.sampled_from([catalog.from_string(name) for name in namespace]) | non_empty_objects_paths)
def evaluate_name_constant(node: ast3.NameConstant, *, scope: Scope, module_path: catalog.Path) -> Node: return catalog.from_string(str(node.value))
def evaluate_ellipsis_or_num(node: Union[ast3.Ellipsis, ast3.Num], *, scope: Scope, module_path: catalog.Path) -> Node: return catalog.from_string(str(Ellipsis))
def evaluate_name(node: ast3.Name, *, scope: Scope, module_path: catalog.Path) -> Node: return catalog.from_string(node.id)
def to_alias_path(node: ast3.alias) -> catalog.Path: return catalog.from_string(to_alias_string(node))
def visit_ClassDef(self, node: ast3.ClassDef) -> None: path = self.resolve_path(catalog.from_string(node.name)) (NamespaceUpdater(namespace=self.namespace, parent_path=path, module_path=self.module_path, is_nested=True).generic_visit(node))
def is_stdlib_object(object_: Any) -> bool: if not has_module(object_): return False top_module_name = catalog.from_string(object_.__module__).parts[0] return top_module_name in stdlib_modules_names
def is_function_supported(object_: FunctionType) -> bool: return (has_module(object_) and is_supported(catalog.from_string(object_.__module__)))