Skip to content

ValueError: Empty body on If when defining class under conditional #352

Closed
@rhaps0dy

Description

Things to check first

  • I have searched the existing issues and didn't find my bug already reported there

  • I have checked that my bug is still present in the latest release

Typeguard version

3.0.2

Python version

3.10.10

What happened?

The following code causes a crash on import/run.

from typeguard import typechecked

if True:
    class A:
        ...

@typechecked
def f(a: A):
    ...

Prints:

Traceback (most recent call last):
  File ".../repro.py", line 8, in <module>
    def f(a: A):
  File ".../python3.10/site-packages/typeguard/_decorators.py", line 175, in typechecked
    retval = instrument(target)
  File ".../python3.10/site-packages/typeguard/_decorators.py", line 75, in instrument
    module_code = compile(module_ast, f.__code__.co_filename, "exec", dont_inherit=True)
ValueError: empty body on If
And indeed the AST contains an empty If statement. Click to expand.
print(ast.dump(module_ast, indent=4))
Module(
    body=[
        ImportFrom(
            module='typeguard',
            names=[
                alias(name='typechecked')],
            level=0),
        If(
            test=Constant(value=True),
            body=[],
            orelse=[]),
        FunctionDef(
            name='f',
            args=arguments(
                posonlyargs=[],
                args=[
                    arg(
                        arg='a',
                        annotation=Name(id='A', ctx=Load()))],
                kwonlyargs=[],
                kw_defaults=[],
                defaults=[]),
            body=[
                ImportFrom(
                    module='typeguard',
                    names=[
                        alias(name='CallMemo')],
                    level=0),
                ImportFrom(
                    module='typeguard._functions',
                    names=[
                        alias(name='check_argument_types')],
                    level=0),
                Assign(
                    targets=[
                        Name(id='call_memo', ctx=Store())],
                    value=Call(
                        func=Name(id='CallMemo', ctx=Load()),
                        args=[
                            Name(id='f', ctx=Load()),
                            Call(
                                func=Name(id='locals', ctx=Load()),
                                args=[],
                                keywords=[])],
                        keywords=[])),
                Expr(
                    value=Call(
                        func=Name(id='check_argument_types', ctx=Load()),
                        args=[
                            Name(id='call_memo', ctx=Load())],
                        keywords=[])),
                Expr(
                    value=Constant(value=Ellipsis))],
            decorator_list=[])],
    type_ignores=[])

I ran into this bug while running the following:

if TYPE_CHECKING:
    class Something:
        ....
else:
    Something = SomethingElse

Maybe intended behavior, and it's not blocking me, but thought it'd be good to submit.

How can we reproduce the bug?

Paste the code above in a file and run it.

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions