Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package micropython-lib for openSUSE:Factory 
checked in at 2026-04-28 11:58:10
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/micropython-lib (Old)
 and      /work/SRC/openSUSE:Factory/.micropython-lib.new.11940 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "micropython-lib"

Tue Apr 28 11:58:10 2026 rev:7 rq:1349591 version:1.28.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/micropython-lib/micropython-lib.changes  
2026-02-20 17:43:09.168709777 +0100
+++ 
/work/SRC/openSUSE:Factory/.micropython-lib.new.11940/micropython-lib.changes   
    2026-04-28 12:02:06.215797998 +0200
@@ -1,0 +2,16 @@
+Mon Apr 27 10:10:03 UTC 2026 - Simon Haendler <[email protected]>
+
+- Update to 1.28.0
+  * string: Convert string module to package and import templatelib.
+  * unix-ffi/_libc: Extend FreeBSD libc versions range.
+  * senml/docs: Correct capitalization of 'MicroPython'.
+  * unix-ffi/machine: Retrieve a unique identifier if one is known.
+  * unix-ffi/re: Add tests for empty string match in ffi regex.
+  * unix-ffi/re: Handle PCRE2_UNSET in group and groups methods.
+  * lsm6dsox: Add pedometer example code.
+  * lsm6dsox: Add pedometer support.
+  * sdcard: Add read/write speed test to sdtest.
+  * sdcard: Compute CRC7 for all SPI commands.
+  * sdcard: Send stop bit after multi-block read/write.
+
+-------------------------------------------------------------------

Old:
----
  micropython-lib-1.27.0.tar.gz

New:
----
  micropython-lib-1.28.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ micropython-lib.spec ++++++
--- /var/tmp/diff_new_pack.dCOQ19/_old  2026-04-28 12:02:06.759820535 +0200
+++ /var/tmp/diff_new_pack.dCOQ19/_new  2026-04-28 12:02:06.759820535 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           micropython-lib
-Version:        1.27.0
+Version:        1.28.0
 Release:        0
 Summary:        Core Python libraries ported to MicroPython
 License:        MIT AND Python-2.0

++++++ micropython-lib-1.27.0.tar.gz -> micropython-lib-1.28.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/micropython-lib-1.27.0/micropython/drivers/imu/lsm6dsox/lsm6dsox.py 
new/micropython-lib-1.28.0/micropython/drivers/imu/lsm6dsox/lsm6dsox.py
--- old/micropython-lib-1.27.0/micropython/drivers/imu/lsm6dsox/lsm6dsox.py     
2025-12-08 01:20:11.000000000 +0100
+++ new/micropython-lib-1.28.0/micropython/drivers/imu/lsm6dsox/lsm6dsox.py     
2026-03-23 01:17:33.000000000 +0100
@@ -60,6 +60,13 @@
 _OUTX_L_G = const(0x22)
 _OUTX_L_XL = const(0x28)
 _MLC_STATUS = const(0x38)
+_MD1_CFG = const(0x5E)
+_MD2_CFG = const(0x5F)
+
+_PAGE_SEL = const(0x02)
+_PAGE_ADDRESS = const(0x08)
+_PAGE_VALUE = const(0x09)
+_PAGE_RW = const(0x17)
 
 _DEFAULT_ADDR = const(0x6A)
 _WHO_AM_I_REG = const(0x0F)
@@ -75,6 +82,17 @@
 
 _EMB_FUNC_EN_A = const(0x04)
 _EMB_FUNC_EN_B = const(0x05)
+_EMB_FUNC_INT1 = const(0x0A)
+_EMB_FUNC_INT2 = const(0x0E)
+_EMB_FUNC_SRC = const(0x64)
+_STEP_COUNTER_L = const(0x62)
+
+_PEDO_DEB_STEPS_CONF = const(0x0184)
+
+_PEDO_EN_MASK = const(0x08)
+_PEDO_RST_STEP_MASK = const(0x80)
+_PEDO_INT_MASK = const(0x08)
+_INT_EMB_FUNC_MASK = const(0x02)
 
 
 class LSM6DSOX:
@@ -108,8 +126,9 @@
         if self._read_reg(_WHO_AM_I_REG) != 108:
             raise OSError("No LSM6DS device was found at address 0x%x" % 
(self.address))
 
