From a9beed3a037c45c804f61c85feddd9d11a82e1a9 Mon Sep 17 00:00:00 2001 From: Gabriel Busnot Date: Thu, 2 Dec 2021 12:16:51 +0100 Subject: [PATCH] python: Define deprecated and callOnce decorators Change-Id: I85d52a65308b9d5068a9aaa46597e5eaf8175064 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/53523 Reviewed-by: Jason Lowe-Power Maintainer: Jason Lowe-Power Reviewed-by: Andreas Sandberg Maintainer: Andreas Sandberg Tested-by: kokoro --- src/python/m5/util/__init__.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/python/m5/util/__init__.py b/src/python/m5/util/__init__.py index a63fa810d5..f5b5c798e5 100644 --- a/src/python/m5/util/__init__.py +++ b/src/python/m5/util/__init__.py @@ -41,6 +41,8 @@ import os import re import sys +from functools import wraps + from . import convert from .attrdict import attrdict, multiattrdict, optiondict @@ -71,6 +73,36 @@ def warn(fmt, *args): def inform(fmt, *args): print('info:', fmt % args, file=sys.stdout) +def callOnce(func): + """Decorator that enables to run a given function only once. Subsequent + calls are discarded.""" + @wraps(func) + def wrapper(*args, **kwargs): + if not wrapper.has_run: + wrapper.has_run = True + return func(*args, **kwargs) + wrapper.has_run = False + return wrapper + +def deprecated(replacement=None, logger=warn): + """This decorator warns the user about a deprecated function.""" + def decorator(func): + @callOnce + def notifyDeprecation(): + try: + func_name = lambda f: f.__module__ + '.' + f.__qualname__ + message = f'Function {func_name(func)} is deprecated.' + if replacement: + message += f' Prefer {func_name(replacement)} instead.' + except AttributeError: + message = f'Function {func} is deprecated.' + if replacement: + message += f' Prefer {replacement} instead.' + logger(message) + notifyDeprecation() + return func + return decorator + class Singleton(type): def __call__(cls, *args, **kwargs): if hasattr(cls, '_instance'):