← index #1736Issue #17732
Related · high · value 0.394
QUERY · ISSUE

uos.dupterm() behavior in underspecified, implementations broken

openby pfalconopened 2015-12-20updated 2016-01-10
rfc

While not directly related to HW API, https://github.com/micropython/micropython/wiki/Hardware-API#os-module-additions specifies os.dupterm(), used for:

os.dupterm([stream_obj]) get or set duplication of controlling terminal, so that REPL can be redirected to UART or other (note: could allow to duplicate to multiple stream objs but that's arguably overkill and could anyway be done in Python by making a stream multiplexer)

Unfortunately, this description is not clear/detailed enough, or alternatively, current implementations of it in stmhal and cc3200 ports are not general or just broken. First of all, it should be made clear if the talk is about duplicating "controlling terminal", or replacing it. If there's talk about duplicating, then there should be immediate talk about non-blocking streams. Otherwise this line https://github.com/micropython/micropython/blob/master/cc3200/hal/cc3200_hal.c#L187 will simply hang the entire REPL, as it will wait until a character is available on that particular stream, ignoring all other input sources.

And then if there's requirement to non-blocking streams, it should be kept in mind that all other REPL sources should be non-blocking too, otherwise standard source can block custom installed one. But requirement of non-blocking sources is merely a minimal condition to get it all working, but working quite inefficiently and requiring weird workaround to not make it burn CPU cycles (and a battery of battery-powered device), e.g. https://github.com/micropython/micropython/blob/master/cc3200/hal/cc3200_hal.c#L196. So, next step is making requirement that REPL sources are pollable, and actually poll them.

That's quite a bunch of requirements to get it working in the general case, sure.

CANDIDATE · ISSUE

rp2: Can't send KeyboardInterrupt with os.dupterm()

closedby sfe-SparkFroopened 2025-07-21updated 2025-07-31
bug

Port, board and/or hardware

rp2

MicroPython version

MicroPython v1.25.0 on 2025-04-15; Raspberry Pi Pico 2 W with RP2350

Reproduction

Call os.dupterm() with UART or other compatible stream object:

from machine import UART
import os
os.dupterm(UART(0), 0)

Run some code:

import time
i = 0
while True:
    print(i)
    i += 1
    time.sleep(1)

Expected behaviour

While code is running, pressing Ctrl+C in the USB REPL works as expected:

0
1
2
Traceback (most recent call last):
  File "<stdin>", line 6, in <module>
KeyboardInterrupt:
>>>

Observed behaviour

While code is running, pressing Ctrl+C in the UART REPL fails to send the KeyboardInterrupt and halt execution.

Below, I pressed Ctrl+C a few times in the UART REPL, then once in the USB REPL. It then output extra >>>'s for each time I hit Ctrl+C in the UART REPL, indicating the KeyboardInterrupt's were getting buffered or something?

0
1
2
3
Traceback (most recent call last):
  File "<stdin>", line 6, in <module>
KeyboardInterrupt:
>>>
>>>
>>>
>>>
>>>

Additional Information

Although the provided replication code uses UART, this also happens with a Bluetooth REPL connection and is actually what we need to be fixed. This was just the simplest way to replicate.

Code of Conduct

Yes, I agree

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied