Задача 05J. dataclass_lite

Входной файл:Стандартный вход   Ограничение времени:1 сек
Выходной файл:Стандартный выход   Ограничение памяти:512 Мб
Максимальный балл:1  

Условие

Требуется реализовать на языке Python декоратор dataclass_lite. Декоратор должен добавлять к переданному классу метод __init__, имеющий аргументы, соответствующим полям, заданным в классе, аналогично dataclasses.dataclass. Гарантируется, что класс не определяет функцию __init__. Полученная функция должна удовлетворять следующим требованиям.

Функция dataclass_lite вызывает следующие исключения.

При тестировании попытки в пространстве имён доступны следующие объекты

MISSING = object()

class field:

    def __init__(self, *, default: Any = MISSING, default_factory: Callable[[], Any] | MISSING = MISSING, kw_only: bool = False):
        '''Represents dataclass_lite field.

        Arguments:
            default: default value to be assigned to the field
            default_factory: function to be used to generate default value for the field
            kw_only: indicates if corresponding argument in initialization function is keyword only'''

        if default is not MISSING and default_factory is not MISSING:
            raise ValueError("'default' and 'default_factory' cannot be specified at the same time")

        self.default = default
        self.default_factory = default_factory
        self.kw_only = kw_only

class factory:
    '''A special value to be used as default for fields with factory initialization.'''

    def __repr__(self):
        return '[factory]'

Все тесты используют следующий функционал

from __future__ import annotations

При решении предполагается использование следующих функций и модулей exec, compile, ast.

Формат выходных данных

Код решения должен содержать только импортируемые модули, определение и реализацию функции.

Примеры тестов

Стандартный вход Стандартный выход
1 @dataclass_lite class Person: name: str age: int help(Person.__init__) person1 = Person('Vasya', 23) person2 = Person('Petya', 42) print(person1.name, person1.age) print(person2.name, person2.age)
Help on function __init__ in module __main__:

__init__(self, /, name: 'str', age: 'int')

Vasya 23
Petya 42
2 @dataclass_lite class Person: name: str age: int children: list[Person] = field(default_factory=lambda: [], kw_only=True) help(Person.__init__) person1 = Person('Vasya', 23) person2 = Person('Petya', 42, children=[person1]) print(person1.name, person1.age, person1.children) print(person2.name, person2.age, person2.children[0].name)
Help on function __init__ in module __main__:

__init__(self, /, name: 'str', age: 'int', *, children: 'list[Person]' = [factory])

Vasya 23 []
Petya 42 Vasya

0.070s 0.011s 13