Skip to content

Commit 373a91d

Browse files
committed
fixes #664
1 parent 62e622c commit 373a91d

File tree

2 files changed

+108
-29
lines changed

2 files changed

+108
-29
lines changed

fastcore/docments.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,9 @@ def _param_locs(s, returns=True, args_kwargs=False):
7373
if isinstance(defn, (FunctionDef, AsyncFunctionDef)):
7474
res = {arg.lineno:arg.arg for arg in defn.args.args}
7575
# Add *args if present
76-
if defn.args.vararg and args_kwargs: res[defn.args.vararg.lineno] = defn.args.vararg.arg
76+
if defn.args.vararg: res[defn.args.vararg.lineno] = defn.args.vararg.arg
7777
# Add keyword-only args
78-
if args_kwargs: res.update({arg.lineno:arg.arg for arg in defn.args.kwonlyargs})
78+
res.update({arg.lineno:arg.arg for arg in defn.args.kwonlyargs})
7979
# Add **kwargs if present
8080
if defn.args.kwarg and args_kwargs: res[defn.args.kwarg.lineno] = defn.args.kwarg.arg
8181
if returns and defn.returns: res[defn.returns.lineno] = 'return'
@@ -98,9 +98,12 @@ def _get_comment(line, arg, comments, parms):
9898
line -= 1
9999
return dedent('\n'.join(reversed(res))) if res else None
100100

101-
def _get_full(anno, name, default, docs):
102-
if anno==empty and default!=empty: anno = type(default)
103-
return AttrDict(docment=docs.get(name), anno=anno, default=default)
101+
def _get_full(p, docs):
102+
anno = p.annotation
103+
if anno==empty:
104+
if p.default!=empty: anno = type(p.default)
105+
elif p.kind in (Parameter.VAR_POSITIONAL, Parameter.VAR_KEYWORD): anno = p.kind
106+
return AttrDict(docment=docs.get(p.name), anno=anno, default=p.default)
104107

105108
# %% ../nbs/06_docments.ipynb
106109
def _merge_doc(dm, npdoc):
@@ -148,8 +151,8 @@ def _docments(s, returns=True, eval_str=False, args_kwargs=False):
148151
docs = {arg:_get_comment(line, arg, comments, parms) for line,arg in parms.items()}
149152

150153
sig = signature_ex(s, True)
151-
res = {arg:_get_full(p.annotation, p.name, p.default, docs) for arg,p in sig.parameters.items()}
152-
if returns: res['return'] = _get_full(sig.return_annotation, 'return', empty, docs)
154+
res = {name:_get_full(p, docs) for name,p in sig.parameters.items()}
155+
if returns: res['return'] = AttrDict(docment=docs.get('return'), anno=sig.return_annotation, default=empty)
153156
res = _merge_docs(res, nps)
154157
if eval_str:
155158
hints = type_hints(s)
@@ -159,8 +162,9 @@ def _docments(s, returns=True, eval_str=False, args_kwargs=False):
159162

160163
# %% ../nbs/06_docments.ipynb
161164
@delegates(_docments)
162-
def docments(elt, full=False, **kwargs):
165+
def docments(elt, full=False, args_kwargs=False, **kwargs):
163166
"Generates a `docment`"
167+
if full: args_kwargs=True
164168
r = {}
165169
params = set(signature(elt).parameters)
166170
params.add('return')

nbs/06_docments.ipynb

