Skip to content

py/modmicropython: Expose repl_autocomplete as python function. - #17011

Open
andrewleech wants to merge 1 commit into
micropython:masterfrom
andrewleech:expose_mp_repl_autocomplete
Open

py/modmicropython: Expose repl_autocomplete as python function.#17011
andrewleech wants to merge 1 commit into
micropython:masterfrom
andrewleech:expose_mp_repl_autocomplete

Conversation

@andrewleech

@andrewleech andrewleech commented Mar 26, 2025

Copy link
Copy Markdown
Contributor

Summary

Exposes mp_repl_autocomplete() and mp_hal_stdio_mode_raw()/mp_hal_stdio_mode_orig() to Python as micropython.repl_autocomplete() and micropython.stdio_mode_raw() respectively.

repl_autocomplete(line) returns the completion suffix string, empty string for no match, or None when multiple candidates are printed. Gated on MICROPY_HELPER_REPL which is already enabled on most ports.

stdio_mode_raw(enabled) switches the terminal between raw and original mode. Gated behind a new MICROPY_PY_MICROPYTHON_STDIO_RAW config option, defaulting to off, enabled on unix.

Both are used by micropython/micropython-lib#1081 to bring aiorepl closer to feature parity with the native REPL — tab completion via repl_autocomplete, and proper terminal mode management via stdio_mode_raw.

Testing

Unit tests added for both functions under tests/micropython/. A cmdline REPL test for stdio_mode_raw verifies actual terminal attribute changes via termios.

Tested on unix port.

Generative AI

I used generative AI tools when creating this PR, but a human has checked the code and is responsible for the description above.

@github-actions

github-actions Bot commented Mar 26, 2025

Copy link
Copy Markdown

Code size report:

Reference:  esp32/boards/SEEED_XIAO_ESP32C6: Add new XIAO board definition. [2dc2e30]
Comparison: py/modmicropython: Expose repl_autocomplete as python function. [merge of aeda0fa]
  mpy-cross:    +0 +0.000% 
   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64:  +296 +0.035% standard[incl +32(data)]
      stm32:  +108 +0.027% PYBV10
      esp32:  +124 +0.007% ESP32_GENERIC[incl +48(data)]
     mimxrt:   +96 +0.025% TEENSY40
        rp2:  +104 +0.011% RPI_PICO_W
       samd:  +104 +0.038% ADAFRUIT_ITSYBITSY_M4_EXPRESS
  qemu rv32:  +116 +0.025% VIRT_RV32

@andrewleech
andrewleech force-pushed the expose_mp_repl_autocomplete branch from e1aa321 to 5dd9831 Compare March 26, 2025 01:13
@dpgeorge dpgeorge added the py-core Relates to py/ directory in source label Mar 27, 2025
@mattytrentini

Copy link
Copy Markdown
Contributor

Adding autocomplete for aiorepl is very desirable, and this is looking promising! Here are some of the tests I ran:

>>>import micropython
>>>micropython.repl_autocomplete("impo")  # Should complete 'import'
'rt '
>>> class Foo:
...     def _bar():
...         pass
...     def alpha():
...         pass
>>> micropython.repl_autocomplete("f = Fo") # Should complete Foo
'o'
>>>f = Foo()
>>> micropython.repl_autocomplete("f.") # Should complete alpha (ignoring _bar)
'alpha'

