Skip to content

Commit 9a80a39

Browse files
authored
Merge pull request #662 from AnswerDotAI/version
Add version action support to Param class
2 parents 57d2eea + 35fad3b commit 9a80a39

File tree

2 files changed

+75
-10
lines changed

2 files changed

+75
-10
lines changed

fastcore/script.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,20 @@ def clean_type_str(x:str):
3939
class Param:
4040
"A parameter in a function used in `anno_parser` or `call_parse`"
4141
def __init__(self, help="", type=None, opt=True, action=None, nargs=None, const=None,
42-
choices=None, required=None, default=None):
43-
if type in (store_true,bool): type,action,default=None,'store_true' ,False
42+
choices=None, required=None, default=None, version=None):
43+
if type in (store_true,bool): type,action,default=None,'store_true',False
4444
if type==store_false: type,action,default=None,'store_false',True
4545
if type and isinstance(type,typing.Type) and issubclass(type,enum.Enum) and not choices: choices=list(type)
4646
help = help or ""
4747
store_attr()
4848

4949
def set_default(self, d):
50+
if self.action == "version":
51+
if d != inspect.Parameter.empty: self.version = d
52+
self.opt = True
53+
return
5054
if self.default is None:
51-
if d==inspect.Parameter.empty: self.opt = False
55+
if d == inspect.Parameter.empty: self.opt = False
5256
else: self.default = d
5357
if self.default is not None:
5458
self.help += f" (default: {self.default})"

nbs/08_script.ipynb

