Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tuple of strings parsed as string if one of the strings contains a hyphen #561

Open
kjxlstad opened this issue Sep 25, 2024 · 2 comments
Open

Comments

@kjxlstad
Copy link

kjxlstad commented Sep 25, 2024

When parsing in a tuple of strings i can normally pass in comma-separated values with no issues, however if one of the values contains a hyphen the arguments gets parsed as a string instead of a tuple of strings.

Using your provided example.py script

import fire
fire.Fire(lambda obj: type(obj).__name__)

If i call it with multiple strings not containing hyphens i get the expected output

>>> python example.py '(foobar,baz)' 
tuple

however, if I call it with a string containing a hyphen (-), I get this unexpected output

>>> python example.py '(foo-bar,baz)'
str

Is this to be expected? I also see that this is an issue with other symbols aswell.
Is there a way to work around this other than to pass in a repr-like string?

E.g, this works, but is not very human friendly:

>>> python example.py '("foo-bar","baz")'
tuple

Edit: This is also the case for lists, sets and dicts containing strings.

@dbieber
Copy link
Member

dbieber commented Sep 27, 2024

Thanks for reporting; this is indeed a confusing experience.

As you've discovered, you can get the behavior you want with python example.py '("foo-bar","baz")', but as you note, it is not human friendly.

Part of the reason for this is that the outermost quotes in whatever command you run are processed by your shell.
This means that the seemingly logical python example.py ("foo-bar","baz") won't work either.

Is there a way to work around this other than to pass in a repr-like string?
You could use the SetParseFn decorator to set your own arg parsing logic.

Now that we've dropped Python 2 support, we have the option of adding a feature for supporting type annotations to specify the parse function. Currently inputs are parsed based solely on their content, not based on the function expecting them. So this could improve the situation for functions annotated with arg: tuple[str]. We don't have active plans to add this feature either however.


My recommendation:
If you're creating a CLI for other people to use, I recommend using @SetParseFn if you're accepting a sequence of strings.
The current behavior of Fire is useful for if you're making a CLI (e.g. just for yourself) out of code you don't control, as it allows you to pass a sequence of strings if that's what's required, albeit sometimes requiring an uncomfortable syntax to do so.

@link89
Copy link

link89 commented Nov 12, 2024

The same happens on dict type. And what makes things worse is, on Windows, you have to use double quote in the outside and single quote inside:

"{'local':'en-US'}" # type: dict
'{"local":"en-US"}' # type str

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants