Click: File option - prompting with pretty default?

Created on 8 Jan 2018  Â·  5Comments  Â·  Source: pallets/click

Hello,
I'm developing simple script, but I have found horrible default when using a file option with prompting with default value...
I have this code:

import click
import os.path
@click.command()
@click.option('-f', default=os.path.realpath("subdir/file.txt"), prompt="Please provide a file", type=click.File('rt'))
def func(f):
    pass
func()

But when I call it, it produces prompt like this:

me@computer:~/directory$ python3 script.py
Please provide a file [<_io.TextIOWrapper name='/home/me/directory/subdir/file.txt' mode='rt' encoding='UTF-8'>]:

Is this solved anywhere or how difficult would it be to fix it, so it would show [/home/me/directory/subdir/file.txt]?

Ubuntu 16.04 LTS 32-bit, Python 3.5.2, click 6.7

Please excuse any imperfections of this issue, I'm quite new to GitHub and haven't written any issues yet...

bug

All 5 comments

Can't reproduce on Mac - Python 3.6.2, Click 6.7...

(tmp-314aa1dbdcce094) ✔ ~/.venvs/tmp-314aa1dbdcce094
21:17 $ pip install click
Collecting click
  Using cached click-6.7-py2.py3-none-any.whl
Installing collected packages: click
Successfully installed click-6.7
(tmp-314aa1dbdcce094) ✔ ~/.venvs/tmp-314aa1dbdcce094
21:17 $ python test.py --help
Usage: test.py [OPTIONS]

Options:
  -f FILENAME
  --help       Show this message and exit.
(tmp-314aa1dbdcce094) ✔ ~/.venvs/tmp-314aa1dbdcce094
21:17 $ cat test.py
import click
import os.path
@click.command()
@click.option('-f', default=os.path.realpath("subdir/file.txt"), prompt="Please provide a file", type=click.File('rt'))
def func(f):
    pass
func()
(tmp-314aa1dbdcce094) ✔ ~/.venvs/tmp-314aa1dbdcce094
21:17 $ python test.py
Usage: test.py [OPTIONS]

Error: Invalid value for "-f": Could not open file: /Users/tomgoren/.venvs/tmp-314aa1dbdcce094/subdir/file.txt: No such file or directory
(tmp-314aa1dbdcce094) ✘-2 ~/.venvs/tmp-314aa1dbdcce094
21:17 $ pip freeze
-f file:///Users/tomgoren/.cache/pip/wheelhouse
click==6.7
(tmp-314aa1dbdcce094) ✔ ~/.venvs/tmp-314aa1dbdcce094
21:17 $ python --version
Python 3.6.2

Oh, @tomgoren, this isn't meant to be reproduced as is. If you want to:

mkdir subdir
touch subdir/file.txt

_Sorry for late reply and writing bad issues..._

Okay - I see it now @mvolfik.

The problem seems to be here.

There is only one value returned, f. If we were to return f.name for instance, then what we would get back would only be a string, and not the actual file handler.

So, while the output would be as expected, it would produce the wrong result if you were to try something like f.read(). Test case using your example (I changed click/types.py locally):

22:21 $ python test.py 
Please provide a file [/home/tomgoren/.venvs/tmp-d5c5119e57bcfc5/subdir/file.txt]: 
Traceback (most recent call last):
  File "test.py", line 9, in <module>
    func()
  File "/home/tomgoren/.venvs/tmp-d5c5119e57bcfc5/lib/python3.6/site-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/home/tomgoren/.venvs/tmp-d5c5119e57bcfc5/lib/python3.6/site-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/home/tomgoren/.venvs/tmp-d5c5119e57bcfc5/lib/python3.6/site-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/tomgoren/.venvs/tmp-d5c5119e57bcfc5/lib/python3.6/site-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "test.py", line 7, in func
    print(f.read())
AttributeError: 'str' object has no attribute 'read'

After digging a bit deeper, there seems to be a whole song and dance between convert, convert_type, prompt, and a few other bits and pieces.

The long and the short of it is that I got a bit lost, and I'm sorry I wasn't able to help more, but it seems like an actual bug, and a tricky one at that. I'm very curious to see how this is solved either way.

Good luck!

Starting to work on it

PR Created #1309

Was this page helpful?
0 / 5 - 0 ratings