-        # allocate scratch buffer for efficient conversions and memread op's
+        # allocate scratch buffers for efficient conversions and memread op's
         self.scratch_int = array.array("h", [0, 0, 0])
+        self.scratch_2b = bytearray(2)
 
         SCALE_GYRO = {250: 0, 500: 1, 1000: 2, 2000: 3}
         SCALE_ACCEL = {2: 0, 4: 2, 8: 3, 16: 1}
@@ -185,6 +204,9 @@
             finally:
                 self.cs(1)
 
+    def _modify_bits(self, reg, clr_mask=0, set_mask=0):
+        self._write_reg(reg, (self._read_reg(reg) & ~clr_mask) | set_mask)
+
     def _read_reg_into(self, reg, buf):
         if self._use_i2c:
             self.bus.readfrom_mem_into(self.address, reg, buf)
@@ -196,8 +218,43 @@
             finally:
                 self.cs(1)
 
+    def _select_page(self, address, value=None):
+        """
+        Selects the embedded function page and reads/writes the value at the 
given address.
+        If value is None, it reads the value at the address. Otherwise, it 
writes the value to the address.
+        """
+        msb = (address >> 8) & 0x0F  # MSB is the page number
+        lsb = address & 0xFF  # LSB is the register address within the page
+
+        self.set_mem_bank(_FUNC_CFG_BANK_EMBED)
+
+        rw_bit = 0x20 if value is None else 0x40
+        # Clear both read and write bits first, then set read (bit 5) or write 
(bit 6).
+        self._modify_bits(_PAGE_RW, clr_mask=0x60, set_mask=rw_bit)
+
+        # select page
+        self._write_reg(_PAGE_SEL, (msb << 4) | 0x01)
+
+        # set page addr
+        self._write_reg(_PAGE_ADDRESS, lsb)
+
+        val = None
+        if value is None:
+            # read value
+            val = self._read_reg(_PAGE_VALUE)
+        else:
+            # write value
+            self._write_reg(_PAGE_VALUE, value)
+
+        # unset page write/read and page_sel
+        self._write_reg(_PAGE_SEL, 0x01)
+        self._modify_bits(_PAGE_RW, clr_mask=rw_bit)
+
+        self.set_mem_bank(_FUNC_CFG_BANK_USER)
+        return val
+
     def reset(self):
-        self._write_reg(_CTRL3_C, self._read_reg(_CTRL3_C) | 0x1)
+        self._modify_bits(_CTRL3_C, set_mask=0x1)
         for i in range(10):
             if (self._read_reg(_CTRL3_C) & 0x01) == 0:
                 return
@@ -205,8 +262,7 @@
         raise OSError("Failed to reset LSM6DS device.")
 
     def set_mem_bank(self, bank):
-        cfg = self._read_reg(_FUNC_CFG_ACCESS) & 0x3F
-        self._write_reg(_FUNC_CFG_ACCESS, cfg | (bank << 6))
+        self._modify_bits(_FUNC_CFG_ACCESS, clr_mask=0xC0, set_mask=(bank << 
6))
 
     def set_embedded_functions(self, enable, emb_ab=None):
         self.set_mem_bank(_FUNC_CFG_BANK_EMBED)
@@ -234,18 +290,18 @@
         emb_ab = self.set_embedded_functions(False)
 
         # Disable I3C interface
-        self._write_reg(_CTRL9_XL, self._read_reg(_CTRL9_XL) | 0x01)
+        self._modify_bits(_CTRL9_XL, set_mask=0x01)
 
         # Enable Block Data Update
-        self._write_reg(_CTRL3_C, self._read_reg(_CTRL3_C) | 0x40)
+        self._modify_bits(_CTRL3_C, set_mask=0x40)
 
         # Route signals on interrupt pin 1
         self.set_mem_bank(_FUNC_CFG_BANK_EMBED)
-        self._write_reg(_MLC_INT1, self._read_reg(_MLC_INT1) & 0x01)
+        self._modify_bits(_MLC_INT1, clr_mask=0xFE)
         self.set_mem_bank(_FUNC_CFG_BANK_USER)
 
         # Configure interrupt pin mode
