예제 #1
0
    def test_parse_method(self) -> None:
        class MyClass:

            @staticmethod
            def f(x: int) -> int:
                """Identity, but with more steps"""
                return x

            @staticmethod
            def g(x: int) -> int:
                """Identity, but with more steps

                Culled, as this is a multi-line docstring
                """
                return x

        _, body = task_base.parse_f(MyClass.f)
        self.assertExpectedInline(
            self._indent(body), """\
            \"\"\"Identity, but with more steps\"\"\"
            return x""",
        )

        _, body = task_base.parse_f(MyClass.g)
        self.assertExpectedInline(
            self._indent(body), """\
            return x""",
        )
예제 #2
0
    def test_no_functor(self) -> None:
        class F:

            def __call__(self) -> None:
                pass

        with self.assertRaisesRegex(TypeError, "Expected function, got"):
            task_base.parse_f(F())
예제 #3
0
    def test_parse_with_comments(self) -> None:
        def f(
            x: int,   # This is a comment
            y: bool,  # also a comment

            # More comments.
        ) -> typing.Any:  # Comment on return line.
            """Docstring

            Note: This will be dropped. See `parse_f` for details.
            """

            x += 1

            y = """
                This is preserved.
            """

            # Comment in src.
            return y

        _, body = task_base.parse_f(f)
        self.assertExpectedInline(
            self._indent(body), """\
            x += 1

            y = \"\"\"
                This is preserved.
            \"\"\"

            # Comment in src.
            return y""",
        )
예제 #4
0
    def test_parse_inline(self) -> None:
        def f(x: typing.Any, y: int = 1) -> None: print([x for _ in range(y)])

        _, body = task_base.parse_f(f)
        self.assertExpectedInline(
            self._indent(body), """\
            print([x for _ in range(y)])""",
        )
예제 #5
0
    def test_parse_trivial(self) -> None:
        def f(x: int) -> None:
            pass

        _, body = task_base.parse_f(f)
        self.assertExpectedInline(
            self._indent(body), """\
            pass""",
        )
예제 #6
0
    def test_no_variadic(self) -> None:
        def f(*args) -> None:
            pass

        with self.assertRaisesRegex(
            TypeError,
            r"Variadic positional argument `\*args` not permitted for `run_in_worker` function."
        ):
            task_base.parse_f(f)

        def g(**kwargs) -> None:
            pass

        with self.assertRaisesRegex(
            TypeError,
            r"Variadic keywork argument `\*\*kwargs` not permitted for `run_in_worker` function."
        ):
            task_base.parse_f(g)
예제 #7
0
    def test_fully_typed(self) -> None:
        def f(x):
            pass

        with self.assertRaisesRegex(
            TypeError,
            "Missing type annotation for parameter `x`"
        ):
            task_base.parse_f(f)

        def g(x: int):
            pass

        with self.assertRaisesRegex(
            TypeError,
            "Missing return annotation."
        ):
            task_base.parse_f(g)
예제 #8
0
    def test_no_decorator(self) -> None:

        def my_decorator(f: typing.Callable) -> typing.Callable:

            @functools.wraps(f)
            def g(*args, **kwargs) -> typing.Any:
                return f(*args, **kwargs)

            return g

        @my_decorator
        def f() -> None:
            pass

        with self.assertRaisesRegex(
            TypeError,
            "`f` cannot be decorated below `@run_in_worker`"
        ):
            task_base.parse_f(f)
예제 #9
0
    def test_parse_simple(self) -> None:
        def f(
            x: int,
        ) -> None:
            for _ in range(10):
                pass

        _, body = task_base.parse_f(f)
        self.assertExpectedInline(
            self._indent(body), """\
            for _ in range(10):
                pass""",
        )
예제 #10
0
    def test_parse_pathological(self) -> None:
        def f(
            x: \
            int,
            y: typing.Dict[str, int],
            *,
            z: str,
        # Isn't that a charming (but legal) indentation?
        ) \
        -> typing.Optional[typing.Union[
        float, int]
                    ]:  # Just for good measure.
            """Begin the actual body.

            (For better or worse...)
            """
            del x
            q = y.get(
                z,
                None,
            )

            # Intermediate comment

            if False:
                return 1
            elif q:
                raise ValueError

            q = 1
            # Trailing comment isn't part of the execution, so it is actually
            # dropped by `inspect`. (Surprisingly.)

        _, body = task_base.parse_f(f)
        self.assertExpectedInline(
            self._indent(body), """\
            del x
            q = y.get(
                z,
                None,
            )

            # Intermediate comment

            if False:
                return 1
            elif q:
                raise ValueError

            q = 1""",
        )