Deprecation best practices ========================== While deprecation best practices are outlined in this `deprecation documentation `_, there is no official guidance on deprecating features within Python. Thus, this topic provides deprecation best practices for PyAnsys libraries. Whenever you deprecate a method, class, or function, you must take one of these actions: - Have the old method call the new method and raise a warning. - Raise an ``AttributeError`` if you remove the method entirely. In the docstring of the old method, use a Sphinx `deprecated directive `_ that links to the new method. This way, you notify your users when you make an API change and give them a chance to change their code. Otherwise, users stop upgrading, or worse, stop using your API, due to stability concerns. For this reason, it is best to use a warning first and then use an error after a minor release or two. .. code:: python import warnings class FieldAnalysis2D: """Class docstring""" def assignmaterial(self, obj, mat): """Assign a material to one or more objects. .. deprecated:: 0.4.0 Use :func:`FieldAnalysis2D.assign_material` instead. """ # one of the following: # raise a DeprecationWarning. User won't have to change anything warnings.warn( "`assignmaterial` is deprecated. Use `assign_material` instead.", DeprecationWarning, ) self.assign_material(obj, mat) # or raise an AttributeError (could also make a custom DeprecationError) raise AttributeError( "`assignmaterial` is deprecated. Use `assign_material` instead." ) def assign_material(self, obj, mat): """Assign a material to one or more objects. ... """ If you remove a method entirely, there is no reason to provide a link to the old method. Simply raise an ``AttributeError`` as part of the class or raise an ``Exception``. .. code:: python def hello_world(): """Print ``"hello_world"`` .. deprecated:: 0.4.0 This function has been deprecated. """ raise Exception("`my_function` has been deprecated") Because there is no built-in deprecation error within Python, an alternate approach is to create a custom ``DeprecationError``. .. code:: python class DeprecationError(RuntimeError): """Used for deprecated methods and functions.""" def __init__(self, message="This feature has been deprecated."): """Empty init.""" RuntimeError.__init__(self, message) You then use this custom ``DeprecationError`` in place of an ``Exception``. .. code:: python def hello_world(): """Print ``"hello_world"`` .. deprecated:: 0.4.0 This function has been deprecated. """ raise DeprecationError("`my_function` has been deprecated.")