def obf_var(self, var: cst.Name, updated_node: cst.Attribute): name = var.value if self.change_fields and self.can_rename(name, 'cv'): attr = self.get_new_cst_name(name) updated_node = updated_node.with_changes(attr=attr) elif self.change_variables and self.can_rename(name, 'v'): updated_node = updated_node.with_changes() return updated_node
def leave_Attribute(self, original_node: cst.Attribute, updated_node: cst.Attribute) -> cst.Attribute: for matcher, renamed in self.matchers_map.items(): if matchers.matches(updated_node, matcher): return updated_node.with_changes(attr=cst.Name(value=renamed)) return updated_node
def leave_Attribute( self, original_node: cst.Attribute, updated_node: cst.Attribute) -> Union[cst.Name, cst.Attribute]: full_name_for_node = get_full_name_for_node(original_node) if full_name_for_node is None: raise Exception("Could not parse full name for Attribute node.") full_replacement_name = self.gen_replacement(full_name_for_node) # If a node has no associated QualifiedName, we are still inside an import statement. inside_import_statement: bool = not self.get_metadata( QualifiedNameProvider, original_node, set()) if (QualifiedNameProvider.has_name( self, original_node, self.old_name, ) or (inside_import_statement and full_replacement_name == self.new_name)): new_value, new_attr = self.new_module, self.new_mod_or_obj if not inside_import_statement: self.scheduled_removals.add(original_node.value) if full_replacement_name == self.new_name: return updated_node.with_changes( value=cst.parse_expression(new_value), attr=cst.Name(value=new_attr.rstrip(".")), ) return self.gen_name_or_attr_node(new_attr) return updated_node
def get_line_node(level): func = Attribute(value=Name('logging'), attr=Name(level)) node_ = node.with_changes(func=func, args=args) line_node_ = line_node.deep_replace(line_node.body[0].value, node_) line_node_ = line_node_.with_deep_changes( line_node_.trailing_whitespace, comment=comment ) return line_node_
def _get_async_attr_replacement( self, node: cst.Attribute) -> Optional[cst.CSTNode]: value = node.value if m.matches(value, m.Call()): value = cast(cst.Call, value) value_replacement = self._get_async_call_replacement(value) if value_replacement is not None: return node.with_changes(value=value_replacement) return self._get_awaitable_replacement(node)
def leave_Attribute(self, original_node: Attribute, updated_node: Attribute) -> BaseExpression: matcher = self.name_matcher if (matcher and m.matches(updated_node, matcher) and not self.is_wrapped_in_call(original_node) and self.matches_import_scope(original_node)): return updated_node.with_changes( value=Name(self.new_parent_name), attr=Name(self.new_name), ) return super().leave_Attribute(original_node, updated_node)
def leave_Attribute(self, original_node: cst.Attribute, updated_node: cst.Attribute) -> cst.Attribute: for matcher in self.matchers: if matchers.matches(updated_node, matcher): # Ensure that wx.adv is imported AddImportsVisitor.add_needed_import(self.context, "wx.adv") # Return modified node return updated_node.with_changes(value=cst.Attribute( value=cst.Name(value="wx"), attr=cst.Name(value="adv"))) return updated_node
def leave_Attribute(self, original_node: cst.Attribute, updated_node: cst.Attribute) -> cst.CSTNode: """Replace requests attrs with httpx attrs""" if (isinstance(original_node.value, cst.Name) and original_node.value.value == "requests"): mapping = {"Session": "AsyncClient"} return updated_node.with_changes( value=cst.Name("httpx"), attr=cst.Name(mapping[original_node.attr.value]), ) return updated_node
def _check_import_from_parent( self, original_node: ImportFrom, updated_node: ImportFrom ) -> Optional[Union[BaseSmallStatement, RemovalSentinel]]: """ Check for when the parent module of thing to replace is imported. When `parent.module.the_thing` is transformed, detect such import: from parent import module """ # First, exit early if 'import *' is used if isinstance(updated_node.names, ImportStar): return None # Check whether parent module is imported if not import_from_matches(updated_node, self.old_parent_module_parts): return None # Match, update the node an return it new_import_aliases = [] for import_alias in updated_node.names: if import_alias.evaluated_name == self.old_parent_name: self.save_import_scope(original_node) module_name_str = (import_alias.evaluated_alias or import_alias.evaluated_name) self.context.scratch[self.ctx_key_name_matcher] = m.Attribute( value=m.Name(module_name_str), attr=m.Name(self.old_name), ) self.context.scratch[self.ctx_key_new_func] = Attribute( attr=Name(self.new_name), value=Name(import_alias.evaluated_alias or self.new_parent_name), ) if self.old_parent_module_parts != self.new_parent_module_parts: # import statement needs updating AddImportsVisitor.add_needed_import( context=self.context, module=".".join(self.new_parent_module_parts), obj=self.new_parent_name, asname=import_alias.evaluated_alias, ) continue new_import_aliases.append(import_alias) if not new_import_aliases: # Nothing left in the import statement: remove it return RemoveFromParent() # Some imports are left, update the statement new_import_aliases = clean_new_import_aliases(new_import_aliases) return updated_node.with_changes(names=new_import_aliases)
def visit_Attribute(self, node: cst.Attribute) -> None: rule_config = self.context.config.rule_config parenthesize_attribute_config = rule_config.get( self.__class__.__name__, {}) if isinstance(parenthesize_attribute_config, dict) and parenthesize_attribute_config.get( "disabled", False): return if len(node.lpar) == 0: new_node = node.with_changes(lpar=[cst.LeftParen()], rpar=[cst.RightParen()]) self.report( node, "All attributes should be parenthesized.", replacement=new_node, )
def leave_Call(self, original_node: Call, updated_node: Call) -> BaseExpression: if ( is_one_to_one_field(original_node) or is_foreign_key(original_node) ) and not has_on_delete(original_node): AddImportsVisitor.add_needed_import( context=self.context, module="django.db", obj="models", ) updated_args = ( *updated_node.args, Arg( keyword=Name("on_delete"), value=Attribute(value=Name("models"), attr=Name("CASCADE")), ), ) return updated_node.with_changes(args=updated_args) return super().leave_Call(original_node, updated_node)
def leave_Attribute(self, original_node: cst.Attribute, updated_node: cst.Attribute): self.attribute_stack.pop() # x.y. z tail = updated_node.value head = updated_node.attr attrs = split_attribute(tail) # Обфускация метода/поля if m.matches(head, m.Name()): head = cst.ensure_type(head, cst.Name) updated_node = self.obf_var(head, updated_node) elif m.matches(head, m.Call()): head = cst.ensure_type(head, cst.Call) updated_node = self.obf_function_name(head, updated_node) else: pass # Обфускация имени if m.matches(tail, m.Name()): tail = cst.ensure_type(tail, cst.Name) if self.can_rename(tail.value, 'v', 'a', 'ca'): updated_node = updated_node.with_changes( value=self.get_new_cst_name(tail.value)) elif m.matches(tail, m.Subscript()): tail = cst.ensure_type(tail, cst.Subscript) else: pass return updated_node
def leave_Attribute(self, original_node: cst.Attribute, updated_node: cst.Attribute) -> cst.Attribute: if matchers.matches(updated_node, self.matcher): return updated_node.with_changes(attr=cst.Name(value="Colour")) return updated_node
def leave_Attribute(self, original_node: cst.Attribute, updated_node: cst.Attribute) -> cst.Attribute: new_value = updated_node.value.visit(self) final_node = updated_node.with_changes(value=new_value) return final_node