-        self._write_reg(_TAP_CFG0, self._read_reg(_TAP_CFG0) | 0x41)
+        self._modify_bits(_TAP_CFG0, set_mask=0x41)
 
         self.set_embedded_functions(True, emb_ab)
 
@@ -258,6 +314,36 @@
             self.set_mem_bank(_FUNC_CFG_BANK_USER)
         return buf
 
+    def pedometer_config(self, enable=True, debounce=10, int1_enable=False, 
int2_enable=False):
+        """Configure the pedometer features."""
+        self._select_page(_PEDO_DEB_STEPS_CONF, debounce)
+
+        if int1_enable:
+            self._modify_bits(_MD1_CFG, set_mask=_INT_EMB_FUNC_MASK)
+        if int2_enable:
+            self._modify_bits(_MD2_CFG, set_mask=_INT_EMB_FUNC_MASK)
+
+        self.set_mem_bank(_FUNC_CFG_BANK_EMBED)
+
+        self._modify_bits(_EMB_FUNC_EN_A, _PEDO_EN_MASK, enable and 
_PEDO_EN_MASK)
+        self._modify_bits(_EMB_FUNC_INT1, _PEDO_INT_MASK, int1_enable and 
_PEDO_INT_MASK)
+        self._modify_bits(_EMB_FUNC_INT2, _PEDO_INT_MASK, int2_enable and 
_PEDO_INT_MASK)
+
+        self.set_mem_bank(_FUNC_CFG_BANK_USER)
+
+    def pedometer_reset(self):
+        """Reset the step counter."""
+        self.set_mem_bank(_FUNC_CFG_BANK_EMBED)
+        self._modify_bits(_EMB_FUNC_SRC, set_mask=_PEDO_RST_STEP_MASK)
+        self.set_mem_bank(_FUNC_CFG_BANK_USER)
+
+    def steps(self):
+        """Return the number of detected steps."""
+        self.set_mem_bank(_FUNC_CFG_BANK_EMBED)
+        self._read_reg_into(_STEP_COUNTER_L, self.scratch_2b)
+        self.set_mem_bank(_FUNC_CFG_BANK_USER)
+        return self.scratch_2b[0] | (self.scratch_2b[1] << 8)
+
     def gyro(self):
         """Returns gyroscope vector in degrees/sec."""
         mv = memoryview(self.scratch_int)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/micropython-lib-1.27.0/micropython/drivers/imu/lsm6dsox/lsm6dsox_pedometer.py
 
new/micropython-lib-1.28.0/micropython/drivers/imu/lsm6dsox/lsm6dsox_pedometer.py
--- 
old/micropython-lib-1.27.0/micropython/drivers/imu/lsm6dsox/lsm6dsox_pedometer.py
   1970-01-01 01:00:00.000000000 +0100
+++ 
new/micropython-lib-1.28.0/micropython/drivers/imu/lsm6dsox/lsm6dsox_pedometer.py
   2026-03-23 01:17:33.000000000 +0100
