Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
2b48860
aiorepl: Fix Enter key handling in raw terminal mode.
pi-anl Jun 2, 2025
0b18838
usb-device-cdc: Fix default timeout in CDCInterface.init().
pi-anl Feb 15, 2026
501daf4
colorsys: Add colorsys and test_colorsys from CPython.
pi-mst Sep 30, 2021
da7584d
uuid: Provide UUID class and uuid4() implementation using os.urandom().
andrewleech Oct 15, 2018
31a65f1
uuid: Convert test to use unittest.
dpgeorge Jul 11, 2026
ff6c2d4
uuid: Use bytes.hex instead of binascii.hexlify.
dpgeorge Jul 11, 2026
81fd893
uuid: Add UUID.bytes attribute.
dpgeorge Jul 20, 2026
00109e9
uuid: Make UUID.__repr__ match CPython.
dpgeorge Jul 20, 2026
e13a8e8
umqtt.simple: Encode subscribe Remaining Length as VBI.
pablogventura Jul 16, 2026
e2a6949
umqtt.simple: Share subscribe/unsubscribe packet encoding.
pablogventura Jul 20, 2026
315af6d
umqtt.simple: Share Remaining Length VBI encoding.
pablogventura Jul 20, 2026
327a15e
umqtt.simple: Avoid None comparisons in _send_subunsub.
pablogventura Jul 20, 2026
64907fc
tools/ci.sh: Add umqtt.simple mock test to package tests CI.
pablogventura Jul 27, 2026
77b8ee7
usb-device-cdc: Optimise CDCInterface constructor.
dpgeorge Jul 15, 2026
769c8fc
usb/examples: Put timeout=0 in CDCInterface constructor.
dpgeorge Jul 15, 2026
641e8b1
aioble/security: Only schedule save when needed.
pi-anl Sep 23, 2021
a2e279c
requests: Add support for query and anchor chars directly after domain.
PermissionDenied7335 Oct 19, 2023
ab6047c
requests: Add tests for query and anchor in URL.
dpgeorge Aug 6, 2026
33c3822
requests: Add chunked response body support.
pablogventura Jul 4, 2026
75d3976
requests: Test chunked response decoding.
pablogventura Jul 4, 2026
3c0d0a5
requests: Document chunked response support.
pablogventura Jul 4, 2026
a747e80
python-ecosys/debugpy: Add VS Code debugging support for MicroPython.
pi-anl Jun 11, 2025
c80bfd3
test_vscode: Add global variables to show vaiable tracking and hover.
Josverl Jun 12, 2025
291e705
debugpy: Improve variable retrievals.
Josverl Jun 12, 2025
03bdabb
dap_monitor: Exit session on debugger disconnect.
Josverl Jun 12, 2025
eebafee
debugpy: Fix VS Code path mapping to prevent read-only file copies.
pi-anl Jun 16, 2025
69c3b26
debugpy: Enhance PDB adapter with special variable processing.
Josverl Jun 18, 2025
02bba91
debugpy/dap_monitor: Add cli for target and ports.
Josverl Jun 19, 2025
c5082c1
debugpy/debug_session: Detect bare metal ports.
Josverl Jun 19, 2025
e2c5bb3
debugpy : Format code.
Josverl Jun 19, 2025
6e3f207
debugpy : Decode debugger IP address on connect.
Josverl Jun 24, 2025
7240308
debugpy: Add type hints and improve path mapping logic in PDB adapter.
Josverl Jun 29, 2025
69cd729
debugpy: Add complex variable handling and caching.
Josverl Jun 30, 2025
ec4dc98
debugpy: Enhance path mapping handling in PDB adapter and debug session.
Josverl Jun 29, 2025
c19d6bf
debugpy: Format code.
Josverl Jun 30, 2025
80dc067
debugpy: Enhance breakpoint handling and path mapping in PdbAdapter.
Josverl Jun 30, 2025
fdb0a18
debugpy : Optimize memory management and performance in PDB adapter.
Josverl Jun 30, 2025
5ab5a3f
debugpy: Store breakpoints in sets rather than lists.
Josverl Jun 30, 2025
42d3551
Merge branch 'pdb_support/perf2' into debugpy/performance
Josverl Jun 30, 2025
564401b
revert: Overly complex variable preview.
Josverl Jun 30, 2025
8f01ba4
debugpy: Performance improvements.
Josverl Jul 1, 2025
64fb03e
debugpy: Performance - aviod method access.
Josverl Jul 1, 2025
b649869
py-ecosys/debugpy: Add pause functionality.
Josverl Jul 1, 2025
2e858e6
python-ecosys/debugpy: Add set Variable functionality.
Josverl Jul 1, 2025
f55fffb
python-ecosys/debugpy: Add local variable modification while debugging.
Josverl Jul 1, 2025
9ef4f77
python-ecosys/debugpy: Format code with ruff.
Josverl Jul 1, 2025
5cc1ff5
python-ecosys/debugpy: Code cleanup.
Josverl Jul 1, 2025
1efe729
debugpy: Capitalise the "Special" variables scope name.
Josverl Jul 14, 2025
01665cd
debugpy: Reassemble DAP messages split across recv() calls.
pi-anl Jul 5, 2026
e4c8169
debugpy: Add wait_for_client, a capability probe and read-only locals.
pi-anl Jul 5, 2026
6318df3
debugpy: Execute statements from repl and clipboard evaluate contexts.
pi-anl Jul 14, 2026
7d15d4e
debugpy: Return the bound endpoint from listen() before accepting.
pi-anl Aug 5, 2026
9c91034
debugpy: Stop nested message pumps from clobbering the socket timeout.
pi-anl Aug 6, 2026
1544fad
debugpy: Make debug_session.py match tools/codeformat.py.
pi-anl Aug 8, 2026
033bc85
debugpy: Fix the EXE001 shebangs on the three top-level scripts.
pi-anl Aug 8, 2026
4da4c34
debugpy: Fix the four typos codespell reports in debug_session.py.
pi-anl Aug 8, 2026
c7d973e
debugpy: Start the debugger around the sample, not inside it.
andrewleech Aug 9, 2026
2f36b80
debugpy: Run the DAP channel over a stream, not only a TCP socket.
pi-anl Aug 7, 2026
e367c15
debugpy: Derive serial_dap from the channel in use.
pi-anl Aug 8, 2026
df0a46e
debugpy: Probe save_names on code the firmware compiled.
andrewleech Aug 8, 2026
b2d0a6a
debugpy: Accept every idle errno, and finish every socket write.
andrewleech Aug 8, 2026
f448206
debugpy: Replace both keys a file's breakpoints are stored under.
andrewleech Aug 8, 2026
7746778
debugpy: Give StreamTransport.send the socket short-write contract.
andrewleech Aug 8, 2026
66ed177
debugpy: Make DAP path translation symmetric and boundary-aware.
andrewleech Aug 8, 2026
caa6bbc
debugpy: Keep the message pump from raising into the debuggee.
andrewleech Aug 8, 2026
9457f2d
debugpy: Stop at a breakpoint only on the events that precede the line.
andrewleech Aug 8, 2026
877ccfd
debugpy: Honour a DAP restart, and add a target console channel.
andrewleech Aug 8, 2026
f179e80
debugpy: Correct the README's claims and the placeholder format.
andrewleech Aug 8, 2026
9c2af1a
debugpy: Make the development guide match a measured session.
andrewleech Aug 8, 2026
a1649ab
debugpy: Let a stream say the host has gone when it cannot reach EOF.
andrewleech Aug 10, 2026
d15c876
debugpy: Stop the target when the client asks it to pause.
andrewleech Aug 10, 2026
33af8af
debugpy: Share the REPL's stream with the DAP channel.
andrewleech Aug 10, 2026
d669e3a
debugpy: End a stream session when the host that held it lets go.
andrewleech Aug 11, 2026
abb03f6
debugpy: Drop the serial_dap capability.
andrewleech Aug 20, 2026
b12d2f6
debugpy: Probe the firmware's capabilities once per interpreter.
andrewleech Aug 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions micropython/aiorepl/aiorepl.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,16 +121,22 @@ async def task(g=None, prompt="--> "):
pt = t # save previous time
t = time.ticks_ms()
if c < 0x20 or c > 0x7E:
if c == 0x0A:
# LF
if c == 0x0A or c == 0x0D:
# LF or CR (handle both for raw terminal mode compatibility)
if paste:
# In paste mode, preserve the actual character
sys.stdout.write(b)
cmd += b
continue
# If the previous character was also LF, and was less
# than 20 ms ago, this was likely due to CRLF->LFLF
# conversion, so ignore this linefeed.
if pc == 0x0A and time.ticks_diff(t, pt) < 20:
# Handle various newline sequences to avoid double-execution:
# - CR+LF (Windows style): ignore LF if it follows CR quickly
# - LF+LF (PTY double-newline): ignore second LF if it follows quickly
# - CR+CR (potential double-CR): ignore second CR if it follows quickly
if (
(c == 0x0A and pc == 0x0D) # LF after CR (CRLF)
or (c == 0x0A and pc == 0x0A) # LF after LF (double LF)
or (c == 0x0D and pc == 0x0D)
) and time.ticks_diff(t, pt) < 20: # CR after CR
continue
if curs:
# move cursor to end of the line
Expand Down
2 changes: 1 addition & 1 deletion micropython/aiorepl/manifest.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
metadata(
version="0.2.2",
version="0.2.3",
description="Provides an asynchronous REPL that can run concurrently with an asyncio, also allowing await expressions.",
)

