diff --git a/ports/zephyr-cp/boards/adafruit/feather_nrf52840_sense_zephyr/autogen_board_info.toml b/ports/zephyr-cp/boards/adafruit/feather_nrf52840_sense_zephyr/autogen_board_info.toml index 989332a143103..9d7af49936a79 100644 --- a/ports/zephyr-cp/boards/adafruit/feather_nrf52840_sense_zephyr/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/adafruit/feather_nrf52840_sense_zephyr/autogen_board_info.toml @@ -47,10 +47,10 @@ fontio = true # Zephyr board has busio fourwire = true # Zephyr board has busio framebufferio = true # Zephyr board has busio frequencyio = false -getpass = false +getpass = true gifio = false gnss = false -hashlib = false +hashlib = true hostnetwork = false i2cdisplaybus = true # Zephyr board has busio i2cioexpander = false @@ -117,4 +117,4 @@ watchdog = false wifi = false zephyr_display = false zephyr_kernel = false -zlib = false +zlib = true diff --git a/ports/zephyr-cp/boards/adafruit/feather_nrf52840_zephyr/autogen_board_info.toml b/ports/zephyr-cp/boards/adafruit/feather_nrf52840_zephyr/autogen_board_info.toml index 51c02dad4cf30..9860956ca234a 100644 --- a/ports/zephyr-cp/boards/adafruit/feather_nrf52840_zephyr/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/adafruit/feather_nrf52840_zephyr/autogen_board_info.toml @@ -47,7 +47,7 @@ fontio = true # Zephyr board has busio fourwire = true # Zephyr board has busio framebufferio = true # Zephyr board has busio frequencyio = false -getpass = false +getpass = true gifio = false gnss = false hashlib = true diff --git a/ports/zephyr-cp/boards/adafruit/feather_rp2040_zephyr/autogen_board_info.toml b/ports/zephyr-cp/boards/adafruit/feather_rp2040_zephyr/autogen_board_info.toml index c1d6e2ed3ce8f..54c1d4d578f6d 100644 --- a/ports/zephyr-cp/boards/adafruit/feather_rp2040_zephyr/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/adafruit/feather_rp2040_zephyr/autogen_board_info.toml @@ -47,7 +47,7 @@ fontio = true # Zephyr board has busio fourwire = true # Zephyr board has busio framebufferio = true # Zephyr board has busio frequencyio = false -getpass = false +getpass = true gifio = false gnss = false hashlib = true diff --git a/ports/zephyr-cp/boards/native/native_sim/autogen_board_info.toml b/ports/zephyr-cp/boards/native/native_sim/autogen_board_info.toml index b293424b539fc..c9bbc0a9a4356 100644 --- a/ports/zephyr-cp/boards/native/native_sim/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/native/native_sim/autogen_board_info.toml @@ -47,7 +47,7 @@ fontio = true # Zephyr board has busio fourwire = true # Zephyr board has busio framebufferio = true # Zephyr board has busio frequencyio = false -getpass = false +getpass = true gifio = false gnss = false hashlib = true # Zephyr networking enabled diff --git a/ports/zephyr-cp/boards/native/nrf5340bsim/autogen_board_info.toml b/ports/zephyr-cp/boards/native/nrf5340bsim/autogen_board_info.toml index 6d6d5841bbc5f..a75b1eee5b4c2 100644 --- a/ports/zephyr-cp/boards/native/nrf5340bsim/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/native/nrf5340bsim/autogen_board_info.toml @@ -47,7 +47,7 @@ fontio = true # Zephyr board has busio fourwire = true # Zephyr board has busio framebufferio = true # Zephyr board has busio frequencyio = false -getpass = false +getpass = true gifio = false gnss = false hashlib = true diff --git a/ports/zephyr-cp/boards/nordic/nrf5340dk/autogen_board_info.toml b/ports/zephyr-cp/boards/nordic/nrf5340dk/autogen_board_info.toml index b5d36e615669b..e850884fd2ee8 100644 --- a/ports/zephyr-cp/boards/nordic/nrf5340dk/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/nordic/nrf5340dk/autogen_board_info.toml @@ -47,7 +47,7 @@ fontio = true # Zephyr board has busio fourwire = true # Zephyr board has busio framebufferio = true # Zephyr board has busio frequencyio = false -getpass = false +getpass = true gifio = false gnss = false hashlib = true diff --git a/ports/zephyr-cp/boards/nordic/nrf54h20dk/autogen_board_info.toml b/ports/zephyr-cp/boards/nordic/nrf54h20dk/autogen_board_info.toml index 2c72ba1570de2..9b4d993369759 100644 --- a/ports/zephyr-cp/boards/nordic/nrf54h20dk/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/nordic/nrf54h20dk/autogen_board_info.toml @@ -47,7 +47,7 @@ fontio = true # Zephyr board has busio fourwire = true # Zephyr board has busio framebufferio = true # Zephyr board has busio frequencyio = false -getpass = false +getpass = true gifio = false gnss = false hashlib = true diff --git a/ports/zephyr-cp/boards/nordic/nrf54l15dk/autogen_board_info.toml b/ports/zephyr-cp/boards/nordic/nrf54l15dk/autogen_board_info.toml index d981883bf65d2..a0ff21ffa30f5 100644 --- a/ports/zephyr-cp/boards/nordic/nrf54l15dk/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/nordic/nrf54l15dk/autogen_board_info.toml @@ -47,7 +47,7 @@ fontio = true # Zephyr board has busio fourwire = true # Zephyr board has busio framebufferio = true # Zephyr board has busio frequencyio = false -getpass = false +getpass = true gifio = false gnss = false hashlib = true diff --git a/ports/zephyr-cp/boards/nordic/nrf7002dk/autogen_board_info.toml b/ports/zephyr-cp/boards/nordic/nrf7002dk/autogen_board_info.toml index 5faed268cdb7d..54e2b89d638a2 100644 --- a/ports/zephyr-cp/boards/nordic/nrf7002dk/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/nordic/nrf7002dk/autogen_board_info.toml @@ -47,7 +47,7 @@ fontio = true # Zephyr board has busio fourwire = true # Zephyr board has busio framebufferio = true # Zephyr board has busio frequencyio = false -getpass = false +getpass = true gifio = false gnss = false hashlib = true # Zephyr networking enabled diff --git a/ports/zephyr-cp/boards/nxp/frdm_mcxn947/autogen_board_info.toml b/ports/zephyr-cp/boards/nxp/frdm_mcxn947/autogen_board_info.toml index 8105f7731daae..32d194c870250 100644 --- a/ports/zephyr-cp/boards/nxp/frdm_mcxn947/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/nxp/frdm_mcxn947/autogen_board_info.toml @@ -47,7 +47,7 @@ fontio = true # Zephyr board has busio fourwire = true # Zephyr board has busio framebufferio = true # Zephyr board has busio frequencyio = false -getpass = false +getpass = true gifio = false gnss = false hashlib = true diff --git a/ports/zephyr-cp/boards/nxp/frdm_rw612/autogen_board_info.toml b/ports/zephyr-cp/boards/nxp/frdm_rw612/autogen_board_info.toml index a23bc81503c2d..db496abb5317e 100644 --- a/ports/zephyr-cp/boards/nxp/frdm_rw612/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/nxp/frdm_rw612/autogen_board_info.toml @@ -47,7 +47,7 @@ fontio = true # Zephyr board has busio fourwire = true # Zephyr board has busio framebufferio = true # Zephyr board has busio frequencyio = false -getpass = false +getpass = true gifio = false gnss = false hashlib = true # Zephyr networking enabled diff --git a/ports/zephyr-cp/boards/nxp/mimxrt1170_evk/autogen_board_info.toml b/ports/zephyr-cp/boards/nxp/mimxrt1170_evk/autogen_board_info.toml index e97292fee76cb..3144751db86ad 100644 --- a/ports/zephyr-cp/boards/nxp/mimxrt1170_evk/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/nxp/mimxrt1170_evk/autogen_board_info.toml @@ -47,7 +47,7 @@ fontio = true # Zephyr board has busio fourwire = true # Zephyr board has busio framebufferio = true # Zephyr board has busio frequencyio = false -getpass = false +getpass = true gifio = false gnss = false hashlib = true diff --git a/ports/zephyr-cp/boards/raspberrypi/rpi_pico2_w_zephyr/autogen_board_info.toml b/ports/zephyr-cp/boards/raspberrypi/rpi_pico2_w_zephyr/autogen_board_info.toml index 83b54ae2fa269..aa41a95b8a0d7 100644 --- a/ports/zephyr-cp/boards/raspberrypi/rpi_pico2_w_zephyr/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/raspberrypi/rpi_pico2_w_zephyr/autogen_board_info.toml @@ -47,7 +47,7 @@ fontio = true # Zephyr board has busio fourwire = true # Zephyr board has busio framebufferio = true # Zephyr board has busio frequencyio = false -getpass = false +getpass = true gifio = false gnss = false hashlib = true # Zephyr networking enabled diff --git a/ports/zephyr-cp/boards/raspberrypi/rpi_pico2_zephyr/autogen_board_info.toml b/ports/zephyr-cp/boards/raspberrypi/rpi_pico2_zephyr/autogen_board_info.toml index 65c5bc003aea5..a9305e511c93b 100644 --- a/ports/zephyr-cp/boards/raspberrypi/rpi_pico2_zephyr/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/raspberrypi/rpi_pico2_zephyr/autogen_board_info.toml @@ -47,7 +47,7 @@ fontio = true # Zephyr board has busio fourwire = true # Zephyr board has busio framebufferio = true # Zephyr board has busio frequencyio = false -getpass = false +getpass = true gifio = false gnss = false hashlib = true diff --git a/ports/zephyr-cp/boards/raspberrypi/rpi_pico_w_zephyr/autogen_board_info.toml b/ports/zephyr-cp/boards/raspberrypi/rpi_pico_w_zephyr/autogen_board_info.toml index 97288095e000f..0658a5674dc49 100644 --- a/ports/zephyr-cp/boards/raspberrypi/rpi_pico_w_zephyr/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/raspberrypi/rpi_pico_w_zephyr/autogen_board_info.toml @@ -47,7 +47,7 @@ fontio = true # Zephyr board has busio fourwire = true # Zephyr board has busio framebufferio = true # Zephyr board has busio frequencyio = false -getpass = false +getpass = true gifio = false gnss = false hashlib = true # Zephyr networking enabled diff --git a/ports/zephyr-cp/boards/raspberrypi/rpi_pico_zephyr/autogen_board_info.toml b/ports/zephyr-cp/boards/raspberrypi/rpi_pico_zephyr/autogen_board_info.toml index 18e1fc835657b..c9184ee81cd1c 100644 --- a/ports/zephyr-cp/boards/raspberrypi/rpi_pico_zephyr/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/raspberrypi/rpi_pico_zephyr/autogen_board_info.toml @@ -47,7 +47,7 @@ fontio = true # Zephyr board has busio fourwire = true # Zephyr board has busio framebufferio = true # Zephyr board has busio frequencyio = false -getpass = false +getpass = true gifio = false gnss = false hashlib = true diff --git a/ports/zephyr-cp/boards/renesas/da14695_dk_usb/autogen_board_info.toml b/ports/zephyr-cp/boards/renesas/da14695_dk_usb/autogen_board_info.toml index 529254cfec271..07463f618e84c 100644 --- a/ports/zephyr-cp/boards/renesas/da14695_dk_usb/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/renesas/da14695_dk_usb/autogen_board_info.toml @@ -47,7 +47,7 @@ fontio = true # Zephyr board has busio fourwire = true # Zephyr board has busio framebufferio = true # Zephyr board has busio frequencyio = false -getpass = false +getpass = true gifio = false gnss = false hashlib = true diff --git a/ports/zephyr-cp/boards/renesas/ek_ra6m5/autogen_board_info.toml b/ports/zephyr-cp/boards/renesas/ek_ra6m5/autogen_board_info.toml index 7a1c0bfd21e31..8f3d8612819e3 100644 --- a/ports/zephyr-cp/boards/renesas/ek_ra6m5/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/renesas/ek_ra6m5/autogen_board_info.toml @@ -47,7 +47,7 @@ fontio = true # Zephyr board has busio fourwire = true # Zephyr board has busio framebufferio = true # Zephyr board has busio frequencyio = false -getpass = false +getpass = true gifio = false gnss = false hashlib = true diff --git a/ports/zephyr-cp/boards/renesas/ek_ra8d1/autogen_board_info.toml b/ports/zephyr-cp/boards/renesas/ek_ra8d1/autogen_board_info.toml index 185859b080756..431d459f06305 100644 --- a/ports/zephyr-cp/boards/renesas/ek_ra8d1/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/renesas/ek_ra8d1/autogen_board_info.toml @@ -47,7 +47,7 @@ fontio = true # Zephyr board has busio fourwire = true # Zephyr board has busio framebufferio = true # Zephyr board has busio frequencyio = false -getpass = false +getpass = true gifio = false gnss = false hashlib = true diff --git a/ports/zephyr-cp/boards/st/nucleo_n657x0_q/autogen_board_info.toml b/ports/zephyr-cp/boards/st/nucleo_n657x0_q/autogen_board_info.toml index 7686dbf320bce..21f064f05774e 100644 --- a/ports/zephyr-cp/boards/st/nucleo_n657x0_q/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/st/nucleo_n657x0_q/autogen_board_info.toml @@ -47,7 +47,7 @@ fontio = true # Zephyr board has busio fourwire = true # Zephyr board has busio framebufferio = true # Zephyr board has busio frequencyio = false -getpass = false +getpass = true gifio = false gnss = false hashlib = true diff --git a/ports/zephyr-cp/boards/st/nucleo_u575zi_q/autogen_board_info.toml b/ports/zephyr-cp/boards/st/nucleo_u575zi_q/autogen_board_info.toml index 4037dac0481ea..dcf94db57ae8a 100644 --- a/ports/zephyr-cp/boards/st/nucleo_u575zi_q/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/st/nucleo_u575zi_q/autogen_board_info.toml @@ -47,7 +47,7 @@ fontio = true # Zephyr board has busio fourwire = true # Zephyr board has busio framebufferio = true # Zephyr board has busio frequencyio = false -getpass = false +getpass = true gifio = false gnss = false hashlib = true diff --git a/ports/zephyr-cp/boards/st/stm32h750b_dk/autogen_board_info.toml b/ports/zephyr-cp/boards/st/stm32h750b_dk/autogen_board_info.toml index 1a97bb3616350..813039f653812 100644 --- a/ports/zephyr-cp/boards/st/stm32h750b_dk/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/st/stm32h750b_dk/autogen_board_info.toml @@ -47,7 +47,7 @@ fontio = true # Zephyr board has busio fourwire = true # Zephyr board has busio framebufferio = true # Zephyr board has busio frequencyio = false -getpass = false +getpass = true gifio = false gnss = false hashlib = true diff --git a/ports/zephyr-cp/boards/st/stm32h7b3i_dk/autogen_board_info.toml b/ports/zephyr-cp/boards/st/stm32h7b3i_dk/autogen_board_info.toml index 4723617a5a7f9..c4a3a0be44c1d 100644 --- a/ports/zephyr-cp/boards/st/stm32h7b3i_dk/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/st/stm32h7b3i_dk/autogen_board_info.toml @@ -47,7 +47,7 @@ fontio = true # Zephyr board has busio fourwire = true # Zephyr board has busio framebufferio = true # Zephyr board has busio frequencyio = false -getpass = false +getpass = true gifio = false gnss = false hashlib = true diff --git a/ports/zephyr-cp/boards/st/stm32wba65i_dk1/autogen_board_info.toml b/ports/zephyr-cp/boards/st/stm32wba65i_dk1/autogen_board_info.toml index 749b040b6d43e..54f72b3006347 100644 --- a/ports/zephyr-cp/boards/st/stm32wba65i_dk1/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/st/stm32wba65i_dk1/autogen_board_info.toml @@ -47,7 +47,7 @@ fontio = true # Zephyr board has busio fourwire = true # Zephyr board has busio framebufferio = true # Zephyr board has busio frequencyio = false -getpass = false +getpass = true gifio = false gnss = false hashlib = true diff --git a/ports/zephyr-cp/cptools/build_circuitpython.py b/ports/zephyr-cp/cptools/build_circuitpython.py index 1a55997974635..7f3a012064fbe 100644 --- a/ports/zephyr-cp/cptools/build_circuitpython.py +++ b/ports/zephyr-cp/cptools/build_circuitpython.py @@ -65,6 +65,7 @@ "hashlib", "zlib", "adafruit_bus_device", + "getpass", ] # Flags that don't match with with a *bindings module. Some used by adafruit_requests MPCONFIG_FLAGS = ["array", "errno", "io", "json", "math"] diff --git a/ports/zephyr-cp/tests/test_getpass.py b/ports/zephyr-cp/tests/test_getpass.py new file mode 100644 index 0000000000000..541d91078b361 --- /dev/null +++ b/ports/zephyr-cp/tests/test_getpass.py @@ -0,0 +1,182 @@ +# SPDX-FileCopyrightText: 2026 Tim Cocks for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""Test the getpass core module.""" + +import pytest + + +DEFAULT_PROMPT_CODE = """\ +import getpass + +print("ready") +pw = getpass.getpass() +print(f"got: {pw}") +print(f"length: {len(pw)}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": DEFAULT_PROMPT_CODE}) +def test_getpass_default_prompt(circuitpython): + """getpass() with no args prints 'Password: ' and returns the typed string.""" + circuitpython.serial.wait_for("ready") + circuitpython.serial.wait_for("Password:") + circuitpython.serial.write("hunter2\r") + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "Password:" in output + assert "got: hunter2" in output + assert "length: 7" in output + assert "done" in output + + +CUSTOM_PROMPT_CODE = """\ +import getpass + +print("ready") +pw = getpass.getpass("Enter secret: ") +print(f"got: {pw}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": CUSTOM_PROMPT_CODE}) +def test_getpass_custom_prompt(circuitpython): + """A user-supplied prompt string is written before reading input.""" + circuitpython.serial.wait_for("Enter secret:") + circuitpython.serial.write("s3cr3t\r") + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "Enter secret:" in output + assert "got: s3cr3t" in output + assert "done" in output + + +NO_ECHO_CODE = """\ +import getpass + +print("ready") +pw = getpass.getpass("Pwd: ") +print("---boundary---") +print(f"got: {pw}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": NO_ECHO_CODE}) +def test_getpass_does_not_echo(circuitpython): + """Characters typed during getpass are not echoed back to the terminal.""" + circuitpython.serial.wait_for("Pwd:") + secret = "TopSecret123" + circuitpython.serial.write(secret + "\r") + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + # Split around the boundary: nothing typed should appear before it, + # but the printed value appears after. + pre, _, post = output.partition("---boundary---") + assert secret not in pre + assert f"got: {secret}" in post + assert "done" in post + + +BACKSPACE_CODE = """\ +import getpass + +print("ready") +pw = getpass.getpass("P: ") +print(f"got: {pw}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": BACKSPACE_CODE}) +def test_getpass_backspace(circuitpython): + """Backspace (0x7f) removes the previous character from the buffer.""" + circuitpython.serial.wait_for("P:") + # Type "abcX", then backspace, then "d" -> "abcd" + circuitpython.serial.write("abcX\x7fd\r") + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "got: abcd" in output + assert "done" in output + + +CTRL_C_CODE = """\ +import getpass + +print("ready") +try: + getpass.getpass("Pwd: ") + print("no exception") +except KeyboardInterrupt: + print("interrupted") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": CTRL_C_CODE}) +def test_getpass_ctrl_c_raises_keyboard_interrupt(circuitpython): + """Sending Ctrl+C while getpass is reading raises KeyboardInterrupt.""" + circuitpython.serial.wait_for("Pwd:") + circuitpython.serial.write("\x03") + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "interrupted" in output + assert "no exception" not in output + assert "done" in output + + +CTRL_D_EMPTY_CODE = """\ +import getpass + +print("ready") +try: + getpass.getpass("Pwd: ") + print("no exception") +except EOFError: + print("eof") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": CTRL_D_EMPTY_CODE}) +def test_getpass_ctrl_d_empty_raises_eof(circuitpython): + """Ctrl+D with an empty buffer raises EOFError.""" + circuitpython.serial.wait_for("Pwd:") + circuitpython.serial.write("\x04") + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "eof" in output + assert "no exception" not in output + assert "done" in output + + +EMPTY_INPUT_CODE = """\ +import getpass + +print("ready") +pw = getpass.getpass("Pwd: ") +print(f"length: {len(pw)}") +print(f"empty: {pw == ''}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": EMPTY_INPUT_CODE}) +def test_getpass_empty_input(circuitpython): + """Pressing return immediately yields an empty string.""" + circuitpython.serial.wait_for("Pwd:") + circuitpython.serial.write("\r") + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "length: 0" in output + assert "empty: True" in output + assert "done" in output