@@ -0,0 +1,55 @@
+"""
+LSM6DSOX IMU Pedometer Example.
+
+This example demonstrates how to use the built-in pedometer feature of the 
LSM6DSOX IMU.
+The pedometer counts the number of steps taken based on the accelerometer data
+and can generate interrupts when a step is detected.
+
+Copyright (C) Arduino s.r.l. and/or its affiliated companies
+"""
+
+import time
+from lsm6dsox import LSM6DSOX
+
+from machine import Pin, I2C
+
+lsm = LSM6DSOX(I2C(0))
+# Or init in SPI mode.
+# lsm = LSM6DSOX(SPI(5), cs=Pin(10))
+
+# Enable the pedometer feature, set debounce steps to 5, and enable interrupts 
on both INT1 and INT2.
+# Default debounce steps is 10. This means that after a step is detected, the 
pedometer
+# will ignore any new steps for the next 5 step detections. This can help to 
filter out
+# false positives and improve step counting accuracy.
+# If you just want to enable the pedometer, simply call 
lsm.pedometer_config(enable=True).
+lsm.pedometer_config(debounce=5, int1_enable=True, int2_enable=True)
+
+# Register interrupt handler on a Pin. e.g. D8
+# The interrupt pins are push-pull outputs by default that go low when a step 
is detected.
+# You can connect either INT1 or INT2 to the interrupt pin.
+interrupt_pin = Pin("D8", Pin.IN)  # Change this to your desired interrupt pin.
+interrupt_fired = False  # Flag to indicate if the interrupt has been fired.
+
+
+def on_step_detected(pin):
+    global interrupt_fired
+    interrupt_fired = True
+
+
+# Configure the interrupt pin to trigger on falling edge (active low) when a 
step is detected.
+interrupt_pin.irq(trigger=Pin.IRQ_FALLING, handler=on_step_detected)
+
+last_steps = None  # Keep track of the last step count to detect changes.
+
+while True:
+    if interrupt_fired:
+        print("Step detected!")
+        interrupt_fired = False  # Reset the flag after handling the interrupt.
+
+    steps = lsm.steps()
+
+    if steps != last_steps:
+        print(f"Steps: {steps}")
+        last_steps = steps
+
+    time.sleep_ms(100)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/micropython-lib-1.27.0/micropython/drivers/imu/lsm6dsox/manifest.py 
new/micropython-lib-1.28.0/micropython/drivers/imu/lsm6dsox/manifest.py
--- old/micropython-lib-1.27.0/micropython/drivers/imu/lsm6dsox/manifest.py     
2025-12-08 01:20:11.000000000 +0100
+++ new/micropython-lib-1.28.0/micropython/drivers/imu/lsm6dsox/manifest.py     
2026-03-23 01:17:33.000000000 +0100
@@ -1,2 +1,2 @@
-metadata(description="ST LSM6DSOX imu driver.", version="1.0.1")
+metadata(description="ST LSM6DSOX imu driver.", version="1.1.0")
 module("lsm6dsox.py", opt=3)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/micropython-lib-1.27.0/micropython/drivers/storage/sdcard/manifest.py 
new/micropython-lib-1.28.0/micropython/drivers/storage/sdcard/manifest.py
--- old/micropython-lib-1.27.0/micropython/drivers/storage/sdcard/manifest.py   
2025-12-08 01:20:11.000000000 +0100
+++ new/micropython-lib-1.28.0/micropython/drivers/storage/sdcard/manifest.py   
2026-03-23 01:17:33.000000000 +0100
@@ -1,3 +1,3 @@
-metadata(description="SDCard block device driver.", version="0.1.1")
+metadata(description="SDCard block device driver.", version="0.2.0")
 
 module("sdcard.py", opt=3)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/micropython-lib-1.27.0/micropython/drivers/storage/sdcard/sdcard.py 
new/micropython-lib-1.28.0/micropython/drivers/storage/sdcard/sdcard.py
--- old/micropython-lib-1.27.0/micropython/drivers/storage/sdcard/sdcard.py     
2025-12-08 01:20:11.000000000 +0100
+++ new/micropython-lib-1.28.0/micropython/drivers/storage/sdcard/sdcard.py     
2026-03-23 01:17:33.000000000 +0100
@@ -38,6 +38,15 @@
 _TOKEN_DATA = const(0xFE)
 
 
+def _crc7(buf, n):
+    crc = 0
+    for i in range(n):
+        crc ^= buf[i]
+        for j in range(8):
+            crc = ((crc << 1) ^ (0x12 * (crc >> 7))) & 0xFF
+    return crc
+
+
 class SDCard:
     def __init__(self, spi, cs, baudrate=1320000):
         self.spi = spi
@@ -76,13 +85,13 @@
 
         # CMD0: init card; should return _R1_IDLE_STATE (allow 5 attempts)
         for _ in range(5):
-            if self.cmd(0, 0, 0x95) == _R1_IDLE_STATE:
+            if self.cmd(0, 0) == _R1_IDLE_STATE:
                 break
         else:
             raise OSError("no SD card")
 
         # CMD8: determine card version
-        r = self.cmd(8, 0x01AA, 0x87, 4)
+        r = self.cmd(8, 0x01AA, 4)
         if r == _R1_IDLE_STATE:
             self.init_card_v2()
         elif r == (_R1_IDLE_STATE | _R1_ILLEGAL_COMMAND):