Expand Down
2 changes: 1 addition & 1 deletion micropython/bluetooth/aioble-security/manifest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
metadata(version="0.2.0")
metadata(version="0.2.1")

require("aioble-core")

Expand Down
9 changes: 3 additions & 6 deletions micropython/bluetooth/aioble/aioble/security.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,6 @@ def _save_secrets(arg=None):

_path = _path or _DEFAULT_PATH

if not _modified:
# Only save if the secrets changed.
return

with open(_path, "w") as f:
# Convert bytes to hex strings (otherwise JSON will treat them like
# strings).
Expand Down Expand Up @@ -106,8 +102,9 @@ def _security_irq(event, data):
_secrets[key] = value

# Queue up a save (don't synchronously write to flash).
_modified = True
schedule(_save_secrets, None)
if not _modified:
_modified = True
schedule(_save_secrets, None)

return True

Expand Down
2 changes: 1 addition & 1 deletion micropython/bluetooth/aioble/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# code. This allows (for development purposes) all the files to live in the
# one directory.

metadata(version="0.6.1")
metadata(version="0.6.2")

# Default installation gives you everything. Install the individual
# components (or a combination of them) if you want a more minimal install.
Expand Down
2 changes: 1 addition & 1 deletion micropython/umqtt.simple/manifest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
metadata(description="Lightweight MQTT client for MicroPython.", version="1.7.1")
metadata(description="Lightweight MQTT client for MicroPython.", version="1.8.0")

