Extend the warnings module with Deprecation utility methods and classes

Sooner or later authors and maintainers of libraries change public interfaces of their creations. Usually one of the two approaches is taken: 1. Outright breaking change 2. Soft deprecation later followed by [1] While [1] is perfectly suitable for libraries with limited audience, [2] is what popular libraries have to do (to remain popular). Python's stdlib contributed to the process via PEP 230 and, recently, PEP 565. The `warn` function and subclasses of Warning are omnipresent. However, when it comes to practical application it's still up to a developer to write utility methods and classes. I propose that Python should extend the warnings module with a set of utilities to cover basic needs as seen across the industry. The extension should include: 1. A decorator for functions 2. A decorator for classes 3. A context manager Function Decorator A function can be deprecated: - Via a rename when an author decides there is a better name - Via a change of its interface - By becoming obsolete Therefore the job of the decorator is to modify the behavior such as upon a call: - A warning is issued - Optionally an aliased (new) function is called - Optionally both positional and keyword arguments are mapped to satisfy new interface; might be followed by an extra warning for each remap Class Decorator A class can be deprecated: - Via a rename when an author decides there is a better name - By becoming obsolete Therefore a job of the decorator is to ensure that: - A warning is issued when class is either instantiated or used as a base class - If aliased, subclasses of a deprecated class (from the end user perspective) pass `issubclass` and `isinstance` checks against an aliased new class - If aliased, subclasses of a new class pass `issubclass` and `isinstance` checks against a deprecated class Context Manager Context manager is useful when behavior of a particular function changes without visible changes to its name or interface. E.g. when author realizes (too late) that arguments are mutually exclusive. Instead of introducing a breaking change outright, better solution is to wrap that particular case with a warning and consistent behavior. Each of these utilities should allow to specify a condition via a callable. E.g. when deprecation only makes sense for certain platforms or python interpreter versions. I think most if not all can be implemented using existing runtime and stdlib. But before diving into code, what do you think of this idea overall?

If you want, feel free to take some of the code from: https://docs.openstack.org/debtcollector/latest/reference/index.html It was made for a similar purpose (and uses warnings module at its lowest level) and may offer some things that could be in this new warnings module. Code is at: https://git.openstack.org/cgit/openstack/debtcollector And mirrored at https://github.com/openstack/debtcollector -Josh

Very nice, thank you. It would be a good start to collect usage patterns like this as seen in the wild for design consideration and test cases.
On Aug 30, 2018, at 10:43 PM, Joshua Harlow <harlowja@fastmail.com> wrote:
And mirrored at https://github.com/openstack/debtcollector <https://github.com/openstack/debtcollector>

If you want, feel free to take some of the code from: https://docs.openstack.org/debtcollector/latest/reference/index.html It was made for a similar purpose (and uses warnings module at its lowest level) and may offer some things that could be in this new warnings module. Code is at: https://git.openstack.org/cgit/openstack/debtcollector And mirrored at https://github.com/openstack/debtcollector -Josh

Very nice, thank you. It would be a good start to collect usage patterns like this as seen in the wild for design consideration and test cases.
On Aug 30, 2018, at 10:43 PM, Joshua Harlow <harlowja@fastmail.com> wrote:
And mirrored at https://github.com/openstack/debtcollector <https://github.com/openstack/debtcollector>
participants (2)
-
Ilya Kulakov
-
Joshua Harlow