1

I'm trying to input() a string containing a large paste of JSON.

(Why I'm pasting a large blob of json is outside the scope of my question, but please believe me when I say I have a not-completely-idiotic reason!)

However, input() only grabs the first 4095 characters of the paste, for reasons described in this answer.

My code looks roughly like this:

import json

foo = input()
json.loads(foo)

When I paste a blob of JSON that's longer than 4095 characters, json.loads(foo) raises an error. (The error varies based on the specifics of how the JSON gets cut off, but it invariably fails one way or another because it's missing the final }.)

I looked at the documentation for input(), and it made no mention of anything that looked useful for this issue. No flags to input in non-canonical mode, no alternate input()-style functions to handle larger inputs, etc.

Is there a way to be able to paste large inputs successfully? This would make my tool's workflow way less janky than having to paste into a file, save it somewhere, and then pass the file's location into the script.

Claire Nielsen
  • 1,881
  • 1
  • 14
  • 31

1 Answers1

4

Python has to follow the terminal rules. But you could use a system call from python to change terminal behaviour and change it back (Linux):

import subprocess,json

subprocess.check_call(["stty","-icanon"])
result = json.loads(input())
subprocess.check_call(["stty","icanon"])

Alternately, consider trying to get an indented json dump from your provider that you can read line by line, then decode.

data = "".join(sys.stdin.readlines())
result = json.loads(data)
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • The stdlib interface for POSIX style tty control is [termios](https://docs.python.org/3/library/termios.html). I guess canon would be a combo of `termios.VERASE` and `termios.VKILL` flags. – wim Oct 06 '21 at 04:50
  • that would be better to avoid 2 system calls I agree. – Jean-François Fabre Oct 06 '21 at 07:49