コード例 #1
0
ファイル: test_parsers.py プロジェクト: danielebra/doctrans
    def test_from_method_in_memory_return_complex(self) -> None:
        """
        Tests that `parse.function` produces properly from a function in memory of current interpreter with:
        - complex return type
        - kwonly args
        """

        method_complex_args_variety_with_imports_str = (
            "from sys import stdout\n"
            "from {package} import Literal\n"
            "{body}".format(
                package="typing" if PY_GTE_3_8 else "typing_extensions",
                body=function_adder_str,
            ))
        add_6_5 = getattr(
            inspectable_compile(method_complex_args_variety_with_imports_str),
            "add_6_5",
        )

        ir = parse.function(add_6_5)
        del ir["_internal"]  # Not needed for this test

        self.assertDictEqual(
            ir,
            function_adder_ir,
        )
コード例 #2
0
    def test_to_function_with_inline_types(self) -> None:
        """
        Tests that `function` can generate a function_def with inline types
        """
        function_def = deepcopy(
            next(
                filter(
                    rpartial(isinstance, FunctionDef), class_with_method_types_ast.body
                )
            )
        )
        function_name = function_def.name
        function_type = get_function_type(function_def)

        gen_ast = emit.function(
            intermediate_repr=parse.function(
                function_def=function_def,
                function_name=function_name,
                function_type=function_type,
            ),
            function_name=function_name,
            function_type=function_type,
            emit_default_doc=False,
            inline_types=True,
            emit_separating_tab=True,
            indent_level=1,
            emit_as_kwonlyargs=False,
        )
        # emit.file(gen_ast, os.path.join(os.path.dirname(__file__), 'delme.py'), mode='wt')
        run_ast_test(
            self,
            gen_ast=gen_ast,
            gold=function_def,
        )
コード例 #3
0
ファイル: test_parsers.py プロジェクト: danielebra/doctrans
 def test_from_function_kw_only(self) -> None:
     """
     Tests that parse.function produces properly from function with only keyword arguments
     """
     gen_ir = parse.function(function_adder_ast, function_type="static")
     del gen_ir["_internal"]  # Not needed for this test
     self.assertDictEqual(
         gen_ir,
         function_adder_ir,
     )
コード例 #4
0
ファイル: test_parsers.py プロジェクト: danielebra/doctrans
 def test_from_method_complex_args_variety(self) -> None:
     """
     Tests that `parse.function` produces correctly with:
     - kw only args;
     - default args;
     - annotations
     - required;
     - unannotated;
     - splat
     """
     gen_ir = parse.function(method_complex_args_variety_ast)
     del gen_ir["_internal"]  # Not needed for this test
     self.assertDictEqual(
         gen_ir,
         method_complex_args_variety_ir,
     )
コード例 #5
0
    def test_from_function_in_memory(self) -> None:
        """
        Tests that parse.function produces properly from a function in memory of current interpreter
        """
        def foo(a=5, b=6):
            """
            the foo function

            :param a: the a value
            :param b: the b value

            """

        self.assertIsNone(foo(5, 6))

        ir = parse.function(foo)
        del ir["_internal"]  # Not needed for this test
        self.assertDictEqual(
            ir,
            {
                "doc":
                "the foo function",
                "name":
                "TestParsers.test_from_function_in_memory.<locals>.foo",
                "params":
                params_to_ordered_dict((
                    {
                        "default": 5,
                        "doc": "the a value",
                        "name": "a",
                        "typ": "int"
                    },
                    {
                        "default": 6,
                        "doc": "the b value",
                        "name": "b",
                        "typ": "int"
                    },
                )),
                "returns":
                None,
                "type":
                "static",
            },
        )
コード例 #6
0
    def test_from_method_in_memory(self) -> None:
        """
        Tests that `parse.function` produces properly from a function in memory of current interpreter with:
        - kw only args;
        - default args;
        - annotations
        - required;
        - unannotated;
        - splat
        """

        method_complex_args_variety_with_imports_str = (
            "from sys import stdout\n"
            "from {package} import Literal\n"
            "{body}".format(
                package="typing" if PY_GTE_3_8 else "typing_extensions",
                body=method_complex_args_variety_str,
            ))
        call_cliff = getattr(
            inspectable_compile(method_complex_args_variety_with_imports_str),
            "call_cliff",
        )

        ir = parse.function(call_cliff)
        del ir["_internal"]  # Not needed for this test

        # This is a hack because JetBrains wraps stdout
        self.assertIn(
            type(ir["params"]["writer"]["default"]).__name__,
            frozenset(("FlushingStringIO", "TextIOWrapper")),
        )

        # This extra typ is copied, for now. TODO: Update AST-level parser to set types when defaults are given.
        ir["params"]["writer"].update({
            "default":
            "stdout",
            "typ":
            method_complex_args_variety_ir["params"]["writer"]["typ"],
        })

        self.assertDictEqual(
            ir,
            method_complex_args_variety_ir,
        )
コード例 #7
0
 def test_from_function_google_tf_squared_hinge_str_to_class(self) -> None:
     """
     Tests that `emit.function` produces correctly with:
     - __call__
     """
     gen_ast = emit.class_(
         parse.function(
             ast.parse(function_google_tf_squared_hinge_str).body[0],
             infer_type=True,
         ),
         class_name="SquaredHingeConfig",
         emit_call=True,
         emit_default_doc=True,
     )
     run_ast_test(
         self,
         gen_ast=gen_ast,
         gold=class_squared_hinge_config_ast,
     )