# Originally written by Paul Sokolovsky.

Expand Down
76 changes: 76 additions & 0 deletions micropython/umqtt.simple/test_umqtt_simple.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import io
import sys


class Socket:
def __init__(self, read_data=b""):
self._write_buffer = io.BytesIO()
self._read_buffer = io.BytesIO(read_data)

def write(self, buf, length=None):
if length is None:
length = len(buf)
self._write_buffer.write(buf[:length])

def read(self, n):
return self._read_buffer.read(n)

def setblocking(self, blocking):
pass

def close(self):
pass


sys.path.insert(0, "micropython/umqtt.simple")
# ruff: noqa: E402
from umqtt.simple import MQTTClient


def make_client(read_data):
c = MQTTClient(b"cid", "127.0.0.1")
c.sock = Socket(read_data)
c.set_callback(lambda topic, msg: None)
return c


def test_subscribe_short_topic():
# Remaining Length = 5 + 4 = 9 -> single VBI byte 0x09, pid=1
c = make_client(b"\x90\x03\x00\x01\x00")
c.subscribe(b"abcd", qos=0)
out = c.sock._write_buffer.getvalue()
assert out[:2] == b"\x82\x09", out
assert out[2:4] == b"\x00\x01", out
assert out[4:6] == b"\x00\x04", out
assert out[6:10] == b"abcd", out
assert out[10:11] == b"\x00", out


