Issue
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?
Solution
'<stdin>'
doesn't means filename but special object sys.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 to console
/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.
- when it runs in script without access to terminal - like in
cron
- when it works in
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
.
import click
import sys
@click.command()
@click.argument("file", type=click.File())
def cli(file):
print('file :', file)
print('number:', file.fileno())
print(' == :', file == sys.stdin)
print('isatty:', file.isatty())
print('stdin :', sys.stdin.isatty())
print('stdout:', sys.stdout.isatty())
if __name__ == "__main__":
cli()
$ python3 ./cmd.py -
<_io.TextIOWrapper name='<stdin>' mode='r' encoding='utf-8'>
number: 0
== : True
isatty: True
$ python3 ./cmd.py cmd.py
<_io.TextIOWrapper name='cmd.py' mode='r' encoding='UTF-8'>
number: 3
== : False
isatty: False
Answered By - furas
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.