コード例 #8
0
ファイル: test_parsers.py プロジェクト: danielebra/doctrans
    def test_from_function(self) -> None:
        """
        Tests that parse.function produces properly
        """
        gen_ir = parse.function(function_default_complex_default_arg_ast)
        gold_ir = {
            "name":
            "call_peril",
            "params":
            OrderedDict((
                (
                    "dataset_name",
                    {
                        "default": "mnist",
                        "typ": "str"
                    },
                ),
                (
                    "writer",
                    {
                        "default":
                        "```{}```".format(
                            paren_wrap_code(
                                get_value(
                                    function_default_complex_default_arg_ast.
                                    args.defaults[1]))),
                    },
                ),
            )),
            "returns":
            None,
            "type":
            "static",
        }

        del gen_ir["_internal"]  # Not needed for this test
        self.assertDictEqual(
            gen_ir,
            gold_ir,
        )
コード例 #9
0
    def test_to_function_with_docstring_types(self) -> None:
        """
        Tests that `function` can generate a function_def with types in docstring
        """

        # Sanity check
        run_ast_test(
            self,
            class_with_method_ast,
            gold=ast.parse(class_with_method_str).body[0],
        )

        function_def = deepcopy(
            next(filter(rpartial(isinstance, FunctionDef), class_with_method_ast.body))
        )
        # Reindent docstring
        function_def.body[0].value.value = "\n{tab}{docstring}\n{tab}".format(
            tab=tab, docstring=reindent(ast.get_docstring(function_def))
        )

        ir = parse.function(function_def)
        gen_ast = emit.function(
            ir,
            function_name=function_def.name,
            function_type=get_function_type(function_def),
            emit_default_doc=False,
            inline_types=False,
            indent_level=1,
            emit_separating_tab=True,
            emit_as_kwonlyargs=False,
        )
        gen_ast.body[0].value.value = "\n{tab}{docstring}\n{tab}".format(
            tab=tab, docstring=reindent(ast.get_docstring(gen_ast))
        )

        run_ast_test(
            self,
            gen_ast=gen_ast,
            gold=function_def,
        )
コード例 #10
0
    def test_from_class_with_body_in_method_to_method_with_body(self) -> None:
        """ Tests if this can make the roundtrip from a full function to a full function """
        annotate_ancestry(class_with_method_and_body_types_ast)

        function_def = next(
            filter(
                rpartial(isinstance, FunctionDef),
                class_with_method_and_body_types_ast.body,
            )
        )
        # Reindent docstring
        function_def.body[0].value.value = "\n{tab}{docstring}\n{tab}".format(
            tab=tab, docstring=reindent(ast.get_docstring(function_def))
        )

        ir = parse.function(
            find_in_ast(
                "C.function_name".split("."),
                class_with_method_and_body_types_ast,
            ),
        )
        gen_ast = emit.function(
            ir,
            emit_default_doc=False,
            function_name="function_name",
            function_type="self",
            indent_level=1,
            emit_separating_tab=True,
            emit_as_kwonlyargs=False,
        )

        # emit.file(gen_ast, os.path.join(os.path.dirname(__file__), "delme.py"), mode="wt")

        run_ast_test(
            self,
            gen_ast=gen_ast,
            gold=function_def,
        )
コード例 #11
0
def populate_files(tempdir, input_module_str=None):
    """
    Populate files in the tempdir

    :param tempdir: Temporary directory
    :type tempdir: ```str```

    :param input_module_str: Input string to write to the input_filename. If None, uses preset mock module.
    :type input_module_str: ```Optional[str]```

    :return: input filename, input str, expected_output
    :rtype: ```Tuple[str, str, str, Module]```
    """
    input_filename = os.path.join(tempdir, "input.py")
    input_class_name = "Foo"
    input_class_ast = emit.class_(
        parse.function(deepcopy(method_adder_ast)),
        emit_call=False,
        class_name=input_class_name,
    )

    input_module_ast = Module(
        body=[
            input_class_ast,
            Assign(
                targets=[Name("input_map", Store())],
                value=Dict(
                    keys=[set_value(input_class_name)],
                    values=[Name(input_class_name, Load())],
                    expr=None,
                ),
                expr=None,
                lineno=None,
                **maybe_type_comment
            ),
            Assign(
                targets=[Name("__all__", Store())],
                value=List(
                    ctx=Load(),
                    elts=[set_value(input_class_name), set_value("input_map")],
                    expr=None,
                ),
                expr=None,
                lineno=None,
                **maybe_type_comment
            ),
        ],
        type_ignores=[],
        stmt=None,
    )

    input_module_str = input_module_str or to_code(input_module_ast)
    # expected_output_class_str = (
    #     "class FooConfig(object):\n"
    #     '    """\n'
    #     "    The amazing Foo\n\n"
    #     "    :cvar a: An a. Defaults to 5\n"
    #     '    :cvar b: A b. Defaults to 16"""\n'
    #     "    a = 5\n"
    #     "    b = 16\n\n"
    #     "    def __call__(self):\n"
    #     "        self.a = 5\n"
    #     "        self.b = 16\n"
    # )
    expected_class_ast = emit.class_(
        parse.function(deepcopy(method_adder_ast)),
        emit_call=True,
        class_name="{input_class_name}Config".format(input_class_name=input_class_name),
    )

    with open(input_filename, "wt") as f:
        f.write(input_module_str)

    return input_filename, input_module_ast, input_class_ast, expected_class_ast