def test_to_named_class_def(self) -> None: """ Test that find_ast_type gives the wrapped named class back """ class_def = ClassDef( name="foo", bases=tuple(), keywords=tuple(), decorator_list=[], body=[], expr=None, identifier_name=None, ) run_ast_test( self, find_ast_type( Module( body=[ ClassDef( name="bar", bases=tuple(), keywords=tuple(), decorator_list=[], body=[], expr=None, identifier_name=None, ), class_def, ], stmt=None, ), node_name="foo", ), class_def, skip_black=True, )
def test_find_ast_type_fails(self) -> None: """ Test that `find_ast_type` throws the right errors """ self.assertRaises(NotImplementedError, lambda: find_ast_type(None)) self.assertRaises(NotImplementedError, lambda: find_ast_type("")) self.assertRaises(TypeError, lambda: find_ast_type(Module(body=[], stmt=None))) self.assertRaises( NotImplementedError, lambda: find_ast_type( Module( body=[ ClassDef(expr=None, identifier_name=None), ClassDef(expr=None, identifier_name=None), ], stmt=None, )), )
def test_find_ast_type(self) -> None: """ Test that `find_ast_type` gives the wrapped class back """ class_def = ClassDef( name="", bases=tuple(), keywords=tuple(), decorator_list=[], body=[], expr=None, identifier_name=None, ) run_ast_test( self, find_ast_type(Module(body=[class_def], stmt=None)), class_def, skip_black=True, )
def class_( class_def, class_name=None, merge_inner_function=None, infer_type=False, word_wrap=True, ): """ Converts an AST to our IR :param class_def: Class AST or Module AST with a ClassDef inside :type class_def: ```Union[Module, ClassDef]``` :param class_name: Name of `class`. If None, gives first found. :type class_name: ```Optional[str]``` :param merge_inner_function: Name of inner function to merge. If None, merge nothing. :type merge_inner_function: ```Optional[str]``` :param infer_type: Whether to try inferring the typ (from the default) :type infer_type: ```bool``` :param word_wrap: Whether to word-wrap. Set `DOCTRANS_LINE_LENGTH` to configure length. :type word_wrap: ```bool``` :returns: a dictionary of form { "name": Optional[str], "type": Optional[str], "doc": Optional[str], "params": OrderedDict[str, {'typ': str, 'doc': Optional[str], 'default': Any}] "returns": Optional[OrderedDict[Literal['return_type'], {'typ': str, 'doc': Optional[str], 'default': Any}),)]] } :rtype: ```dict``` """ assert not isinstance(class_def, FunctionDef) is_supported_ast_node = isinstance(class_def, (Module, ClassDef)) if not is_supported_ast_node and isinstance(class_def, type): ir = _inspect(class_def, class_name, word_wrap) parsed_body = ast.parse(getsource(class_def).lstrip()).body[0] parsed_body.body = (parsed_body.body if ast.get_docstring(parsed_body) is None else parsed_body.body[1:]) if merge_inner_function is not None: _merge_inner_function( parsed_body, infer_type=infer_type, intermediate_repr=ir, merge_inner_function=merge_inner_function, ) return ir ir["_internal"] = { "body": list( filterfalse( rpartial(isinstance, AnnAssign), parsed_body.body, )), "from_name": class_name, "from_type": "cls", } body_ir = class_( class_def=parsed_body, class_name=class_name, merge_inner_function=merge_inner_function, ) ir_merge(ir, body_ir) return ir assert (is_supported_ast_node ), "Expected 'Union[Module, ClassDef]' got `{!r}`".format( type(class_def).__name__) class_def = find_ast_type(class_def, class_name) doc_str = get_docstring(class_def) intermediate_repr = ({ "name": class_name, "type": "static", "doc": "", "params": OrderedDict(), "returns": None, } if doc_str is None else docstring(get_docstring(class_def).replace( ":cvar", ":param"), emit_default_doc=False)) if "return_type" in intermediate_repr["params"]: intermediate_repr["returns"] = OrderedDict( (("return_type", intermediate_repr["params"].pop("return_type")), )) body = class_def.body if doc_str is None else class_def.body[1:] for e in body: if isinstance(e, AnnAssign): typ = to_code(e.annotation).rstrip("\n") val = (lambda v: { "default": NoneStr } if v is None else { "default": v if type(v).__name__ in simple_types else (lambda value: { "{}": {} if isinstance(v, Dict) else set(), "[]": [], "()": (), }.get(value, parse_to_scalar(value)))(to_code(v).rstrip("\n")) })(get_value(get_value(e))) # if 'str' in typ and val: val["default"] = val["default"].strip("'") # Unquote? typ_default = dict(typ=typ, **val) for key in "params", "returns": if e.target.id in (intermediate_repr[key] or iter(())): intermediate_repr[key][e.target.id].update(typ_default) typ_default = False break if typ_default: k = "returns" if e.target.id == "return_type" else "params" if intermediate_repr.get(k) is None: intermediate_repr[k] = OrderedDict() intermediate_repr[k][e.target.id] = typ_default elif isinstance(e, Assign): val = get_value(e) if val is not None: val = get_value(val) deque( map( lambda target: setitem(*( (intermediate_repr["params"][target.id], "default", val) if target.id in intermediate_repr["params"] else ( intermediate_repr["params"], target.id, { "default": val }, ))), e.targets, ), maxlen=0, ) intermediate_repr.update({ "params": OrderedDict( map( partial(_set_name_and_type, infer_type=infer_type, word_wrap=word_wrap), intermediate_repr["params"].items(), )), "_internal": { "body": list(filterfalse(rpartial(isinstance, (AnnAssign, Assign)), body)), "from_name": class_def.name, "from_type": "cls", }, }) if merge_inner_function is not None: assert isinstance(class_def, ClassDef) _merge_inner_function( class_def, infer_type=infer_type, intermediate_repr=intermediate_repr, merge_inner_function=merge_inner_function, ) # intermediate_repr['_internal']["body"]= list(filterfalse(rpartial(isinstance,(AnnAssign,Assign)),class_def.body)) return intermediate_repr