Lines changed: 96 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,9 @@
245245
" if isinstance(defn, (FunctionDef, AsyncFunctionDef)):\n",
246246
" res = {arg.lineno:arg.arg for arg in defn.args.args}\n",
247247
" # Add *args if present\n",
248-
" if defn.args.vararg and args_kwargs: res[defn.args.vararg.lineno] = defn.args.vararg.arg\n",
248+
" if defn.args.vararg: res[defn.args.vararg.lineno] = defn.args.vararg.arg\n",
249249
" # Add keyword-only args\n",
250-
" if args_kwargs: res.update({arg.lineno:arg.arg for arg in defn.args.kwonlyargs})\n",
250+
" res.update({arg.lineno:arg.arg for arg in defn.args.kwonlyargs})\n",
251251
" # Add **kwargs if present\n",
252252
" if defn.args.kwarg and args_kwargs: res[defn.args.kwarg.lineno] = defn.args.kwarg.arg\n",
253253
" if returns and defn.returns: res[defn.returns.lineno] = 'return'\n",
@@ -258,6 +258,27 @@
258258
" return None"
259259
]
260260
},
261+
{
262+
"cell_type": "code",
263+
"execution_count": null,
264+
"metadata": {},
265+
"outputs": [
266+
{
267+
"data": {
268+
"text/plain": [
269+
"{2: 'a', 3: 'b', 4: 'return'}"
270+
]
271+
},
272+
"execution_count": null,
273+
"metadata": {},
274+
"output_type": "execute_result"
275+
}
276+
],
277+
"source": [
278+
"parms = _param_locs(add)\n",
279+
"parms"
280+
]
281+
},
261282
{
262283
"cell_type": "code",
263284
"execution_count": null,
@@ -284,9 +305,32 @@
284305
" line -= 1\n",
285306
" return dedent('\\n'.join(reversed(res))) if res else None\n",
286307
"\n",
287-
"def _get_full(anno, name, default, docs):\n",
288-
" if anno==empty and default!=empty: anno = type(default)\n",
289-
" return AttrDict(docment=docs.get(name), anno=anno, default=default)"
308+
"def _get_full(p, docs):\n",
309+
" anno = p.annotation\n",
310+
" if anno==empty:\n",
311+
" if p.default!=empty: anno = type(p.default)\n",
312+
" elif p.kind in (Parameter.VAR_POSITIONAL, Parameter.VAR_KEYWORD): anno = p.kind\n",
313+
" return AttrDict(docment=docs.get(p.name), anno=anno, default=p.default)"
314+
]
315+
},
316+
{
317+
"cell_type": "code",
318+
"execution_count": null,
319+
"metadata": {},
320+
"outputs": [
321+
{
322+
"data": {
323+
"text/plain": [
324+
"'the 1st number to add'"
325+
]
326+
},
327+
"execution_count": null,
328+
"metadata": {},
329+
"output_type": "execute_result"
330+
}
331+
],
332+
"source": [
333+
"_get_comment(2, 'a', {2: ' the 1st number to add'}, parms)"
290334
]
291335
},
292336
{
@@ -395,8 +439,8 @@
395439
" docs = {arg:_get_comment(line, arg, comments, parms) for line,arg in parms.items()}\n",
396440
"\n",
397441
" sig = signature_ex(s, True)\n",
398-
" res = {arg:_get_full(p.annotation, p.name, p.default, docs) for arg,p in sig.parameters.items()}\n",
399-
" if returns: res['return'] = _get_full(sig.return_annotation, 'return', empty, docs)\n",
442+
" res = {name:_get_full(p, docs) for name,p in sig.parameters.items()}\n",
443+
" if returns: res['return'] = AttrDict(docment=docs.get('return'), anno=sig.return_annotation, default=empty)\n",
400444
" res = _merge_docs(res, nps)\n",
401445
" if eval_str:\n",
402446
" hints = type_hints(s)\n",
@@ -413,8 +457,9 @@
413457
"source": [
414458
"#|export\n",
415459
"@delegates(_docments)\n",
416-
"def docments(elt, full=False, **kwargs):\n",
460+
"def docments(elt, full=False, args_kwargs=False, **kwargs):\n",
417461
" \"Generates a `docment`\"\n",
462+
" if full: args_kwargs=True\n",
418463
" r = {}\n",
419464
" params = set(signature(elt).parameters)\n",
420465
" params.add('return')\n",
@@ -472,6 +517,13 @@
472517
"docments(add)"
473518
]
474519
},
520+
{
521+
"cell_type": "markdown",
522+
"metadata": {},
523+
"source": [
524+
"`args_kwargs=True` adds args and kwargs docs too:"
525+
]
526+
},
475527
{
476528
"cell_type": "code",
477529
"execution_count": null,
@@ -484,15 +536,15 @@
484536
"{ 'a': 'the 1st number to add',\n",
485537
" 'args': 'some args',\n",
486538
" 'b': 'the 2nd number to add',\n",
487-
" 'kwargs': 'Passed to the `example` function',\n",
539+
" 'kwargs': None,\n",
488540
" 'return': 'the result of adding `a` to `b`'}\n",
489541
"```"
490542
],
491543
"text/plain": [
492544
"{'args': 'some args',\n",
493545
" 'a': 'the 1st number to add',\n",
494546
" 'b': 'the 2nd number to add',\n",
495-
" 'kwargs': 'Passed to the `example` function',\n",
547+
" 'kwargs': None,\n",
496548
" 'return': 'the result of adding `a` to `b`'}"
497549
]
498550
},
@@ -517,7 +569,7 @@
517569
"cell_type": "markdown",
518570
"metadata": {},
519571
"source": [
520-
"If you pass `full=True`, the values are `dict` of defaults, types, and docments as values. Note that the type annotation is inferred from the default value, if the annotation is empty and a default is supplied."
572+
"If you pass `full=True`, the values are `dict` of defaults, types, and docments as values. Note that the type annotation is inferred from the default value, if the annotation is empty and a default is supplied. (Note that for `full`, `args_kwargs=True` is always set too.)"
521573
]
522574
},
523575
{
@@ -532,19 +584,31 @@
532584
"{ 'a': { 'anno': <class 'int'>,\n",
533585
" 'default': <class 'inspect._empty'>,\n",
534586
" 'docment': 'the 1st number to add'},\n",
587+
" 'args': { 'anno': <_ParameterKind.VAR_POSITIONAL: 2>,\n",
588+
" 'default': <class 'inspect._empty'>,\n",
589+
" 'docment': 'some args'},\n",
535590
" 'b': { 'anno': <class 'int'>,\n",
536591
" 'default': 0,\n",
537592
" 'docment': 'the 2nd number to add'},\n",
593+
" 'kwargs': { 'anno': <_ParameterKind.VAR_KEYWORD: 4>,\n",
594+
" 'default': <class 'inspect._empty'>,\n",
595+
" 'docment': None},\n",
538596
" 'return': { 'anno': <class 'int'>,\n",
539597
" 'default': <class 'inspect._empty'>,\n",
540598
" 'docment': 'the result of adding `a` to `b`'}}\n",
541599
"```"
542600
],
543601
"text/plain": [
544-
"{'a': {'docment': 'the 1st number to add',\n",
602+
"{'args': {'docment': 'some args',\n",
603+
" 'anno': <_ParameterKind.VAR_POSITIONAL: 2>,\n",
604+
" 'default': inspect._empty},\n",
605+
" 'a': {'docment': 'the 1st number to add',\n",
545606
" 'anno': int,\n",
546607
" 'default': inspect._empty},\n",
547608
" 'b': {'docment': 'the 2nd number to add', 'anno': int, 'default': 0},\n",
609+
" 'kwargs': {'docment': None,\n",
610+
" 'anno': <_ParameterKind.VAR_KEYWORD: 4>,\n",
611+
" 'default': inspect._empty},\n",
548612
" 'return': {'docment': 'the result of adding `a` to `b`',\n",
549613
" 'anno': int,\n",
550614
" 'default': inspect._empty}}"
@@ -968,11 +1032,21 @@
9681032
"data": {
9691033
"text/markdown": [
9701034
"```json\n",
971-
"{'a': 'First', 'b': 'Second', 'return': None}\n",
1035+
"{ 'a': {'anno': <class 'int'>, 'default': 2, 'docment': 'First'},\n",
1036+
" 'b': { 'anno': 'str',\n",
1037+
" 'default': <class 'inspect._empty'>,\n",
1038+
" 'docment': 'Second'},\n",
1039+
" 'return': { 'anno': <class 'inspect._empty'>,\n",
1040+
" 'default': <class 'inspect._empty'>,\n",
1041+
" 'docment': None}}\n",
9721042
"```"
9731043
],
9741044
"text/plain": [
975-
"{'a': 'First', 'return': None, 'b': 'Second'}"
1045+
"{'a': {'docment': 'First', 'anno': int, 'default': 2},\n",
1046+
" 'return': {'docment': None,\n",
1047+
" 'anno': inspect._empty,\n",
1048+
" 'default': inspect._empty},\n",
1049+
" 'b': {'docment': 'Second', 'anno': 'str', 'default': inspect._empty}}"
9761050
]
9771051
},
9781052
"execution_count": null,
@@ -981,13 +1055,7 @@
9811055
}
9821056
],
9831057
"source": [
984-
"def _a(a:int=2): return a # First\n",
985-
"\n",
986-
"@delegates(_a)\n",
987-
"def _b(b:str, # Second\n",
988-
" **kwargs): \n",
989-
" return b, (_a(**kwargs)) \n",
990-
"docments(_b)"
1058+
"docments(_b, full=True)"
9911059
]
9921060
},
9931061
{
@@ -1142,6 +1210,13 @@
11421210
"#|hide\n",
11431211
"import nbdev; nbdev.nbdev_export()"
11441212
]
1213+
},
1214+
{
1215+
"cell_type": "code",
1216+
"execution_count": null,
1217+
"metadata": {},
1218+
"outputs": [],
1219+
"source": []
11451220
}
11461221
],
11471222
"metadata": {

0 commit comments

Comments
 (0)