def _remover(node: LN, capture: Capture, filename: Filename) -> None: if node.type == 300: for ch in node.post_order(): if isinstance(ch, Leaf) and ch.value == class_name: if ch.next_sibling and ch.next_sibling.value == ",": ch.next_sibling.remove() ch.remove() elif node.type == 311: node.parent.remove() else: node.remove()
def modify_attr(node: LN, capture: Capture, filename: Filename) -> Optional[LN]: node.replace( Call( Name("getattr"), args=[ capture["obj"].clone(), Comma(), Space(), String('"' + capture["attr"].value + '"'), ], ))
def remove_super_init_call_modifier(node: LN, capture: Capture, filename: Filename) -> None: for ch in node.post_order(): if isinstance(ch, Leaf) and ch.value == "super": if any(c.value for c in ch.parent.post_order() if isinstance(c, Leaf)): ch.parent.remove()
def _remover(node: LN, capture: Capture, filename: Filename) -> None: node.remove()
def m_add_type_comment(node: LN, capture: Capture, filename: Filename, threadlocals) -> LN: """ (modifier) Adds type comment annotations for functions, as understood by `mypy --py2` type checking. """ threadlocals.docstring_count += 1 # since we filtered for funcs with a docstring, the initial_indent_node # should be the indent before the start of the docstring quotes. initial_indent = capture["initial_indent_node"] function: Leaf = capture["function_name"] try: doc_annotation = docstring_parser.parse( capture["docstring_node"].value) except parsy.ParseError as e: report_parse_error(e, function) raise Interrupt if not doc_annotation.has_types: raise Interrupt annotation_arg_names = (doc_annotation.arg_types.args.keys() if doc_annotation.arg_types else set()) signature_name, signature_arg_names = threadlocals.signatures[ node.get_lineno()] assert signature_name == function.value, f"{signature_name} != {function.value}" if doc_annotation.arg_types and not annotation_arg_names == set( signature_arg_names): report_doc_args_signature_mismatch_error(function) raise Interrupt # we either have no annotation args, or we do and the names match the signature # are we okay to annotate? # TODO these are currently WARN/FAIL... maybe should be OK/WARN/FAIL # configurably, like for amibiguous types if signature_arg_names and (not doc_annotation.arg_types or not doc_annotation.arg_types.is_fully_typed): report_incomplete_arg_types(function) if not threadlocals.settings.ALLOW_UNTYPED_ARGS: raise Interrupt elif not signature_arg_names and not doc_annotation.arg_types: # special case: replace doc_annotation with one having empty args # (rather than `None`) doc_annotation = TypeSignature.factory( arg_types=ArgTypes.no_args_factory(), return_type=doc_annotation.return_type, ) if not doc_annotation.return_type or not doc_annotation.return_type.is_fully_typed: report_incomplete_return_type(function) if threadlocals.settings.REQUIRE_RETURN_TYPE: raise Interrupt # yes, annotate... threadlocals.typed_docstring_count += 1 # print(doc_annotation.return_type, doc_annotation.return_type.is_fully_typed, doc_annotation.return_type.name is ReturnsSection.YIELDS) if (doc_annotation.return_type and doc_annotation.return_type.is_fully_typed and doc_annotation.return_type.name is ReturnsSection.YIELDS): report_generator_annotation(function) # record the types we found in this docstring # and warn/fail on ambiguous types according to IMPORT_COLLISION_POLICY name_to_strategy: Dict[str, ImportStrategy] = {} for name in doc_annotation.type_names(): try: name_to_strategy[ name] = threadlocals.import_strategist.get_for_name(name) except AmbiguousTypeError as e: report_ambiguous_type_error(e, function) if e.should_fail: raise Interrupt record_type_names(name_to_strategy) # add the type comment as first line of func body (before docstring) type_comment = get_type_comment(doc_annotation, name_to_strategy) initial_indent.prefix = f"{initial_indent}{type_comment}\n" threadlocals.comment_count += 1 # remove types from docstring new_docstring_node = capture["docstring_node"].clone() new_docstring_node.value = remove_types( docstring=capture["docstring_node"].value, signature=doc_annotation, ) capture["docstring_node"].replace(new_docstring_node) return node
def _remover(node: LN, capture: Capture, filename: Filename) -> None: if node.type not in (300, 311): # remove only definition node.remove()
def corrector(node: LN, capture: Capture, filename: Filename) -> Optional[LN]: node.value = fix_spelling(node.value) return node