diff --git a/cdd/__init__.py b/cdd/__init__.py index 1f922cb..7c74375 100644 --- a/cdd/__init__.py +++ b/cdd/__init__.py @@ -8,7 +8,7 @@ from logging import getLogger as get_logger __author__ = "Samuel Marks" -__version__ = "0.0.99rc6" +__version__ = "0.0.99rc7" __description__ = ( "Open API to/fro routes, models, and tests. " "Convert between docstrings, classes, methods, argparse, pydantic, and SQLalchemy." diff --git a/cdd/compound/exmod_utils.py b/cdd/compound/exmod_utils.py index 1b2c302..326ed35 100644 --- a/cdd/compound/exmod_utils.py +++ b/cdd/compound/exmod_utils.py @@ -26,7 +26,6 @@ from cdd.shared.pkg_utils import relative_filename from cdd.shared.pure_utils import ( INIT_FILENAME, - no_magic_or_builtin_dir2attr, read_file_to_str, rpartial, sanitise_emit_name, @@ -59,12 +58,12 @@ def get_module_contents(obj, module_root_dir, current_module=None, _result={}): module_root_dir_init = path.join( module_root_dir, "__init__{extsep}py".format(extsep=path.extsep) ) - process_module_contents = partial( - _process_module_contents, - _result=_result, - current_module=current_module, - module_root_dir=module_root_dir, - ) + # process_module_contents = partial( + # _process_module_contents, + # _result=_result, + # current_module=current_module, + # module_root_dir=module_root_dir, + # ) if path.isfile(module_root_dir): with open(module_root_dir, "rt") as f: mod = ast.parse(f.read()) @@ -141,8 +140,8 @@ def get_module_contents(obj, module_root_dir, current_module=None, _result={}): # assert not isinstance( # obj, (int, float, complex, str, bool, type(None)) # ), "module is unexpected type: {!r}".format(type(obj).__name__) - for name, symbol in no_magic_or_builtin_dir2attr(obj).items(): - process_module_contents(name=name, symbol=symbol) + # for name, symbol in no_magic_or_builtin_dir2attr(obj).items(): + # process_module_contents(name=name, symbol=symbol) return _result diff --git a/cdd/shared/ast_utils.py b/cdd/shared/ast_utils.py index 95c5d4a..4015caa 100644 --- a/cdd/shared/ast_utils.py +++ b/cdd/shared/ast_utils.py @@ -1,5 +1,5 @@ """ -ast_utils, bunch of helpers for converting input into ast.* input_str +ast_utils, a bunch of helpers for converting input into ast.* input_str """ import ast @@ -1668,46 +1668,46 @@ def merge_modules(mod0, mod1, remove_imports_from_second=True, deduplicate_names if remove_imports_from_second else deepcopy(mod1_body) ) - if deduplicate_names: - - def unique_nodes(node): - """ - :param node: AST node - :type node: ```AST``` - - :return: node if name is in `seen` set else None; with side-effect of adding to `seen` - :rtype: ```bool``` - """ - - def side_effect_ret(name): - """ - :param name: Name - :type name: ```str``` - - :return: node if name is in `seen` set else None; with side-effect of adding to `seen` - :rtype: ```bool``` - """ - if name in seen: - return None - else: - seen.add(node.name) - return node - - if isinstance(node, (FunctionDef, AsyncFunctionDef, ClassDef)): - return side_effect_ret(node.name) - elif isinstance(node, AnnAssign): - return side_effect_ret(get_value(node.target)) - elif isinstance(node, Assign): - return any( - filter( - lambda target: side_effect_ret(get_value(target)), node.targets - ) - ) - else: - return node - - seen = set() - new_mod.body = list(filter(None, map(unique_nodes, new_mod.body))) + # if deduplicate_names: + # + # def unique_nodes(node): + # """ + # :param node: AST node + # :type node: ```AST``` + # + # :return: node if name is in `seen` set else None; with side-effect of adding to `seen` + # :rtype: ```bool``` + # """ + # + # def side_effect_ret(name): + # """ + # :param name: Name + # :type name: ```str``` + # + # :return: node if name is in `seen` set else None; with side-effect of adding to `seen` + # :rtype: ```bool``` + # """ + # if name in seen: + # return None + # else: + # seen.add(node.name) + # return node + # + # if isinstance(node, (FunctionDef, AsyncFunctionDef, ClassDef)): + # return side_effect_ret(node.name) + # elif isinstance(node, AnnAssign): + # return side_effect_ret(get_value(node.target)) + # elif isinstance(node, Assign): + # return any( + # filter( + # lambda target: side_effect_ret(get_value(target)), node.targets + # ) + # ) + # else: + # return node + # + # seen = set() + # new_mod.body = list(filter(None, map(unique_nodes, new_mod.body))) return new_mod diff --git a/cdd/shared/pure_utils.py b/cdd/shared/pure_utils.py index 89d770d..12764aa 100644 --- a/cdd/shared/pure_utils.py +++ b/cdd/shared/pure_utils.py @@ -18,7 +18,6 @@ from sys import stderr, version_info from textwrap import fill as _fill from textwrap import indent -from types import BuiltinFunctionType from typing import Callable, Dict, FrozenSet, Optional, Tuple, Union pp: Callable[[object], None] = PrettyPrinter(indent=4, width=100, stream=stderr).pprint @@ -1120,27 +1119,6 @@ def default(self, obj): ) -def no_magic_or_builtin_dir2attr(p_object): - """ - Dictionary of `dir` without the __ prefix magics (also without _ prefix) - and without builtins - return the names comprising (some of) the attributes - of the given object, and of attributes reachable from it. - - :param p_object: Object - :type p_object: ```Any``` - - :return: Dict of name to attribute value - :rtype: ```dict``` - """ - return { - attr: getattr(p_object, attr) - for attr in dir(p_object) - if not attr.startswith("_") - and not isinstance(getattr(p_object, attr), BuiltinFunctionType) - } - - def pascal_to_upper_camelcase(s): """ Transform pascal input to upper camelcase @@ -1261,7 +1239,6 @@ def namespaced_upper_camelcase_to_pascal(s, sep="__"): "multiline", "namespaced_pascal_to_upper_camelcase", "namespaced_upper_camelcase_to_pascal", - "no_magic_or_builtin_dir2attr", "none_types", "num_of_nls", "omit_whitespace", diff --git a/cdd/tests/mocks/methods.py b/cdd/tests/mocks/methods.py index 2509e0d..8bf02f5 100644 --- a/cdd/tests/mocks/methods.py +++ b/cdd/tests/mocks/methods.py @@ -659,6 +659,8 @@ def add_6_5(*, a=6, b=5): arguments_args=None, identifier_name=None, stmt=None, + lineno=None, + returns=None, ) function_default_complex_default_arg_str = ( diff --git a/cdd/tests/test_shared/test_ast_utils.py b/cdd/tests/test_shared/test_ast_utils.py index 2a40d44..17f034c 100644 --- a/cdd/tests/test_shared/test_ast_utils.py +++ b/cdd/tests/test_shared/test_ast_utils.py @@ -42,6 +42,7 @@ annotate_ancestry, ast_type_to_python_type, cmp_ast, + construct_module_with_symbols, del_ass_where_name, emit_ann_assign, emit_arg, @@ -70,13 +71,14 @@ from cdd.shared.pure_utils import PY3_8, PY_GTE_3_8, tab from cdd.shared.source_transformer import ast_parse from cdd.tests.mocks.argparse import argparse_add_argument_expr -from cdd.tests.mocks.classes import class_ast, class_str -from cdd.tests.mocks.doctrans import function_type_annotated +from cdd.tests.mocks.classes import class_ast, class_doc_str_expr, class_str +from cdd.tests.mocks.doctrans import ann_assign_with_annotation, function_type_annotated from cdd.tests.mocks.gen import import_star_from_input_ast from cdd.tests.mocks.methods import ( class_with_method_and_body_types_ast, class_with_method_and_body_types_str, class_with_optional_arg_method_ast, + function_adder_ast, function_adder_str, ) from cdd.tests.mocks.sqlalchemy import config_decl_base_ast @@ -133,6 +135,29 @@ def test_cmp_ast(self) -> None: """Test `cmp_ast` branch that isn't tested anywhere else""" self.assertFalse(cmp_ast(None, 5)) + def test_construct_module_with_symbols(self) -> None: + """Tests `construct_module_with_symbols` creates a Module with symbols""" + run_ast_test( + self, + gen_ast=construct_module_with_symbols( + Module( + body=[ + class_doc_str_expr, + ann_assign_with_annotation, + function_adder_ast, + ], + type_ignores=[], + stmt=None, + ), + ("add_6_5",), + ), + gold=Module( + body=[function_adder_ast], + type_ignores=[], + stmt=None, + ), + ) + def test_emit_ann_assign(self) -> None: """Tests that AnnAssign is emitted from `emit_ann_assign`""" self.assertIsInstance(class_ast.body[1], AnnAssign)