python-fire icon indicating copy to clipboard operation
python-fire copied to clipboard

How do I preserve underscores in arguments?

Open MattKleinsmith opened this issue 7 years ago • 10 comments

Here's run.py:

import fire

def f(x):
    print(x)

if __name__ == '__main__':
    fire.Fire(f)

Command: python run.py --x 20180217_064501

Output:

20180217064501

Expected output:

20180217_064501

MattKleinsmith avatar Feb 17 '18 14:02 MattKleinsmith

These issues seem related: https://github.com/google/python-fire/issues/102 https://github.com/google/python-fire/issues/97

MattKleinsmith avatar Feb 17 '18 14:02 MattKleinsmith

I'm not able to reproduce this issue. When I run python run.py --x 20180217_064501 I get the expected output 20180217_064501.

What version of Python are you using? What version of fire?

dbieber avatar Feb 19 '18 16:02 dbieber

Python 3.6.3 fire 0.1.2, installed via pip OS: Ubuntu 16.04 on Docker and host

I should have included this information in the original post. My apologies.

MattKleinsmith avatar Feb 19 '18 16:02 MattKleinsmith

With this Dockerfile I get the expected output:

FROM ubuntu:16.04

RUN apt-get update --fix-missing && apt-get install -y \
    python3 \
    python3-pip \
    vim \
    wget

RUN pip3 install fire

RUN wget https://raw.githubusercontent.com/MattKleinsmith/dockerfiles/master/errors/fire/run.py

CMD ["python3", "run.py", "--x", "20180217_064501"]

MattKleinsmith avatar Feb 19 '18 16:02 MattKleinsmith

When I install Anaconda and use its provided pip to install fire, I get the erroneous output.

Here's a Dockerfile reproducing the issue.

MattKleinsmith avatar Feb 19 '18 17:02 MattKleinsmith

Tested with anaconda and python 2.7.15, I was getting the expected output. Then tested with anaconda and python 3.5.3(latest version available on Ubuntu 16.04, dockerfile uses 3.5.2) and again got the expected output. Then tested with anaconda and python 3.6.5 and got the erroneous output. Maybe the problem is with python 3.6+

frextrite avatar Aug 22 '18 13:08 frextrite

It looks like an issue with PEP 515 and underscores in numbers, which was implemented in Python 3.6. It seems like underscores between numbers are more likely to be used as part of a string rather than for a long number, so it could be worthwhile to, when we encounter a number with an underscore in it during traversal, treat it as a string instead.

I can take a shot at implementing that if that is the chosen solution.

JadeIden avatar Sep 18 '18 06:09 JadeIden

@JadeIden Do you still feel like implementing something? I tracked down where this happens but implementing a fix for this is well beyond me.

This is caused by line 96 of parser.py in the _LiteralEval function. Specifically root = ast.parse(value, mode='eval').

This can be demonstrated with the following code:

import ast
root = ast.parse("123_456", mode='eval')
print(root.body.value)

prints 123456.

kyle-goodwin avatar Jun 27 '23 00:06 kyle-goodwin

*bump, this is also affecting me, any news on a workaround ? why not inspect the type annotations (if present) and use that to bias the type ?

farridav avatar Jan 22 '24 15:01 farridav

One (poor :() workaround for the moment is to surround your argument with quotes... twice...

python run.py --x '"20180217_064501"'

The outer quotes get stripped by your shell, leaving just the inner quotes to be parsed by Python Fire, resulting in the arg getting treated as a string rather than a number.

dbieber avatar Jan 22 '24 16:01 dbieber