def test_subscribe_long_topic():
# Remaining Length = 5 + 123 = 128 -> VBI 0x80 0x01
topic = b"a" * 123
c = make_client(b"\x90\x03\x00\x01\x00")
c.subscribe(topic, qos=0)
out = c.sock._write_buffer.getvalue()
assert out[:3] == b"\x82\x80\x01", out
assert out[3:5] == b"\x00\x01", out
assert out[5:7] == b"\x00\x7b", out
assert out[7:130] == topic, out
assert out[130:131] == b"\x00", out


def test_unsubscribe_long_topic():
# Remaining Length = 4 + 123 = 127 -> still one VBI byte; use 124 for 128
topic = b"a" * 124
c = make_client(b"\xb0\x02\x00\x01")
c.unsubscribe(topic)
out = c.sock._write_buffer.getvalue()
assert out[:3] == b"\xa2\x80\x01", out
assert out[3:5] == b"\x00\x01", out
assert out[5:7] == b"\x00\x7c", out
assert out[7:131] == topic, out


test_subscribe_short_topic()
test_subscribe_long_topic()
test_unsubscribe_long_topic()
66 changes: 31 additions & 35 deletions micropython/umqtt.simple/umqtt/simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ class MQTTException(Exception):
pass


def _encode_len(pkt, sz):
i = 1
while sz > 0x7F:
pkt[i] = (sz & 0x7F) | 0x80
sz >>= 7
i += 1
pkt[i] = sz
return i