Note that this is correct and consistent with MicroPython's built-in tab completion - but differs in some cases to CPython, at least at v3.12. CPython will also supply parentheses, ie it would return 'o()' to complete f = Fo and 'alpha(' for f.. That's not a problem with this PR, but should be resolved in mp_repl_autocomplete.

I also tested a module with private members and they were also correctly filtered out.

Looks good!

@Josverl

Josverl commented Apr 5, 2025

Copy link
Copy Markdown
Contributor

but differs in some cases to CPython, at least at v3.12.

Perhaps that should just be documented as such. I'd be fine with consistent behavior with the MicroPython repl.

Comment thread py/repl.c Outdated
@@ -218,7 +218,7 @@ static void print_completions(const mp_print_t *print,
for (qstr q = q_first; q <= q_last; ++q) {
size_t d_len;
const char *d_str = (const char *)qstr_data(q, &d_len);
if (s_len <= d_len && strncmp(s_start, d_str, s_len) == 0) {
if (s_len <= d_len && strncmp(s_start, d_str, s_len) == 0 && d_str[0] != '_') {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please break this out into a separate PR. It'll need changes to the tests as well.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Split out to #17108 with a unit test (which might need some more updating to ensure the test is consistent / works across ports etc?)

@andrewleech

Copy link
Copy Markdown
Contributor Author

Ok I'm really not sure why the unit tests are still failing on some builds; unix standard in particular. The test passes for me locally with the same build.
Are local variable names somehow handled differently in CI that they're not visible to the auto complete function?
I only just found/ looked at the cmdline repl autocomplete unit test, I should rewrite the test for this module to use test cases more similar to that.

@andrewleech
andrewleech force-pushed the expose_mp_repl_autocomplete branch from bdb98b0 to 6709f5e Compare May 6, 2025 21:33
Comment thread py/modmicropython.c Outdated
const char *str = mp_obj_str_get_data(cur_line, &str_len);

ssize_t compl_len = mp_repl_autocomplete(str, str_len, &mp_plat_print, &compl_str);
return (compl_len <= 0) ? mp_const_none : mp_obj_new_str_via_qstr(compl_str, compl_len);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you make this (compl_len < 0) then the caller should be able to distinguish between the 3 distinct cases (no match, one match, many matches).

@andrewleech
andrewleech force-pushed the expose_mp_repl_autocomplete branch from 6709f5e to 5dd9ba0 Compare February 16, 2026 07:57
@andrewleech

Copy link
Copy Markdown
Contributor Author

Updated the branch with a few fixes and an additional feature:

Fixed a type mismatch in repl_autocomplete — was using ssize_t (not available on MSVC, hence all the Windows CI failures) and <= 0 which incorrectly returned None for zero-length completions. Now uses size_t and compares against (size_t)(-1) matching how readline.c handles the same sentinel. The test also now uses repr() on outputs which avoids the trailing whitespace comparison issue that was likely causing the unix CI failures.

Also added micropython.stdio_mode_raw(enabled) in a second commit. This wraps the existing mp_hal_stdio_mode_raw() / mp_hal_stdio_mode_orig() HAL functions so Python code can control terminal mode directly — needed for aiorepl to properly manage terminal I/O without relying on the native REPL's implicit mode switching. Gated behind MICROPY_PY_MICROPYTHON_STDIO_RAW with a default of 0 in mpconfig.h, enabled on unix.

Added docs entries for both functions in micropython.rst.

@andrewleech
andrewleech force-pushed the expose_mp_repl_autocomplete branch 2 times, most recently from dad98b0 to 84cc57e Compare February 16, 2026 08:30
@codecov

codecov Bot commented Feb 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.46%. Comparing base (2dc2e30) to head (aeda0fa).
⚠️ Report is 491 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #17011   +/-   ##
=======================================
  Coverage   98.46%   98.46%           
=======================================
  Files         176      176           
  Lines       22784    22793    +9     
=======================================
+ Hits        22435    22444    +9     
  Misses        349      349           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Allows adding tab completion to custom REPLs such as aiorepl.

Returns a non-empty string (the completion suffix) on a unique match or
common prefix, an empty string when multiple candidates are printed to
stdout, or None when there is no match.

Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
@andrewleech
andrewleech force-pushed the expose_mp_repl_autocomplete branch from 047a306 to aeda0fa Compare March 26, 2026 14:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

py-core Relates to py/ directory in source

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants