from functools import wraps


'''
Этот декоратор демонстрирует способ сохранить данные
об исходной функции

def table(func):
    def inner(*args, **kwargs):
        print('<table>')
        func(*args, **kwargs)
        print('</table>')

    inner.__name__ = func.__name__
    inner.__doc__ = func.__name__
    inner.__annotations__ = func.__annotations__
    return inner
'''
    
"""
Это другой способ сохранить данные об исходной функции
"""

def table(func):
    @wraps(func)
    def inner(*args, **kwargs):
        print('<table>')
        func(*args, **kwargs)
        print('</table>')
    return inner


@table
def print_sqr_number(x: int) -> None:
    """
    Печатает квадрат числа x
    :param x
    :retrun: None
    """
    print(x ** 2)


'''
@table
def say_hello(name: str, surname: str) -> None:
    """Функция приветствует человека"""
    print("Hello", name, surname)
'''


@table
def say_bye(name):
    print('Hello', name)


def dec(fn):
    print("Запуск декоратора")
    def wrapper(*args, **kwargs):
        print("Запуск inner")
        return fn(*args, **kwargs)
    return wrapper


@dec
def say_hello() -> None:
    return 'Hello'
    



def main():

    '''    
    print(f'{say_hello.__name__         =  }')
    print(f'{say_hello.__doc__          =  }')
    print(f'{say_hello.__annotations__  =  }')
            
    print(f'{say_hello.__name__         =  }')
    print(f'{say_bye.__name__          =  }')
    '''

    '''
    print(f'{print_sqr_number.__name__        =  }')
    print(f'{print_sqr_number.__doc__         =  }')
    print(f'{print_sqr_number.__annotations__ =  }')

    print_sqr_number(6)
    '''
    print(say_hello())
    print(say_hello())
    

if __name__ == '__main__':
    main()