class MQTTClient:
def __init__(
self,
Expand Down Expand Up @@ -93,12 +103,7 @@ def connect(self, clean_session=True, timeout=None):
msg[6] |= 0x4 | (self.lw_qos & 0x1) << 3 | (self.lw_qos & 0x2) << 3
msg[6] |= self.lw_retain << 5

i = 1
while sz > 0x7F:
premsg[i] = (sz & 0x7F) | 0x80
sz >>= 7
i += 1
premsg[i] = sz
i = _encode_len(premsg, sz)

self.sock.write(premsg, i + 2)
self.sock.write(msg)
Expand Down Expand Up @@ -130,12 +135,7 @@ def publish(self, topic, msg, retain=False, qos=0):
if qos > 0:
sz += 2
assert sz < 2097152
i = 1
while sz > 0x7F:
pkt[i] = (sz & 0x7F) | 0x80
sz >>= 7
i += 1
pkt[i] = sz
i = _encode_len(pkt, sz)
# print(hex(len(pkt)), hexlify(pkt, ":"))
self.sock.write(pkt, i + 1)
self._send_str(topic)
Expand All @@ -158,37 +158,33 @@ def publish(self, topic, msg, retain=False, qos=0):
elif qos == 2:
assert 0

def subscribe(self, topic, qos=0):
assert self.cb is not None, "Subscribe callback is not set"
pkt = bytearray(b"\x82\0\0\0")
def _send_subunsub(self, topic, typ, ack_op, ack_n, qos=0):
pkt = bytearray(4)
pkt[0] = typ
self.pid += 1
struct.pack_into("!BH", pkt, 1, 2 + 2 + len(topic) + 1, self.pid)
# print(hex(len(pkt)), hexlify(pkt, ":"))
self.sock.write(pkt)
pid = self.pid
i = _encode_len(pkt, 4 + len(topic) + (ack_n > 3))
self.sock.write(pkt, i + 1)
struct.pack_into("!H", pkt, 0, pid)
self.sock.write(pkt, 2)
self._send_str(topic)
self.sock.write(qos.to_bytes(1, "little"))
if ack_n > 3:
self.sock.write(bytes((qos,)))
while 1:
op = self.wait_msg()
if op == 0x90:
resp = self.sock.read(4)
# print(resp)
assert resp[1] == pkt[2] and resp[2] == pkt[3]
if resp[3] == 0x80:
if op == ack_op:
resp = self.sock.read(ack_n)
assert (resp[1] << 8 | resp[2]) == pid
if ack_n > 3 and resp[3] == 0x80:
raise MQTTException(resp[3])
return

def subscribe(self, topic, qos=0):
assert self.cb is not None, "Subscribe callback is not set"
self._send_subunsub(topic, 0x82, 0x90, 4, qos)

def unsubscribe(self, topic):
pkt = bytearray(b"\xa2\0\0\0")
self.pid += 1
struct.pack_into("!BH", pkt, 1, 2 + 2 + len(topic), self.pid)
self.sock.write(pkt)
self._send_str(topic)
while 1:
op = self.wait_msg()
if op == 0xB0:
resp = self.sock.read(3)
assert resp[1] == pkt[2] and resp[2] == pkt[3]
return
self._send_subunsub(topic, 0xA2, 0xB0, 3)

# Wait for a single incoming MQTT message and process it.
# Subscribed messages are delivered to a callback previously
Expand Down
4 changes: 2 additions & 2 deletions micropython/usb/examples/device/cdc_repl_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
import usb.device
from usb.device.cdc import CDCInterface

cdc = CDCInterface()
cdc.init(timeout=0) # zero timeout makes this non-blocking, suitable for os.dupterm()
# Zero timeout makes this non-blocking, suitable for os.dupterm().
cdc = CDCInterface(timeout=0)

# pass builtin_driver=True so that we get the built-in USB-CDC alongside,
# if it's available.
Expand Down
2 changes: 1 addition & 1 deletion micropython/usb/usb-device-cdc/manifest.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
metadata(version="0.1.2")
metadata(version="0.1.4")
require("usb-device")
package("usb")
10 changes: 3 additions & 7 deletions micropython/usb/usb-device-cdc/usb/device/cdc.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,22 +107,18 @@ def __init__(self, **kwargs):
self.line_coding_cb = None

self._line_state = 0 # DTR & RTS
# Set a default line coding of 115200/8N1
self._line_coding = bytearray(b"\x00\xc2\x01\x00\x00\x00\x08")

self._wb = () # Optional write Buffer (IN endpoint), set by CDC.init()
self._rb = () # Optional read Buffer (OUT endpoint), set by CDC.init()
self._timeout = 1000 # set from CDC.init() as well
self._line_coding = bytearray(7) # Will be populated by .init()

# one control interface endpoint, two data interface endpoints
self.ep_c_in = self.ep_d_in = self.ep_d_out = None

self._c_itf = None # Number of control interface, data interface is one more

# The _timeout, _wb and _rb attributes will be set by this call to .init().
self.init(**kwargs)

def init(
self, baudrate=9600, bits=8, parity="N", stop=1, timeout=None, txbuf=256, rxbuf=256, flow=0
self, baudrate=9600, bits=8, parity="N", stop=1, timeout=1000, txbuf=256, rxbuf=256, flow=0
):
# Configure the CDC serial port. Note that many of these settings like
# baudrate, bits, parity, stop don't change the USB-CDC device behavior
Expand Down
Loading