python-openstackclient/doc/source/contributor/command-wrappers.rst
Stephen Finucane 5f650853f7 Remove references to setuptools
Newer versions of cliff and stevedore use importlib rather than
setuptools to work with entry points. Replace any references to
"setuptools' entry points mechanism" with "Python's entry points
mechanism".

Change-Id: Iae36155685ee37ab5e38a0c173110a5ece33d05d
Signed-off-by: Stephen Finucane <sfinucan@redhat.com>
2020-10-22 09:52:57 +01:00

53 lines
2.0 KiB
ReStructuredText

======================
Command Class Wrappers
======================
When we want to deprecate a command, policy says we need to alert the user.
We do this with a message logged at WARNING level before any command output
is emitted.
OpenStackClient command classes are derived from the ``cliff`` classes.
Cliff uses Python's *entry points* mechanism for dispatching the parsed command
to the respective handler classes. This lends itself to modifying the
command execution at run-time.
The obvious approach to adding the deprecation message would be to just add
the message to the command class ``take_action()`` method directly. But then
the various deprecations are scattered throughout the code base. If we
instead wrap the deprecated command class with a new class we can put all of
the wrappers into a separate, dedicated module. This also lets us leave the
original class unmodified and puts all of the deprecation bits in one place.
This is an example of a minimal wrapper around a command class that logs a
deprecation message as a warning to the user then calls the original class.
* Subclass the deprecated command.
* Set class attribute ``deprecated`` to ``True`` to signal cliff to not
emit help text for this command.
* Log the deprecation message at WARNING level and refer to the replacement
for the deprecated command in the log warning message.
* Change the entry point class in ``setup.cfg`` to point to the new class.
Example Deprecation Class
-------------------------
.. code-block:: python
class ListFooOld(ListFoo):
"""List resources"""
# This notifies cliff to not display the help for this command
deprecated = True
log = logging.getLogger('deprecated')
def take_action(self, parsed_args):
self.log.warning(
"%s is deprecated, use 'foobar list'",
getattr(self, 'cmd_name', 'this command'),
)
return super(ListFooOld, self).take_action(parsed_args)