Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

is it possible to make input() throw errors?

>>> input("input")
input>? a
'a'
>>> input("input")
input>? 'a
"'a"
>>> input("input")
input>? '"a
'\'"a'
>>> input("input")
input>? \'"a
'\\\'"a'
>>> input("input")
input>? "'a
'"\'a'
>>> input("input")
input>? "''a
'"\'\'a'

It seems that whatever I throw in input in hopes to break it, python just keeps one upping me. It like knows what I'm trying to achieve here and goes "nope"

like image 966
Konulv Avatar asked Dec 30 '18 14:12

Konulv


4 Answers

The EOFError mentioned by others can also be triggered by standard input being something that isn't an infinite stream (like standard input generally is), such as /dev/null:

$ python3 -c 'input("")' < /dev/null
Traceback (most recent call last):
  File "<string>", line 1, in <module>
EOFError: EOF when reading a line

In a similar vein, we could also write input that's impossible to decode as UTF-8 (here using xxd to decode hex into bytes that are then passed to Python).

$ echo 'fe fe ff ff' | xxd -r -ps | python3 -c 'print(input())'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/local/Cellar/python/3.7.1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/codecs.py", line 322, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xfe in position 0: invalid start byte
like image 133
AKX Avatar answered Oct 20 '22 20:10

AKX


Not exactly an answer to the question, but you can throw a UnicodeDecodeError by changing the default encoding in python and then trying to input a unicode character (such as an emoji) which follows a different encoding scheme.

$ export PYTHONIOENCODING=ascii
$ python3.6
Python 3.6.0 (v3.6.0:41df79263a11, Dec 22 2016, 17:23:13) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> input('>>> ')
>>> 😃
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xf0 in position 0: ordinal not in range(128)
like image 43
cs95 Avatar answered Oct 20 '22 20:10

cs95


The easiest way I can think of is to press CTRL+D which will trigger an EOFError.
Similary, CTRL+C will raise a KeyboardInterrupt.

Demo:

>>> input('in: ')
in: Traceback (most recent call last): # <-- I pressed CTRL-D
  File "<stdin>", line 1, in <module>
EOFError

Maybe a more interesting way to get the EOFError is to use an empty file as the input to your program.

$ cat input.py
got = input('in: ')
print(got)
$ echo some text > not_empty.txt
$ python3 input.py < not_empty.txt 
in: some text
$ touch empty.txt
$ python3 input.py < empty.txt 
in: Traceback (most recent call last):
  File "input.py", line 1, in <module>
    got = input('in: ')
EOFError: EOF when reading a line
like image 1
timgeb Avatar answered Oct 20 '22 20:10

timgeb


Based on the comments on the question here, it appears that the actual confusion stems from how the Python interactive prompt displays the return value of input. The interactive session always displays values using repr, which is designed to try to print a string which, when parsed, would produce the original value. For strings this can lead to some confusion, since the thing that is printed in the interactive session is not the actual string, but a representation of the string.

To see the difference, you can try playing around with this program, which will likely be instructive:

#!/usr/bin/env python3

import unicodedata

def main():
    while True:
        s = input('Enter a string: ')
        if not s:
            break
        print('Got string with length {}'.format(len(s)))
        for i, c in enumerate(s):
            print('Character {}: {}'.format(i, unicodedata.name(c)))
        print('repr() produces: {}'.format(repr(s)))
        print('String literally contains: {}'.format(s))
        print()


if __name__ == '__main__':
    main()

Here are some examples of what it prints:

Enter a string: a
Got string with length 1
Character 0: LATIN SMALL LETTER A
repr() produces: 'a'
String literally contains: a

Enter a string: 'a
Got string with length 2
Character 0: APOSTROPHE
Character 1: LATIN SMALL LETTER A
repr() produces: "'a"
String literally contains: 'a

Enter a string: "a'
Got string with length 3
Character 0: QUOTATION MARK
Character 1: LATIN SMALL LETTER A
Character 2: APOSTROPHE
repr() produces: '"a\''
String literally contains: "a'
like image 1
Daniel Pryden Avatar answered Oct 20 '22 20:10

Daniel Pryden