Lines changed: 68 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -246,16 +246,20 @@
246246
"class Param:\n",
247247
" \"A parameter in a function used in `anno_parser` or `call_parse`\"\n",
248248
" def __init__(self, help=\"\", type=None, opt=True, action=None, nargs=None, const=None,\n",
249-
" choices=None, required=None, default=None):\n",
250-
" if type in (store_true,bool): type,action,default=None,'store_true' ,False\n",
249+
" choices=None, required=None, default=None, version=None):\n",
250+
" if type in (store_true,bool): type,action,default=None,'store_true',False\n",
251251
" if type==store_false: type,action,default=None,'store_false',True\n",
252252
" if type and isinstance(type,typing.Type) and issubclass(type,enum.Enum) and not choices: choices=list(type)\n",
253253
" help = help or \"\"\n",
254254
" store_attr()\n",
255255
"\n",
256256
" def set_default(self, d):\n",
257+
" if self.action == \"version\":\n",
258+
" if d != inspect.Parameter.empty: self.version = d\n",
259+
" self.opt = True\n",
260+
" return\n",
257261
" if self.default is None:\n",
258-
" if d==inspect.Parameter.empty: self.opt = False\n",
262+
" if d == inspect.Parameter.empty: self.opt = False\n",
259263
" else: self.default = d\n",
260264
" if self.default is not None:\n",
261265
" self.help += f\" (default: {self.default})\"\n",
@@ -288,7 +292,7 @@
288292
"cell_type": "markdown",
289293
"metadata": {},
290294
"source": [
291-
"Each parameter in your function should have an annotation `Param(...)`. You can pass the following when calling `Param`: `help`,`type`,`opt`,`action`,`nargs`,`const`,`choices`,`required` (i.e. it takes the same parameters as `argparse.ArgumentParser.add_argument`, plus `opt`). Except for `opt`, all of these are just passed directly to `argparse`, so you have all the power of that module at your disposal. Generally you'll want to pass at least `help` (since this is provided as the help string for that parameter) and `type` (to ensure that you get the type of data you expect).\n",
295+
"Each parameter in your function should have an annotation `Param(...)`. You can pass the following when calling `Param`: `help`,`type`,`opt`,`action`,`nargs`,`const`,`choices`,`required`, `version` (i.e. it takes the same parameters as `argparse.ArgumentParser.add_argument`, plus `opt`). Except for `opt`, all of these are just passed directly to `argparse`, so you have all the power of that module at your disposal. Generally you'll want to pass at least `help` (since this is provided as the help string for that parameter) and `type` (to ensure that you get the type of data you expect).\n",
292296
"\n",
293297
"`opt` is a bool that defines whether a param is optional or required (positional) - but you'll generally not need to set this manually, because fastcore.script will set it for you automatically based on *default* values. You should provide a default (after the `=`) for any *optional* parameters. If you don't provide a default for a parameter, then it will be a *positional* parameter.\n",
294298
"\n",
@@ -398,16 +402,17 @@
398402
"name": "stdout",
399403
"output_type": "stream",
400404
"text": [
401-
"usage: progname [-h] [--b B] [--c {aa,bb,cc}] required a\n",
405+
"usage: progname [-h] [--v] [--b B] [--c {aa,bb,cc}] required a\n",
402406
"\n",
403407
"my docs\n",
404408
"\n",
405409
"positional arguments:\n",
406410
" required Required param\n",
407411
" a param 1\n",
408412
"\n",
409-
"optional arguments:\n",
413+
"options:\n",
410414
" -h, --help show this help message and exit\n",
415+
" --v Print version\n",
411416
" --b B param 2 (default: test)\n",
412417
" --c {aa,bb,cc} param 3 (default: aa)\n"
413418
]
@@ -417,6 +422,7 @@
417422
"_en = str_enum('_en', 'aa','bb','cc')\n",
418423
"def f(required:Param(\"Required param\", int),\n",
419424
" a:Param(\"param 1\", bool_arg),\n",
425+
" v:Param(\"Print version\", action='version', version='%(prog)s 2.0.0'),\n",
420426
" b:Param(\"param 2\", str)=\"test\",\n",
421427
" c:Param(\"param 3\", _en)=_en.aa):\n",
422428
" \"my docs\"\n",
@@ -426,6 +432,61 @@
426432
"p.print_help()"
427433
]
428434
},
435+
{
436+
"cell_type": "markdown",
437+
"metadata": {},
438+
"source": [
439+
"We can also check the version and help flaggs are working."
440+
]
441+
},
442+
{
443+
"cell_type": "code",
444+
"execution_count": null,
445+
"metadata": {},
446+
"outputs": [
447+
{
448+
"name": "stdout",
449+
"output_type": "stream",
450+
"text": [
451+
"progname 2.0.0\n"
452+
]
453+
}
454+
],
455+
"source": [
456+
"try: p.parse_args(['--v'])\n",
457+
"except: pass"
458+
]
459+
},
460+
{
461+
"cell_type": "code",
462+
"execution_count": null,
463+
"metadata": {},
464+
"outputs": [
465+
{
466+
"name": "stdout",
467+
"output_type": "stream",
468+
"text": [
469+
"usage: progname [-h] [--v] [--b B] [--c {aa,bb,cc}] required a\n",
470+
"\n",
471+
"my docs\n",
472+
"\n",
473+
"positional arguments:\n",
474+
" required Required param\n",
475+
" a param 1\n",
476+
"\n",
477+
"options:\n",
478+
" -h, --help show this help message and exit\n",
479+
" --v Print version\n",
480+
" --b B param 2 (default: test)\n",
481+
" --c {aa,bb,cc} param 3 (default: aa)\n"
482+
]
483+
}
484+
],
485+
"source": [
486+
"try: p.parse_args(['-h'])\n",
487+
"except: pass"
488+
]
489+
},
429490
{
430491
"cell_type": "markdown",
431492
"metadata": {},
@@ -450,7 +511,7 @@
450511
" required Required param\n",
451512
" a param 1\n",
452513
"\n",
453-
"optional arguments:\n",
514+
"options:\n",
454515
" -h, --help show this help message and exit\n",
455516
" --b B param 2 (default: test)\n",
456517
" --c {aa,bb,cc} param 3 (default: aa)\n"

0 commit comments

Comments
 (0)