@@ -92,7 +101,7 @@
 
         # get the number of sectors
         # CMD9: response R2 (R1 byte + 16-byte block read)
-        if self.cmd(9, 0, 0, 0, False) != 0:
+        if self.cmd(9, 0, 0, False) != 0:
             raise OSError("no response from SD card")
         csd = bytearray(16)
         self.readinto(csd)
@@ -109,7 +118,7 @@
         # print('sectors', self.sectors)
 
         # CMD16: set block length to 512 bytes
-        if self.cmd(16, 512, 0) != 0:
+        if self.cmd(16, 512) != 0:
             raise OSError("can't set 512 block size")
 
         # set to high data rate now that it's initialised
@@ -118,8 +127,8 @@
     def init_card_v1(self):
         for i in range(_CMD_TIMEOUT):
             time.sleep_ms(50)
-            self.cmd(55, 0, 0)
-            if self.cmd(41, 0, 0) == 0:
+            self.cmd(55, 0)
+            if self.cmd(41, 0) == 0:
                 # SDSC card, uses byte addressing in read/write/erase commands
                 self.cdv = 512
                 # print("[SDCard] v1 card")
@@ -129,10 +138,10 @@
     def init_card_v2(self):
         for i in range(_CMD_TIMEOUT):
             time.sleep_ms(50)
-            self.cmd(58, 0, 0, 4)
-            self.cmd(55, 0, 0)
-            if self.cmd(41, 0x40000000, 0) == 0:
-                self.cmd(58, 0, 0, -4)  # 4-byte response, negative means keep 
the first byte
+            self.cmd(58, 0, 4)
+            self.cmd(55, 0)
+            if self.cmd(41, 0x40000000) == 0:
+                self.cmd(58, 0, -4)  # 4-byte response, negative means keep 
the first byte
                 ocr = self.tokenbuf[0]  # get first byte of response, which is 
OCR
                 if not ocr & 0x40:
                     # SDSC card, uses byte addressing in read/write/erase 
commands
@@ -144,7 +153,7 @@
                 return
         raise OSError("timeout waiting for v2 card")
 
-    def cmd(self, cmd, arg, crc, final=0, release=True, skip1=False):
+    def cmd(self, cmd, arg, final=0, release=True, skip1=False):
         self.cs(0)
 
         # create and send the command
@@ -154,7 +163,7 @@
         buf[2] = arg >> 16
         buf[3] = arg >> 8
         buf[4] = arg
-        buf[5] = crc
+        buf[5] = _crc7(buf, 5) | 0x01  # ensure stop bit is always set
         self.spi.write(buf)
 
         if skip1:
@@ -250,7 +259,7 @@
         assert nblocks and not len(buf) % 512, "Buffer length is invalid"
         if nblocks == 1:
             # CMD17: set read address for single block
-            if self.cmd(17, block_num * self.cdv, 0, release=False) != 0:
+            if self.cmd(17, block_num * self.cdv, release=False) != 0:
                 # release the card
                 self.cs(1)
                 raise OSError(5)  # EIO
@@ -258,7 +267,7 @@
             self.readinto(buf)
         else:
             # CMD18: set read address for multiple blocks
-            if self.cmd(18, block_num * self.cdv, 0, release=False) != 0:
+            if self.cmd(18, block_num * self.cdv, release=False) != 0:
                 # release the card
                 self.cs(1)
                 raise OSError(5)  # EIO
@@ -269,7 +278,7 @@
                 self.readinto(mv[offset : offset + 512])
                 offset += 512
                 nblocks -= 1
-            if self.cmd(12, 0, 0xFF, skip1=True):
+            if self.cmd(12, 0, skip1=True):
                 raise OSError(5)  # EIO
 
     def writeblocks(self, block_num, buf):
@@ -281,14 +290,14 @@
         assert nblocks and not err, "Buffer length is invalid"
         if nblocks == 1:
             # CMD24: set write address for single block
-            if self.cmd(24, block_num * self.cdv, 0) != 0:
+            if self.cmd(24, block_num * self.cdv) != 0:
                 raise OSError(5)  # EIO
 
             # send the data
             self.write(_TOKEN_DATA, buf)
         else:
             # CMD25: set write address for first block
