@@ -88,3 +88,50 @@ def wrapper(*args, **kwargs):
8888 return wrapper
8989
9090 return decorator
91+
92+ def renamed_class (deprecated_class_name : str , message : str , removal_date : str ):
93+ """A decorator for marking classes as being renamed and removed in the future.
94+ Callers to this function should explicitly update to use the other plugins instead.
95+
96+ Args:
97+ deprecated_class_name: The name of the class being deprecated
98+ message: A message added to the standard deprecation warning. Should include the replacement API paths
99+ removal_date: A YYYY-MM-DD formatted date of when the function will be removed from the framework
100+ """
101+
102+ def decorator (replacement_func ):
103+ @functools .wraps (replacement_func )
104+ def wrapper (* args , ** kwargs ):
105+ warnings .warn (
106+ f"This plugin ({ deprecated_class_name } ) has been renamed and will be removed in the first release after { removal_date } . { message } " ,
107+ FutureWarning ,
108+ )
109+ return replacement_func (* args , ** kwargs )
110+
111+ return wrapper
112+
113+ return decorator
114+
115+
116+ class PluginRenameClass :
117+ """Class to move all classmethod invocations (for when a plugin has been moved)"""
118+
119+ def __init_subclass__ (cls , replacement_class , removal_date , ** kwargs ):
120+ deprecated_class_name = f"{ cls .__module__ } .{ cls .__qualname__ } "
121+ super ().__init_subclass__ (** kwargs )
122+ for attr , value in replacement_class .__dict__ .items ():
123+ if isinstance (value , classmethod ):
124+ setattr (
125+ cls ,
126+ attr ,
127+ classmethod (
128+ renamed_class (
129+ deprecated_class_name = deprecated_class_name ,
130+ removal_date = removal_date ,
131+ message = f"Please ensure all method calls to this plugin are replaced with calls to { replacement_class .__module__ } .{ replacement_class .__qualname__ } " ,
132+ )(value .__func__ )
133+ ),
134+ )
135+ else :
136+ setattr (cls , attr , value )
137+ return super (replacement_class ).__init_subclass__ (** kwargs )
0 commit comments