Consider the following code:
import click
@click.command()
@click.argument("file", type=click.File())
def cli(file):
print(file)
if __name__ == "__main__":
cli()
Executing as:
$ python ./cmd.py -
<_io.TextIOWrapper name='<stdin>' mode='r' encoding='utf-8'>
$ touch '<stdin>'
$ python ./cmd.py '<stdin>'
<_io.TextIOWrapper name='<stdin>' mode='r' encoding='UTF-8'>
There is suprising difference in encoding.
How can I detect if the input was actual -
and not anything else in python click?
'<stdin>'
doesn't means filename but special objectsys.stdin
And you can compare
file == sys.stdin
Every opened file has number which system uses to work with this opened file and
sys.stdin
also has this number.Normally
sys.stdin.fileno()
is0
,sys.stdout.fileno()
is1
,sys.sterr.fileno()
is2
So you can compare
file.fileno() == 0
sys.stdin
is usually also assigned toconsole
/terminal
but normal file is not assigned - and you can check it with.isatty()
So you can compare
file.isatty() is False
But this is not good method because sometimes
sys.stdin
is not assigned - ie.cron
pipe
likeecho "text" | script.py
(but it will be it can be assigned when it is first inpipe
likescript.py | sort
But this method can be useful when you want to draw colored text on screen and send not colored text to file. But this may need to check also
sys.stdout
.