@stephanelsmith

On unix port, I'type of sys.stdin is a TextIOWrapper.

This is the correct behavior. However what's missing is that it should have a .buffer attribute to access the underlying binary stream -- this is the CPython-compatible way to do this (see the note at the end of the sys.stdin docs -- https://docs.python.org/3/library/sys.html#sys.stderr ).

Conversely, on ESP32, sys.stdin is a FileIO with sys.stdin.buffer available for use.

Confusingly, despite being named FileIO, this object (on all the embedded ports) is actually a TextIOWrapper-like implementation. It is a text stream, and supports the .buffer attribute to get the underlying binary stream.

I don't know the history, but I'm guessing it's called "FileIO" just to save the additional code size for "TextIOWrapper", but if you look at shared/runtime/sys_stdio_mphal.c you can see it's implemented with is_text set to true.

Why not FileIO which would provide text and buffered versions?

I think the solution is just to provide the buffer attribute on the unix version (in vfs_posix_file.c), which should be do-able using basically the same approach as sys_stdio_mphal.c.

🌐
GitHub
github.com › micropython › micropython › issues › 16550
select.poll not working properly with sys.stdin · Issue #16550 · micropython/micropython
January 8, 2025 - However, reading only character by character is probably very inefficient and blows up code additionally. ... import sys, select p = select.poll() p.register(sys.stdin, select.POLLIN) while True: for o, _ in p.ipoll(): if o is sys.stdin: read = sys.stdin.read() print('read', read)
Author   cxxcoder
🌐
Digi
docs.digi.com › resources › documentation › digidocs › 90002219 › reference › r_uart_constants.htm
How to use the primary UART
December 8, 2022 - MicroPython provides access to ... and stderr with other stream objects. sys.stdin sys.stdin supports standard stream methods read and readline in text mode, converting carriage return (\r) to newline (\n)....
Discussions

