Comments (5)
This is by design
Please note how the pythonic notation maps to that of argparse:
f(x)
=arg('x')
= positionalf(x=y)
=arg('--x', default=y)
= optional (keyword)
You have defined a positional argument in your function signature and then refer to an optional argument (kwarg) which does not exist.
Let's define a command with both types of arguments with both "natural" and "explicit" notations:
#!/usr/bin/env python
import argh
@argh.arg('my-positional', help='a positional argument')
@argh.arg('--my-optional', help='an optional argument')
def mycommand(my_positional, my_optional='full'):
print(my_positional, my_optional)
argh.dispatch_command(mycommand)
Run it:
$ python issue47.py foo
foo full
There's room for improvement
To sum up, there's no bug here but the confusion is certainly undesired.
I think we should raise a more informative exception if the @arg
decorator refers to an argument of one type whereas an argument of different type exists with such name. Something like "optional argument --my-switch conflicts with positional my-switch from function signature".
from argh.
Changed the issue title from "How do include optional arguments with hyphens/underscores" to "More informative exception on explicit vs inferred arg type clash".
from argh.
Thanks for the explanation, it makes much more sense now. For some reason, I didn't get this from the documentation including the tutorial part, so perhaps adding this example or something similar might help.
BTW, thanks for argh. It is simply fantastic to use, and I really like the DRY, pythonic design.
from argh.
I've started writing tests for this issue and found out that the problem actually does not appear until there's a underscore/hyphen in argument name. If there isn't one, the application still works properly but another subtle bug may appear:
import argh
@argh.arg('--foo', default=1)
def f(foo):
"Positional in signature, keyword in decorator"
return foo
@argh.arg('foo')
def p(foo=1):
"Keyword in signature, positional in decorator"
return foo
argh.dispatch_commands([f, p])
and the call:
$ python issue47.py p 5
5
$ python issue47.py p
usage: issue47.py p [-h] foo
issue47.py p: error: the following arguments are required: foo
(Note that whether it may be OK to override some features of the original signature with decorators, here the very nature of the argument is distorted in a seemingly harmless and simple piece of code.)
So:
- Underscores should be always converted to hyphens before comparison of inferred and declared arguments;
- Assembling should ensure strict mutual conformance of definitions. This means that any combination of equally named positional arguments and flags should raise an error with an easily understandable message.
from argh.
Works great, thanks.
from argh.
Related Issues (20)
- override function signature with decorator HOT 2
- getting NameError for @arg decorator HOT 1
- More detailed signature inference with typing.get_type_hints HOT 2
- Generator command dumps the whole output at once when piped
- Passing a required argument by name
- Search for completion on RTD shows no results HOT 1
- Tests fail on python-3.9.7 (3.9.6 worked) HOT 3
- argh.dispatching.dispatch( skip_unknown_args=True ) bug HOT 1
- argh.dispatching.dispatch( skip_unknown_args=True ) bug
- use kwargs from different function? HOT 1
- use unittest.mock instead of mock HOT 4
- tox.ini file missing from sdist on PyPI HOT 3
- Raise coverage to 100%
- Remove Makefile HOT 2
- Rename "namespace" in add_commands() HOT 1
- 0.28.0: pytest fails in `tests/test_completion.py::test_disabled_without_bash` unit HOT 3
- Tests fail when run via "python -m pytest" HOT 2
- Make `help` output for base command containing multiple subcommands shorter
- Suppress return output. HOT 2
- Expose version information at runtime
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from argh.