Skip to content

Commit 4f5a823

Browse files
authored
Merge pull request #660 from AnswerDotAI/args_kwargs
Support args kwargs
2 parents 7af5bb6 + 1972669 commit 4f5a823

File tree

2 files changed

+92
-15
lines changed

2 files changed

+92
-15
lines changed

fastcore/docments.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,19 @@ def _clean_comment(s):
6565
res = _clean_re.findall(s)
6666
return res[0] if res else None
6767

68-
def _param_locs(s, returns=True):
68+
def _param_locs(s, returns=True, args_kwargs=False):
6969
"`dict` of parameter line numbers to names"
7070
body = _parses(s).body
71-
if len(body)==1: #or not isinstance(body[0], FunctionDef): return None
71+
if len(body)==1:
7272
defn = body[0]
7373
if isinstance(defn, (FunctionDef, AsyncFunctionDef)):
7474
res = {arg.lineno:arg.arg for arg in defn.args.args}
75+
# Add *args if present
76+
if defn.args.vararg and args_kwargs: res[defn.args.vararg.lineno] = defn.args.vararg.arg
77+
# Add keyword-only args
78+
if args_kwargs: res.update({arg.lineno:arg.arg for arg in defn.args.kwonlyargs})
79+
# Add **kwargs if present
80+
if defn.args.kwarg and args_kwargs: res[defn.args.kwarg.lineno] = defn.args.kwarg.arg
7581
if returns and defn.returns: res[defn.returns.lineno] = 'return'
7682
return res
7783
elif isdataclass(s):
@@ -133,12 +139,12 @@ def qual_name(obj):
133139
return get_name(obj)
134140

135141
# %% ../nbs/06_docments.ipynb
136-
def _docments(s, returns=True, eval_str=False):
142+
def _docments(s, returns=True, eval_str=False, args_kwargs=False):
137143
"`dict` of parameter names to 'docment-style' comments in function or string `s`"
138144
nps = parse_docstring(s)
139145
if isclass(s) and not is_dataclass(s): s = s.__init__ # Constructor for a class
140146
comments = {o.start[0]:_clean_comment(o.string) for o in _tokens(s) if o.type==COMMENT}
141-
parms = _param_locs(s, returns=returns) or {}
147+
parms = _param_locs(s, returns=returns, args_kwargs=args_kwargs) or {}
142148
docs = {arg:_get_comment(line, arg, comments, parms) for line,arg in parms.items()}
143149

144150
sig = signature_ex(s, True)

nbs/06_docments.ipynb

