'''
Метод __prepare__ вызывается перед __new__
Создает словарь пространства имен cls_dict
'''



class MyMeta(type):

    @staticmethod
    def __prepare__(name, bases, **kwargs):
        print('MyMeta.__prepare__ called... with {kwargs}')
        print()
        kwargs['bonus_attr'] = 'hello'
        return kwargs
    
        '''
        print('name:', name)
        print('base: ', bases)
        print('kwargs: ', kwargs)
        print()
        return {'NAME': 'Billy', 'age': 33}
        '''

    def __new__(cls, name, bases, cls_dict, **kwargs):
        print('MyMeta.__new__ called...')
        print('cls: ', cls, type(cls))
        print('name: ', name, type(name))
        print('bases: ', bases, type(bases))
        print('cls_dict: ', cls_dict, type(cls_dict))
        print('kwargs: ', kwargs)
        return super().__new__(cls, name, bases, cls_dict)
    
class MyClass(metaclass=MyMeta, arg1=10, arg2=15):
    pass

def test_1():
    my_class = MyClass()



class CustomDict(dict):
    def __setitem__(self, key, value):
        print(f'Setting {key} = {value} in custom dictionary')
        super().__setitem__(key, value)

    def __getitem__(self, key):
        print(f'Getting {key} from custom dictionary')
        return int(super().__getitem__(key))


class MyMeta(type):
    @staticmethod
    def __prepare__(name, bases):
        d = CustomDict()
        d[1] = 100
        d['a'] = 'b'
        return d

    def __new__(cls, name, bases, cls_dict):
        print()
        print('metaclass __new__ called...')
        print(f'type(cls_dict) = {type(cls_dict)}')
        print(f'cls_dict={cls_dict}')
        return super().__new__(cls, name, bases, cls_dict)


class MyClass(metaclass=MyMeta):
    pass


print(MyClass.__dict__)



def main():
    test_1()

    
if __name__ == '__main__':
    main()
