Fatal1ty / mashumaro

Fast and well tested serialization library
Apache License 2.0
758 stars 45 forks source link

The types defined inside the function result in syntactically invalid generated code #182

Closed Fatal1ty closed 8 months ago

Fatal1ty commented 9 months ago

Description

If someone puts dataclasses or other types inside a function, a syntax error will occur. This problem first reported in the following pull requests:

What I Did

This code:

def foobar():
    @dataclass
    class Foo:
        foo: int

    @dataclass
    class Bar(DataClassDictMixin):
        foo: Foo

foobar()

leads to this exception:

raise MissingField('foo',__main__.foobar.<locals>.Foo,cls) from None

There is the type_name helper function that may return a string containing <locals> if the type is defined in a function scope. This string may then be used inside the generated code. We need to come up with a general solution because type_name is used widely across all the code base. One way would be a wrapper for type_name helper in CodeBuilder:

def type_name(self, typ, *args, **kwargs) -> str:
    name = type_name(typ, *args, **kwargs)
    if "<locals>" in name:
        name = clean_id(name)
        self.ensure_object_imported(typ, name)
    return name