1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
|
.. _ATTR/ArgParse:
ArgParse
########
Many people use Python's :mod:`argparse` command line argument parser. This parser
can handle sub-commands like ``git commit -m "message"`` where *commit* is a
sub-command and ``-m <message>`` is an argument of this sub-command parser. It's
possible to assign a callback function to each individual sub-command parser.
.. rubric:: Advantages
* Declarative description instead of imperative form.
* All options from argparse can be used.
* Declare accepted command-line arguments close to the responsible handler method
* Complex parsers can be distributed accross multiple classes and merged via multiple inheritance.
* Pre-defined argument templates like switch parameters (``--help``).
.. _ATTR/ArgParse/Comparison:
Comparison
**********
.. grid:: 2
.. grid-item:: **pyTooling.Attributes.ArgParse**
.. code-block:: Python
class Program:
@DefaultHandler()
@FlagArgument(short="-v", long="--verbose", dest="verbose", help="Show verbose messages.")
def HandleDefault(self, args) -> None:
pass
@CommandHandler("new-user", help="Add a new user.")
@StringArgument(dest="username", metaName="username", help="Name of the new user.")
@LongValuedFlag("--quota", dest="quota", help="Max usable disk space.")
def NewUserHandler(self, args) -> None:
pass
@CommandHandler("delete-user", help="Delete a user.")
@StringArgument(dest="username", metaName="username", help="Name of the user.")
@FlagArgument(short="-f", long="--force", dest="force", help="Ignore internal checks.")
def DeleteUserHandler(self, args) -> None:
pass
@CommandHandler("list-user", help="List all users.")
def ListUserHandler(self, args) -> None:
pass
.. grid-item:: **Traditional ArgParse**
.. code-block:: Python
class Program:
def __init__(self):
mainParser = argparse.ArgumentParser()
mainParser.set_defaults(func=self.HandleDefault)
mainParser.add_argument("-v", "--verbose")
subParsers = mainParser.add_subparsers()
newUserParser = subParsers.add_parser("new-user", help="Add a new user.")
newUserParser.add_argument(dest="username", metaName="username", help="Name of the new user.")
newUserParser.add_argument("--quota", dest="quota", help="Max usable disk space.")
newUserParser.set_defaults(func=self.NewUserHandler)
deleteUserParser = subParsers.add_parser("delete-user", help="Delete a user.")
deleteUserParser.add_argument(dest="username", metaName="username", help="Name of the user.")
deleteUserParser.add_argument("-f", "--force", dest="force", help="Ignore internal checks.")
deleteUserParser.set_defaults(func=self.DeleteUserHandler)
listUserParser = subParsers.add_parser("list-user", help="List all users.")
listUserParser.set_defaults(func=self.ListUserHandler)
def HandleDefault(self, args) -> None:
pass
def NewUserHandler(self, args) -> None:
pass
def DeleteUserHandler(self, args) -> None:
pass
def ListUserHandler(self, args) -> None:
pass
.. _ATTR/ArgParse/Arguments:
Arguments
*********
.. _ATTR/ArgParse/Flags:
Flags
=====
.. _ATTR/ArgParse/ValuedFlags:
ValuedFlags
===========
.. _ATTR/ArgParse/ValuedTupleFlags:
ValuedTupleFlags
================
.. _ATTR/ArgParse/Lists:
Argument Lists
**************
.. _ATTR/ArgParse/Commands:
Commands
********
.. _ATTR/ArgParse/Grouping:
Grouping Arguments
******************
.. _ATTR/ArgParse/MixIn:
Split Handlers into multiple classes
************************************
Classic ``argparse`` Example
****************************
.. literalinclude:: ../../tests/example/OldStyle.py
:language: python
:linenos:
:caption: tests/example/OldStyle.py
:tab-width: 2
New ``pyTooling.Attributes`` Approach
*************************************
A better and more descriptive solution could look like this:
.. literalinclude:: ../../tests/example/UserManager.py
:language: python
:linenos:
:caption: tests/example/UserManager.py
:tab-width: 2
.. _ATTR/ArgParse/Consumers:
Consumers
*********
This package is used by:
* ✅ . |br|
:ref:`pyTooling.Attributes.ArgParse <ATTR/ArgParse>`
|