AnswerDotAI / AnswerDotAI/fastcore

`@call_parse`: Keyword only arguments help-msg not showing in help

Open
#532 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Jupyter Notebook
Stars
1.1k
Forks
295
Avg merge
1d 6h
Merged PRs (30d)
7

Description

This is one of my first Issues, so it probably isn't perfect. Sorry if I missed other (related) Issues.

# The problem:
The issues is that using the "*" star syntax to define keyword-only arguments in functions, makes the help message of the arguments after the the star (keyword-only arguments) not show up:

```python
@call_parse
def fun(
a:int=3, # The a parameter
b:str='string', # comment parameter b
*, # Keywords only from now on
c:float=0.42, # c param with comment <-- not shown in help
d='var', # The d param comment <-- not shown in help
e=42 # Comment 4 e <-- not shown in help
):
"->Documentation<-"
return True

print(anno_parser(fun).format_help())
```
The output:

```
usage: ipykernel_launcher.py [-h] [--a A] [--b B] [--c C] [--d D] [--e E]

->Documentation<-

options:
-h, --help show this help message and exit
--a A The a parameter (default: 3)
--b B String parameter b (default: string)
--c C (default: 0.42)
--d D (default: var)
--e E (default: 42)
```
The behavior is also present if I save to a file and run it from the commandline.

The help message for arg c,d & e are missing. If I comment out the "*, " line it works again.

# The cause/potential solution:
I think I have tracked down why this happens:

```python
#from fastcore.docments import _param_locs
def _param_locs(s, returns=True):
"`dict` of parameter line numbers to names"
body = _parses(s).body
if len(body)==1: #or not isinstance(body[0], FunctionDef): return None
defn = body[0]
if isinstance(defn, FunctionDef):
#res = {arg.lineno:arg.arg for arg in defn.args.args} # Original line
# Suggested change that makes it work: <---------------------------
res = {arg.lineno:arg.arg for arg in (defn.args.args + defn.args.kwonlyargs)}
if returns and defn.returns: res[defn.returns.lineno] = 'return'
return res
elif isdataclass(s):
res = {arg.lineno:arg.target.id for arg in defn.body if isinstance(arg, AnnAssign)}
return res
return None
```

Since _param_locs does not return keyword-only arguments (defn.args.kwonlyargs) it does not get matched with its comments and hence does not lead to a help message.

Its probably a bit preliminary, but perhaps I can turn this into a PR after some testing?

Contributor guide

Open the contributing guide

Research direction

Start at the _param_locs entry point in fastcore.docments and trace how anno_parser(fun).format_help() matches parameter comments to arguments. Verify the behavior with a function containing keyword-only parameters, then confirm that their help descriptions appear while the existing positional-argument help remains unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
tooling
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.