"""
    https://stepik.org/lesson/701986/step/5?unit=702087

    Объявите класс Book для представления информации о книге. Объекты этого класса должны создаваться командами:

>>> book = Book()
>>> book = Book("название", "автор", 100, 1984) # 100 - число страниц, 1984 - год издания

В каждом объекте класса Book автоматически должны формироваться следующие локальные свойства:

title - заголовок книги (строка, по умолчанию пустая строка);
author - автор книги (строка, по умолчанию пустая строка);
pages - число страниц (целое число, по умолчанию 0);
year - год издания (целое число, по умолчанию 0).

Объявите в классе Book магический метод __setattr__ для проверки типов присваиваемых данных локальным свойствам title, author, pages и year. Если типы не соответствуют локальному атрибуту (например, title должна ссылаться на строку, а pages - на целое число), то генерировать исключение командой:

raise TypeError("Неверный тип присваиваемых данных.")
>>> book = Book(1)
Traceback (most recent call last):
    ...
TypeError: Неверный тип присваиваемых данных.

Создайте в программе объект book класса Book для книги:

автор: Сергей Балакирев
заголовок: Python ООП
pages: 123
year: 2022

>>> book = Book("Python ООП", "Сергей Балакирев", 123, 2022)
>>> str(book)
'Python ООП, Сергей Балакирев, 123, 2022'
"""


class Book:
    title: str = ""
    author: str = ""
    pages: int = 0
    year: int = 0

    def __init__(self, *args, **kwargs):
        for src in (zip(self.__annotations__, args), kwargs.items()):
            for k, v in src:
                setattr(self, k, v)

    def __str__(self):
        return f"{self.title}, {self.author}, {self.pages}, {self.year}"

    def __setattr__(self, name: str, value):
        if not isinstance(value, self.__annotations__.get(name, object)):
            raise TypeError("Неверный тип присваиваемых данных.")
        super().__setattr__(name, value)


def tests():
    ...


if __name__ == "__main__":
    import doctest

    doctest.testmod()
    tests()