Lines changed: 82 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -237,13 +237,19 @@
237237
" res = _clean_re.findall(s)\n",
238238
" return res[0] if res else None\n",
239239
"\n",
240-
"def _param_locs(s, returns=True):\n",
240+
"def _param_locs(s, returns=True, args_kwargs=False):\n",
241241
" \"`dict` of parameter line numbers to names\"\n",
242242
" body = _parses(s).body\n",
243-
" if len(body)==1: #or not isinstance(body[0], FunctionDef): return None\n",
243+
" if len(body)==1:\n",
244244
" defn = body[0]\n",
245245
" if isinstance(defn, (FunctionDef, AsyncFunctionDef)):\n",
246246
" res = {arg.lineno:arg.arg for arg in defn.args.args}\n",
247+
" # Add *args if present\n",
248+
" if defn.args.vararg and args_kwargs: res[defn.args.vararg.lineno] = defn.args.vararg.arg\n",
249+
" # Add keyword-only args\n",
250+
" if args_kwargs: res.update({arg.lineno:arg.arg for arg in defn.args.kwonlyargs})\n",
251+
" # Add **kwargs if present\n",
252+
" if defn.args.kwarg and args_kwargs: res[defn.args.kwarg.lineno] = defn.args.kwarg.arg\n",
247253
" if returns and defn.returns: res[defn.returns.lineno] = 'return'\n",
248254
" return res\n",
249255
" elif isdataclass(s):\n",
@@ -380,12 +386,12 @@
380386
"outputs": [],
381387
"source": [
382388
"#|export\n",
383-
"def _docments(s, returns=True, eval_str=False):\n",
389+
"def _docments(s, returns=True, eval_str=False, args_kwargs=False):\n",
384390
" \"`dict` of parameter names to 'docment-style' comments in function or string `s`\"\n",
385391
" nps = parse_docstring(s)\n",
386392
" if isclass(s) and not is_dataclass(s): s = s.__init__ # Constructor for a class\n",
387393
" comments = {o.start[0]:_clean_comment(o.string) for o in _tokens(s) if o.type==COMMENT}\n",
388-
" parms = _param_locs(s, returns=returns) or {}\n",
394+
" parms = _param_locs(s, returns=returns, args_kwargs=args_kwargs) or {}\n",
389395
" docs = {arg:_get_comment(line, arg, comments, parms) for line,arg in parms.items()}\n",
390396
"\n",
391397
" sig = signature_ex(s, True)\n",
@@ -466,6 +472,47 @@
466472
"docments(add)"
467473
]
468474
},
475+
{
476+
"cell_type": "code",
477+
"execution_count": null,
478+
"metadata": {},
479+
"outputs": [
480+
{
481+
"data": {
482+
"text/markdown": [
483+
"```json\n",
484+
"{ 'a': 'the 1st number to add',\n",
485+
" 'args': 'some args',\n",
486+
" 'b': 'the 2nd number to add',\n",
487+
" 'kwargs': 'Passed to the `example` function',\n",
488+
" 'return': 'the result of adding `a` to `b`'}\n",
489+
"```"
490+
],
491+
"text/plain": [
492+
"{'args': 'some args',\n",
493+
" 'a': 'the 1st number to add',\n",
494+
" 'b': 'the 2nd number to add',\n",
495+
" 'kwargs': 'Passed to the `example` function',\n",
496+
" 'return': 'the result of adding `a` to `b`'}"
497+
]
498+
},
499+
"execution_count": null,
500+
"metadata": {},
501+
"output_type": "execute_result"
502+
}
503+
],
504+
"source": [
505+
"def add(*args, # some args\n",
506+
" a:int, # the 1st number to add\n",
507+
" b=0, # the 2nd number to add\n",
508+
" **kwargs, # Passed to the `example` function\n",
509+
")->int: # the result of adding `a` to `b`\n",
510+
" \"The sum of two numbers.\"\n",
511+
" return a+b\n",
512+
"\n",
513+
"docments(add, args_kwargs=True)"
514+
]
515+
},
469516
{
470517
"cell_type": "markdown",
471518
"metadata": {},
@@ -910,6 +957,37 @@
910957
"docments(_b)"
911958
]
912959
},
960+
{
961+
"cell_type": "code",
962+
"execution_count": null,
963+
"metadata": {},
964+
"outputs": [
965+
{
966+
"data": {
967+
"text/markdown": [
968+
"```json\n",
969+
"{'a': 'First', 'b': 'Second', 'return': None}\n",
970+
"```"
971+
],
972+
"text/plain": [
973+
"{'a': 'First', 'return': None, 'b': 'Second'}"
974+
]
975+
},
976+
"execution_count": null,
977+
"metadata": {},
978+
"output_type": "execute_result"
979+
}
980+
],
981+
"source": [
982+
"def _a(a:int=2): return a # First\n",
983+
"\n",
984+
"@delegates(_a)\n",
985+
"def _b(b:str, # Second\n",
986+
" **kwargs): \n",
987+
" return b, (_a(**kwargs)) \n",
988+
"docments(_b)"
989+
]
990+
},
913991
{
914992
"cell_type": "code",
915993
"execution_count": null,
@@ -1062,13 +1140,6 @@
10621140
"#|hide\n",
10631141
"import nbdev; nbdev.nbdev_export()"
10641142
]
1065-
},
1066-
{
1067-
"cell_type": "code",
1068-
"execution_count": null,
1069-
"metadata": {},
1070-
"outputs": [],
1071-
"source": []
10721143
}
10731144
],
10741145
"metadata": {

0 commit comments

Comments
 (0)