Binary over sys.stdin question, sys.stdin is type TextIOWrapper, not FileIO?
Hello all, Brief, I'm writing a CLI tool with micropython where I need to pipe in binary over stdin. On unix port, I'type of sys.stdin is a TextIOWrapper. Conversely, on ESP32, sys.stdin is a FileI... More on github.com
🌐 github.com
2
1
July 23, 2023
python - What does sys.stdin read? - Stack Overflow
Are you familiar with input()? Wherever input() would take input from, that's sys.stdin. That may be a terminal, or it may be directed from a file, or it might be coming from another program's output, or it might be something else, depending on how you invoked the program. ... This reads the file ... More on stackoverflow.com
🌐 stackoverflow.com
Is there a way to read stdin with a timeout?
I want to write some code which reads characters from stdin, but if I don't get any input after some timeout then I'd like the read to fail. Does something like this exist? I'd love som... More on github.com
🌐 github.com
8
July 28, 2014
How to read stdin (and why in that way)
On the page about keyboard to hub communication there is the use of if keyboard.poll(0): It looks to me, based on testing, the functionality works just as well without the polling. Therefore the qu... More on github.com
🌐 github.com
7
1
June 9, 2023
🌐
GitHub
github.com › orgs › micropython › discussions › 11448
Non blocking read of input from the terminal · micropython · Discussion #11448
May 9, 2023 - import sys, select, time """ Note: this code does not work under Thonny because in Thonny input is sent to program only after [Enter] is clicked. """ class TermRead: """ We create a select.poll() object called spoll, and register the standard input (sys.stdin) with the POLLIN flag, indicating that we want to wait for the standard input to be ready for reading.
🌐
MicroPython
docs.micropython.org › en › v1.5.1 › pyboard › library › sys.html
sys – system specific functions — MicroPython 1.5.1 documentation
sys.stdin¶ · standard input (connected to USB VCP, and optional UART object) sys.stdout¶ · standard output (connected to USB VCP, and optional UART object) sys.version¶ · Python language version that this implementation conforms to, as a string · sys.version_info¶ ·
🌐
DigitalOcean
digitalocean.com › community › tutorials › read-stdin-python
How to Read from stdin in Python | DigitalOcean
August 3, 2022 - Here is a simple program to read user messages from the standard input and process it. The program will terminate when the user enters “Exit” message. import sys for line in sys.stdin: if 'Exit' == line.rstrip(): break print(f'Processing Message from sys.stdin *****{line}*****') print("Done")
Top answer
1 of 6
49

So you have used Python's "pre built in functions", presumably like this:

file_object = open('filename')
for something in file_object:
    some stuff here

This reads the file by invoking an iterator on the file object which happens to return the next line from the file.

You could instead use:

file_object = open('filename')
lines = file_object.readlines()

which reads the lines from the current file position into a list.

Now, sys.stdin is just another file object, which happens to be opened by Python before your program starts. What you do with that file object is up to you, but it is not really any different to any other file object, its just that you don't need an open.

for something in sys.stdin:
    some stuff here

will iterate through standard input until end-of-file is reached. And so will this:

lines = sys.stdin.readlines()

Your first question is really about different ways of using a file object.

Second, where is it reading from? It is reading from file descriptor 0 (zero). On Windows it is file handle 0 (zero). File descriptor/handle 0 is connected to the console or tty by default, so in effect it is reading from the keyboard. However it can be redirected, often by a shell (like bash or cmd.exe) using syntax like this:

myprog.py < input_file.txt 

That alters file descriptor zero to read a file instead of the keyboard. On UNIX or Linux this uses the underlying call dup2(). Read your shell documentation for more information about redirection (or maybe man dup2 if you are brave).

2 of 6
8

It is reading from the standard input - and it should be provided by the keyboard in the form of stream data.

It is not required to provide a file, however you can use redirection to use a file as standard input.

In Python, the readlines() method reads the entire stream, and then splits it up at the newline character and creates a list of each line.

lines = sys.stdin.readlines()

The above creates a list called lines, where each element will be a line (as determined by the end of line character).

You can read more about this at the input and output section of the Python tutorial.

If you want to prompt the user for input, use the input() method (in Python 2, use raw_input()):

user_input = input('Please enter something: ')
print('You entered: {}'.format(user_input))
🌐
GitHub
github.com › micropython › micropython › issues › 774
Is there a way to read stdin with a timeout? · Issue #774 · micropython/micropython
July 28, 2014 - I want to write some code which reads characters from stdin, but if I don't get any input after some timeout then I'd like the read to fail. Does something like this exist? I'd love somethine like: sys.stdin.read(1, timeout=500) which wo...
Author   dhylands
Find elsewhere
🌐
Pycom User Forum
forum.pycom.io › home › getting started › micropython › adding timeout to sys.stdin.read(1)
Adding timeout to sys.stdin.read(1) | Pycom user forum
February 21, 2022 - I am trying to read from the serial and telnet using sys.stdin.read(1). Since the function is blocking, I tried some suggested options with uselect: import sys, uselect spoll=uselect.poll() spoll.register(sys.stdin, uselect.POLLIN) def read1(): retu...
🌐
GitHub
github.com › micropython › micropython › issues › 12037
Data loss in string transfer through sys.stdout.write · Issue #12037 · micropython/micropython
July 18, 2023 - import serial connection = serial.Serial('COM6', timeout=3) for i in range(1000): connection.write(b'\n') res = connection.readline() print(i, len(res)) If BUF_SIZE set to 8000 everything will work fine. ... import sys BUF_SIZE = 40000 while True: sys.stdin.readline() line = bytes(BUF_SIZE) sys.stdout.write(line)
Author   pchala
🌐
GitHub
github.com › micropython › micropython › issues › 3356
[baremetal] sys.stdin does not handle ctrl-D EOF markers · Issue #3356 · micropython/micropython
October 7, 2017 - sys.stdin.read(), sys.stdin.readlines(), etc. do not handle ctrl-D at the beginning of a line as EOF (except on ports like unix). So for instance, there's no way to terminate input when doing sys.s...
Author   dhalbert
🌐
Reddit
reddit.com › r/learnpython › [beginners] intro to reading from standard input
r/learnpython on Reddit: [BEGINNERS] Intro to reading from standard input
January 6, 2018 -

Hey everyone, I just want to talk about reading in data from standard input and the 4 main ways it can be done.

I'm not going to talk about the input() or raw_input() functions today, instead ill be talking about how to read from standard input using the sys module.

To get access to the sys module we first need to import it

import sys

Ok now we have access to this module, there are 3 ways to read from standard input:

  1. sys.stdin.read([size])

  2. sys.stdin.readline()

  3. sys.stdin.readlines()

Lets look at how all of these work first and the ways to use them.

First off we can read lines directly from the console, this will look something like this

lines = sys.stdin.read()
print(lines)

$ python3 stdin.py
Line1
Line 2
**END**
Line 1
Line 2

Our lines variable looks like this: "Line1\nLine2"

Here when we run our program, it waits until it we pass some data through the console window. We specify end of input using ctrl+z on windows and I believe ctrl+d on linux.

The sys.stdin.read() function also has an optional parameter for the size of the data we want to read. For example if we pass 10 then it reads 10 characters including any newline characters.

The read() function will read everything, or the size of data specified, and return it as one string. This is useful for small amounts of data but if we read large files this way, it can use up a lot of memory.

The second way is sys.stdin.readline() which is self explanatory and reads a single line from standard input with a newline character at the end.

line = sys.stdin.readline()
print(line)

$ python3 stdin.py
hello
hello

The next way is sys.stdin.readlines(). I find myself using this way most often. With this way, we read lines from the console and are returned a list containing all the lines we entered.

lines = sys.stdin.readlines()
print(lines)

$ python3 stdin.py
line1
line2
line3
['line1\n', 'line2\n', 'line3\n']

This is very useful if we wish to process a file line by line although, we do have a large list sitting in memory which we may not want with large files. I will show you how to read from files in a moment.

Reading from files:

To read from a file we can do this a couple of ways, we can open and read the file within our program.

with open('FILENAME', [rw]) as our_file:
    for line in our_file:
        print(line)

The optional [rw] specifies whether we wish to open the file for reading, r or writing, w. This will work depending on the access permission on the file. You can check this on linux from the command line by navigating to your directory where the file is and typing:

$ ls -l

This will display the access permissions of the file in that directory.

An error will be thrown if you try to read or write without having permission to do so.

If the file name you entered doesn't exist, an empty file will be created for you.

The use of with open() here is very useful as it closes our file for us when we are finished.

Another way to read a file is passing it at the command line

$ python3 stdin.py < FILENAME.txt

Presuming FILENAME.txt looks like this:

Line 1
Line 2
Line 3

Running the following program, we get the following output:

import sys

lines = sys.stdin.readlines()
print(lines)

$ python3 stdin.py < FILENAME.txt
['Line 1\n', 'Line 2\n', 'Line 3']

I dont want to talk to much about the different ways of reading and writing files as I only wanted to talk about the different methods we have available to use for reading so I wont discuss any further ways of reading.

If we wish to strip the newline characters from our lines we can use the strip() method, I'm going to use a list comprehension here as it is a good example of their usage:

lines = [line.strip() for line in sys.stdin.readlines()]
print(lines)

$ python3 stdin.py < FILENAME.txt
['Line 1', Line 2', 'Line 3']

Whats the list comprehension doing? It uses a for loop to loop through each line in standard input, takes each line and strips it then appends it to our list, lines.

Now our newline characters are gone.

We covered a fair bit of stuff here and got the chance to see some extra things in use such as list comprehensions. If you found anything here confusing, play around with it yourself, after all its one of the best ways to learn.

🌐
MicroPython
docs.micropython.org › en › latest › library › sys.html
sys – system specific functions — MicroPython latest documentation
sys.stdin · Standard input stream. sys.stdout · Standard output stream. sys.tracebacklimit · A mutable attribute holding an integer value which is the maximum number of traceback entries to store in an exception. Set to 0 to disable adding tracebacks.
🌐
GitHub
github.com › micropython › micropython › issues › 1293
esp8266: can't read from sys.stdin · Issue #1293 · micropython/micropython
May 28, 2015 - While sys.stdout works as expected, trying to read even a single character from sys.stdin hangs the REPL.
🌐
GitHub
github.com › orgs › micropython › discussions › 9954
How to override stdin for tests simulating user input? · micropython · Discussion #9954
November 14, 2022 - It works great in CPython, but fails in MicroPython. I think I know why, but I'm unsure how to fix it. ... import sys from io import FileIO with FileIO('Hello World') as f: stdin_save = sys.stdin sys.stdin = f msg = input() print('"{}" was passed to input() by overriding stdin.'.format(msg)) sys.stdin = stdin_save · Now I've made things worse and running the code above causes an unhandled exception that reboots the board. I also tried getting more specific with sys.stdin.read, but again I'm just crashing the board.