-            if self.cmd(25, block_num * self.cdv, 0) != 0:
+            if self.cmd(25, block_num * self.cdv) != 0:
                 raise OSError(5)  # EIO
             # send the data
             offset = 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/micropython-lib-1.27.0/micropython/drivers/storage/sdcard/sdtest.py 
new/micropython-lib-1.28.0/micropython/drivers/storage/sdcard/sdtest.py
--- old/micropython-lib-1.27.0/micropython/drivers/storage/sdcard/sdtest.py     
2025-12-08 01:20:11.000000000 +0100
+++ new/micropython-lib-1.28.0/micropython/drivers/storage/sdcard/sdtest.py     
2026-03-23 01:17:33.000000000 +0100
@@ -2,6 +2,7 @@
 # Peter hinch 30th Jan 2016
 import machine
 import os
+import time
 import sdcard
 
 
@@ -44,6 +45,26 @@
         result2 = f.read()
         print(len(result2), "bytes read")
 
+    fn = "/fc/speed.bin"
+    buf = bytearray(32768)  # 32 KB buffer
+
+    print()
+    print("Write speed test")
+    t = time.ticks_ms()
+    with open(fn, "wb") as f:
+        for _ in range(32):  # 1 MB total
+            f.write(buf)
+    elapsed = time.ticks_diff(time.ticks_ms(), t)
+    print("{} KB/s".format(32768 * 32 // elapsed))
+
+    print("Read speed test")
+    t = time.ticks_ms()
+    with open(fn, "rb") as f:
+        while f.readinto(buf):
+            pass
+    elapsed = time.ticks_diff(time.ticks_ms(), t)
+    print("{} KB/s".format(32768 * 32 // elapsed))
+
     os.umount("/fc")
 
     print()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/micropython-lib-1.27.0/micropython/senml/docs/index.md 
new/micropython-lib-1.28.0/micropython/senml/docs/index.md
--- old/micropython-lib-1.27.0/micropython/senml/docs/index.md  2025-12-08 
01:20:11.000000000 +0100
+++ new/micropython-lib-1.28.0/micropython/senml/docs/index.md  2026-03-23 
01:17:33.000000000 +0100
@@ -1,4 +1,4 @@
-Welcome to the API document site for the micro-python SenML library.
+Welcome to the API document site for the MicroPython SenML library.
 
 The following api sections are available:
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/micropython-lib-1.27.0/python-stdlib/string/manifest.py 
new/micropython-lib-1.28.0/python-stdlib/string/manifest.py
--- old/micropython-lib-1.27.0/python-stdlib/string/manifest.py 2025-12-08 
01:20:11.000000000 +0100
+++ new/micropython-lib-1.28.0/python-stdlib/string/manifest.py 2026-03-23 
01:17:33.000000000 +0100
@@ -1,3 +1,3 @@
-metadata(version="0.1.1")
+metadata(version="0.2.0")
 
-module("string.py")
+package("string")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/micropython-lib-1.27.0/python-stdlib/string/string/__init__.py 
new/micropython-lib-1.28.0/python-stdlib/string/string/__init__.py
--- old/micropython-lib-1.27.0/python-stdlib/string/string/__init__.py  
1970-01-01 01:00:00.000000000 +0100
+++ new/micropython-lib-1.28.0/python-stdlib/string/string/__init__.py  
2026-03-23 01:17:33.000000000 +0100
@@ -0,0 +1,27 @@
+# Some strings for ctype-style character classification
+whitespace = " \t\n\r\v\f"
+ascii_lowercase = "abcdefghijklmnopqrstuvwxyz"
+ascii_uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ascii_letters = ascii_lowercase + ascii_uppercase
+digits = "0123456789"
+hexdigits = digits + "abcdef" + "ABCDEF"
+octdigits = "01234567"
+punctuation = """!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~"""
+printable = digits + ascii_letters + punctuation + whitespace
+
+
+def translate(s, map):
+    import io
+
+    sb = io.StringIO()
+    for c in s:
+        v = ord(c)
+        if v in map:
+            v = map[v]
+            if isinstance(v, int):
+                sb.write(chr(v))
+            elif v is not None:
+                sb.write(v)
+        else:
+            sb.write(c)
+    return sb.getvalue()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/micropython-lib-1.27.0/python-stdlib/string/string/templatelib.py 
new/micropython-lib-1.28.0/python-stdlib/string/string/templatelib.py
--- old/micropython-lib-1.27.0/python-stdlib/string/string/templatelib.py       
1970-01-01 01:00:00.000000000 +0100
+++ new/micropython-lib-1.28.0/python-stdlib/string/string/templatelib.py       
2026-03-23 01:17:33.000000000 +0100
@@ -0,0 +1,5 @@
+# Import built-in t-string classes if they exist.
+try:
+    from ustring.templatelib import *
+except:
+    pass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/micropython-lib-1.27.0/python-stdlib/string/string.py 
new/micropython-lib-1.28.0/python-stdlib/string/string.py
--- old/micropython-lib-1.27.0/python-stdlib/string/string.py   2025-12-08 
01:20:11.000000000 +0100
+++ new/micropython-lib-1.28.0/python-stdlib/string/string.py   1970-01-01 
01:00:00.000000000 +0100
@@ -1,27 +0,0 @@
-# Some strings for ctype-style character classification
-whitespace = " \t\n\r\v\f"
-ascii_lowercase = "abcdefghijklmnopqrstuvwxyz"
-ascii_uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-ascii_letters = ascii_lowercase + ascii_uppercase
-digits = "0123456789"
-hexdigits = digits + "abcdef" + "ABCDEF"
-octdigits = "01234567"
-punctuation = """!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~"""
-printable = digits + ascii_letters + punctuation + whitespace
-
-
-def translate(s, map):
-    import io
-
-    sb = io.StringIO()
-    for c in s:
-        v = ord(c)
-        if v in map:
-            v = map[v]
-            if isinstance(v, int):
-                sb.write(chr(v))
-            elif v is not None:
-                sb.write(v)
-        else:
-            sb.write(c)
-    return sb.getvalue()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/micropython-lib-1.27.0/unix-ffi/_libc/_libc.py 
new/micropython-lib-1.28.0/unix-ffi/_libc/_libc.py
--- old/micropython-lib-1.27.0/unix-ffi/_libc/_libc.py  2025-12-08 
01:20:11.000000000 +0100
+++ new/micropython-lib-1.28.0/unix-ffi/_libc/_libc.py  2026-03-23 
01:17:33.000000000 +0100
@@ -4,7 +4,7 @@
 
 _h = None
 
-names = ("libc.so", "libc.so.0", "libc.so.6", "libc.dylib")
+names = ("libc.so", "libc.so.0", "libc.so.6", "libc.so.7", "libc.dylib")
 
 
 def get():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/micropython-lib-1.27.0/unix-ffi/_libc/manifest.py 
new/micropython-lib-1.28.0/unix-ffi/_libc/manifest.py
--- old/micropython-lib-1.27.0/unix-ffi/_libc/manifest.py       2025-12-08 
01:20:11.000000000 +0100
+++ new/micropython-lib-1.28.0/unix-ffi/_libc/manifest.py       2026-03-23 
01:17:33.000000000 +0100
@@ -1,6 +1,6 @@
 metadata(
     description="MicroPython FFI helper module (deprecated, replaced by 
micropython-ffilib).",
-    version="0.3.1",
+    version="0.4.0",
 )
 
 # Originally written by Paul Sokolovsky.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/micropython-lib-1.27.0/unix-ffi/machine/machine/__init__.py 
new/micropython-lib-1.28.0/unix-ffi/machine/machine/__init__.py
--- old/micropython-lib-1.27.0/unix-ffi/machine/machine/__init__.py     
2025-12-08 01:20:11.000000000 +0100
+++ new/micropython-lib-1.28.0/unix-ffi/machine/machine/__init__.py     
2026-03-23 01:17:33.000000000 +0100
@@ -4,4 +4,13 @@
 
 
 def unique_id():
+    for base in ("/etc", "/var/lib/dbus"):
+        try:
+            with open(base + "/machine-id", "rb") as source:
+                data = source.read(32)
+                if len(data) == 32:
+                    # unhexlify might not be available
+                    return bytes([int(data[i : i + 2], 16) for i in range(0, 
32, 2)])
+        except OSError as e:
+            pass
     return b"upy-non-unique"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/micropython-lib-1.27.0/unix-ffi/machine/manifest.py 
new/micropython-lib-1.28.0/unix-ffi/machine/manifest.py
--- old/micropython-lib-1.27.0/unix-ffi/machine/manifest.py     2025-12-08 
01:20:11.000000000 +0100
+++ new/micropython-lib-1.28.0/unix-ffi/machine/manifest.py     2026-03-23 
01:17:33.000000000 +0100
@@ -1,4 +1,4 @@
-metadata(version="0.2.2")
+metadata(version="0.2.3")
 
 # Originally written by Paul Sokolovsky.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/micropython-lib-1.27.0/unix-ffi/re/manifest.py 
new/micropython-lib-1.28.0/unix-ffi/re/manifest.py
--- old/micropython-lib-1.27.0/unix-ffi/re/manifest.py  2025-12-08 
01:20:11.000000000 +0100
+++ new/micropython-lib-1.28.0/unix-ffi/re/manifest.py  2026-03-23 
01:17:33.000000000 +0100
@@ -1,4 +1,4 @@
-metadata(version="0.2.5")
+metadata(version="0.2.6")
 
 # Originally written by Paul Sokolovsky.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/micropython-lib-1.27.0/unix-ffi/re/re.py 
new/micropython-lib-1.28.0/unix-ffi/re/re.py
--- old/micropython-lib-1.27.0/unix-ffi/re/re.py        2025-12-08 
01:20:11.000000000 +0100
+++ new/micropython-lib-1.28.0/unix-ffi/re/re.py        2026-03-23 
01:17:33.000000000 +0100
@@ -38,6 +38,10 @@
 # to -1
 PCRE2_ZERO_TERMINATED = -1
 
+# PCRE2_UNSET is used for offsets of groups that didn't participate in a match
+# It's SIZE_MAX: 0xFFFFFFFF for 32bit, 0xFFFFFFFFFFFFFFFF for 64bit
+PCRE2_UNSET = (1 << (PCRE2_SIZE_SIZE * 8)) - 1
+
 
 IGNORECASE = I = 0x8
 MULTILINE = M = 0x400
@@ -62,12 +66,11 @@
         if not n:
             return self.s[self.offsets[0] : self.offsets[1]]
         if len(n) == 1:
-            return self.s[self.offsets[n[0] * 2] : self.offsets[n[0] * 2 + 1]]
-        return tuple(self.s[self.offsets[i * 2] : self.offsets[i * 2 + 1]] for 
i in n)
+            return None if self.offsets[n[0] * 2] == PCRE2_UNSET else 
self.s[self.offsets[n[0] * 2] : self.offsets[n[0] * 2 + 1]]
+        return tuple(None if self.offsets[i * 2] == PCRE2_UNSET else 
self.s[self.offsets[i * 2] : self.offsets[i * 2 + 1]] for i in n)
 
     def groups(self, default=None):
-        assert default is None
-        return tuple(self.group(i + 1) for i in range(self.num - 1))
+        return tuple(default if self.offsets[(i + 1) * 2] == PCRE2_UNSET else 
self.group(i + 1) for i in range(self.num - 1))
 
     def start(self, n=0):
         return self.offsets[n * 2]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/micropython-lib-1.27.0/unix-ffi/re/test_re.py 
new/micropython-lib-1.28.0/unix-ffi/re/test_re.py
--- old/micropython-lib-1.27.0/unix-ffi/re/test_re.py   2025-12-08 
01:20:11.000000000 +0100
+++ new/micropython-lib-1.28.0/unix-ffi/re/test_re.py   2026-03-23 
01:17:33.000000000 +0100
@@ -60,3 +60,9 @@
 text = "  \thello there\n  \t  how are you?"
 indents = _leading_whitespace_re.findall(text)
 assert indents == ["  \t", "  \t  "]
+
+m = re.match(r"(.)?", "")
+assert m.group() == ""
+assert m.group(0, 1) == ("", None)
+assert m.groups() == (None,)
+assert m.groups("default") == ("default",)

Reply via email to