diff --git a/.gitattributes b/.gitattributes
index 2d8496db504..fbab4e69abe 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -14,10 +14,12 @@
*.dxf binary
*.mpy binary
*.der binary
+*.bin binary
# These should also not be modified by git.
tests/basics/string_cr_conversion.py -text
tests/basics/string_crlf_conversion.py -text
+tests/micropython/test_normalize_newlines.py.exp -text
ports/stm32/pybcdc.inf_template -text
ports/stm32/usbhost/** -text
ports/cc3200/hal/aes.c -text
diff --git a/.github/actions/setup_esp32/action.yml b/.github/actions/setup_esp32/action.yml
new file mode 100644
index 00000000000..42c44cf76ce
--- /dev/null
+++ b/.github/actions/setup_esp32/action.yml
@@ -0,0 +1,47 @@
+name: Setup ESP-IDF for CI
+description: Install ESP-IDF
+inputs:
+ idf_ver:
+ required: true
+ type: string
+ ccache_key:
+ required: true
+ type: string
+
+runs:
+ using: "composite"
+
+ steps:
+ - id: python_ver
+ name: Read the Python version
+ run: echo PYTHON_VER=py$(python --version | cut -d' ' -f2) | tee "${GITHUB_OUTPUT}"
+ shell: bash
+
+ - name: Cached ESP-IDF install
+ id: cache_esp_idf
+ uses: actions/cache@v5
+ with:
+ path: |
+ ./esp-idf/
+ ~/.espressif/
+ !~/.espressif/dist/
+ ~/.cache/pip/
+ # Cache is keyed on both IDF version (from the job) and Python version (from the runner)
+ key: esp-idf-${{ inputs.idf_ver }}-${{ steps.python_ver.outputs.PYTHON_VER }}
+
+ - name: Install ESP-IDF packages
+ if: steps.cache_esp_idf.outputs.cache-hit != 'true'
+ env:
+ IDF_VER: ${{ inputs.idf_ver }}
+ run: tools/ci.sh esp32_idf_setup
+ shell: bash
+
+ - name: ccache
+ uses: hendrikmuhs/ccache-action@v1.2
+ with:
+ key: esp32-${{ inputs.idf_ver }}-${{ inputs.ccache_key }}
+
+ - name: Enable CCache for ESP-IDF
+ run: echo "IDF_CCACHE_ENABLE=1" >> ${GITHUB_ENV}
+ shell: bash
+
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index e11cebddb37..8be63024039 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -3,7 +3,6 @@
others can review your Pull Request.
Before submitting, please read:
- https://github.com/micropython/micropython/blob/master/CODEOFCONDUCT.md
https://github.com/micropython/micropython/wiki/ContributorGuidelines
Please check any CI failures that appear after your Pull Request is opened.
@@ -12,16 +11,15 @@
### Summary
-
+ solve, or what improvement does it add? Add links if relevant,
+ especially links to open issues. -->
### Testing
-
+ If you leave this section empty then your Pull Request may be closed. -->
### Trade-offs and Alternatives
@@ -31,3 +29,20 @@
Delete this heading if not relevant (i.e. small fixes) -->
+
+### Generative AI
+
+
+
+I did not use generative AI tools when creating this PR.
+
+I used generative AI tools when creating this PR, but a human has checked the
+code and is responsible for the code and the description above.
+
+
diff --git a/.github/workflows/biome.yml b/.github/workflows/biome.yml
index 88744f16ca7..0cde10acc91 100644
--- a/.github/workflows/biome.yml
+++ b/.github/workflows/biome.yml
@@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
- name: Setup Biome
uses: biomejs/setup-biome@v2
with:
diff --git a/.github/workflows/code_formatting.yml b/.github/workflows/code_formatting.yml
index 9f30f048cfd..95653d941f9 100644
--- a/.github/workflows/code_formatting.yml
+++ b/.github/workflows/code_formatting.yml
@@ -10,11 +10,11 @@ jobs:
code-formatting:
runs-on: ubuntu-22.04
steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-python@v5
+ - uses: actions/checkout@v6
+ - uses: actions/setup-python@v6
- name: Install packages
- run: source tools/ci.sh && ci_c_code_formatting_setup
+ run: tools/ci.sh c_code_formatting_setup
- name: Run code formatting
- run: source tools/ci.sh && ci_c_code_formatting_run
+ run: tools/ci.sh c_code_formatting_run
- name: Check code formatting
run: git diff --exit-code
diff --git a/.github/workflows/code_size.yml b/.github/workflows/code_size.yml
index 163d4455cff..f3238a85d9a 100644
--- a/.github/workflows/code_size.yml
+++ b/.github/workflows/code_size.yml
@@ -1,7 +1,6 @@
name: Check code size
on:
- push:
pull_request:
paths:
- '.github/workflows/*.yml'
@@ -11,6 +10,7 @@ on:
- 'shared/**'
- 'lib/**'
- 'ports/bare-arm/**'
+ - 'ports/esp32/**'
- 'ports/mimxrt/**'
- 'ports/minimal/**'
- 'ports/rp2/**'
@@ -24,17 +24,30 @@ concurrency:
jobs:
build:
- runs-on: ubuntu-22.04
+ runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
with:
fetch-depth: 100
- name: Install packages
- run: source tools/ci.sh && ci_code_size_setup
+ run: tools/ci.sh code_size_setup
+
+ - name: Find IDF_NEWEST_VER
+ id: idf_ver
+ run: |
+ echo "IDF_VER="$(yq .env.IDF_NEWEST_VER < .github/workflows/ports_esp32.yml) \
+ | tee "${GITHUB_OUTPUT}"
+
+ - name: Setup ESP-IDF
+ uses: ./.github/actions/setup_esp32
+ with:
+ idf_ver: ${{ steps.idf_ver.outputs.IDF_VER }}
+ ccache_key: code_size
+
- name: Build
- run: source tools/ci.sh && ci_code_size_build
+ run: tools/ci.sh code_size_build
- name: Compute code size difference
- run: tools/metrics.py diff ~/size0 ~/size1 | tee diff
+ run: source tools/ci.sh && ci_code_size_report
- name: Save PR number
if: github.event_name == 'pull_request'
env:
@@ -42,7 +55,7 @@ jobs:
run: echo $PR_NUMBER > pr_number
- name: Upload diff
if: github.event_name == 'pull_request'
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
with:
name: code-size-report
path: |
diff --git a/.github/workflows/code_size_comment.yml b/.github/workflows/code_size_comment.yml
index 521afad709d..2eed0b06b8e 100644
--- a/.github/workflows/code_size_comment.yml
+++ b/.github/workflows/code_size_comment.yml
@@ -15,7 +15,7 @@ jobs:
steps:
- name: 'Download artifact'
id: download-artifact
- uses: actions/github-script@v7
+ uses: actions/github-script@v8
with:
result-encoding: string
script: |
@@ -56,7 +56,7 @@ jobs:
run: unzip code-size-report.zip
- name: Post comment to pull request
if: steps.download-artifact.outputs.result == 'ok'
- uses: actions/github-script@v7
+ uses: actions/github-script@v8
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml
index 2d8b4627aac..e3a9c79bd5e 100644
--- a/.github/workflows/codespell.yml
+++ b/.github/workflows/codespell.yml
@@ -6,8 +6,13 @@ jobs:
codespell:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
# codespell version should be kept in sync with .pre-commit-config.yml
- - run: pip install --user codespell==2.2.6 tomli
+ - run: pip install --user codespell==2.4.1 tomli
- run: codespell
-
+ # additionally check for misspelling of "MicroPython"
+ - run: |
+ if git grep -n Micropython -- ":(exclude).github/workflows/codespell.yml"; then
+ echo "Please correct capitalisation of MicroPython on the above lines"
+ exit 1
+ fi
diff --git a/.github/workflows/commit_formatting.yml b/.github/workflows/commit_formatting.yml
index 3fdcabc4ca7..6abc3612a00 100644
--- a/.github/workflows/commit_formatting.yml
+++ b/.github/workflows/commit_formatting.yml
@@ -1,6 +1,6 @@
name: Check commit message formatting
-on: [push, pull_request]
+on: [pull_request]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@@ -10,9 +10,9 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
with:
- fetch-depth: '100'
- - uses: actions/setup-python@v5
+ fetch-depth: 100
+ - uses: actions/setup-python@v6
- name: Check commit message formatting
- run: source tools/ci.sh && ci_commit_formatting_run
+ run: tools/ci.sh commit_formatting_run
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index d01a4b50c98..79755b74197 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -5,6 +5,8 @@ on:
pull_request:
paths:
- docs/**
+ - py/**
+ - tests/cpydiff/**
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@@ -15,9 +17,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-python@v5
+ - uses: actions/checkout@v6
+ - uses: actions/setup-python@v6
- name: Install Python packages
run: pip install -r docs/requirements.txt
+ - name: Build unix port
+ run: tools/ci.sh unix_build_helper
- name: Build docs
run: make -C docs/ html
diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml
index 6613f106625..4627247fb9f 100644
--- a/.github/workflows/examples.yml
+++ b/.github/workflows/examples.yml
@@ -18,8 +18,6 @@ jobs:
embedding:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Build
- run: make -C examples/embedding -f micropython_embed.mk && make -C examples/embedding
- - name: Run
- run: ./examples/embedding/embed | grep "hello world"
+ run: tools/ci.sh embedding_build
diff --git a/.github/workflows/mpremote.yml b/.github/workflows/mpremote.yml
index ee91b6360b9..ad5dd454905 100644
--- a/.github/workflows/mpremote.yml
+++ b/.github/workflows/mpremote.yml
@@ -11,18 +11,28 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
with:
# Setting this to zero means fetch all history and tags,
# which hatch-vcs can use to discover the version tag.
fetch-depth: 0
- - uses: actions/setup-python@v5
+ - uses: actions/setup-python@v6
- name: Install build tools
run: pip install build
- name: Build mpremote wheel
- run: cd tools/mpremote && python -m build --wheel
+ run: |
+ if ! git rev-parse --verify -q v1.23.0 >/dev/null; then
+ echo "::error::mpremote wheel build requires recent MicroPython version tags in the forked repo."
+ echo ""
+ echo "To fix, push tags from upstream:"
+ echo " git remote add upstream https://github.com/micropython/micropython.git"
+ echo " git fetch upstream --tags"
+ echo " git push origin --tags"
+ exit 1
+ fi
+ cd tools/mpremote && python -m build --wheel
- name: Archive mpremote wheel
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
with:
name: mpremote
path: |
diff --git a/.github/workflows/mpy_format.yml b/.github/workflows/mpy_format.yml
index baa02ce08d5..ab668c1cb5e 100644
--- a/.github/workflows/mpy_format.yml
+++ b/.github/workflows/mpy_format.yml
@@ -6,6 +6,8 @@ on:
paths:
- '.github/workflows/*.yml'
- 'examples/**'
+ - 'mpy-cross/**'
+ - 'py/**'
- 'tests/**'
- 'tools/**'
@@ -15,10 +17,12 @@ concurrency:
jobs:
test:
- runs-on: ubuntu-20.04 # use 20.04 to get python2
+ runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Install packages
- run: source tools/ci.sh && ci_mpy_format_setup
+ run: tools/ci.sh mpy_format_setup
- name: Test mpy-tool.py
- run: source tools/ci.sh && ci_mpy_format_test
+ run: tools/ci.sh mpy_format_test
+ - name: Test mpy-cross debug emitter
+ run: tools/ci.sh mpy_cross_debug_emitter
diff --git a/.github/workflows/ports.yml b/.github/workflows/ports.yml
index 1f262b0ba4b..5e71d4d076a 100644
--- a/.github/workflows/ports.yml
+++ b/.github/workflows/ports.yml
@@ -17,6 +17,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Build ports download metadata
run: mkdir boards && ./tools/autobuild/build-downloads.py . ./boards
diff --git a/.github/workflows/ports_alif.yml b/.github/workflows/ports_alif.yml
new file mode 100644
index 00000000000..6fb225937a9
--- /dev/null
+++ b/.github/workflows/ports_alif.yml
@@ -0,0 +1,33 @@
+name: alif port
+
+on:
+ push:
+ pull_request:
+ paths:
+ - '.github/workflows/*.yml'
+ - 'tools/**'
+ - 'py/**'
+ - 'extmod/**'
+ - 'shared/**'
+ - 'lib/**'
+ - 'drivers/**'
+ - 'ports/alif/**'
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ build_alif:
+ strategy:
+ fail-fast: false
+ matrix:
+ ci_func: # names are functions in ci.sh
+ - alif_ae3_build
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v6
+ - name: Install packages
+ run: tools/ci.sh alif_setup
+ - name: Build ci_${{matrix.ci_func }}
+ run: tools/ci.sh ${{ matrix.ci_func }}
diff --git a/.github/workflows/ports_cc3200.yml b/.github/workflows/ports_cc3200.yml
index f178a140587..194483ec218 100644
--- a/.github/workflows/ports_cc3200.yml
+++ b/.github/workflows/ports_cc3200.yml
@@ -21,8 +21,8 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Install packages
- run: source tools/ci.sh && ci_cc3200_setup
+ run: tools/ci.sh cc3200_setup
- name: Build
- run: source tools/ci.sh && ci_cc3200_build
+ run: tools/ci.sh cc3200_build
diff --git a/.github/workflows/ports_esp32.yml b/.github/workflows/ports_esp32.yml
index 45808b659ad..56dce3b69d9 100644
--- a/.github/workflows/ports_esp32.yml
+++ b/.github/workflows/ports_esp32.yml
@@ -17,41 +17,47 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
+env:
+ # Oldest and newest supported ESP-IDF versions, should match ports/esp32/README.md
+ IDF_OLDEST_VER: &oldest "v5.3"
+ IDF_NEWEST_VER: &newest "v5.5.1"
+
jobs:
build_idf:
strategy:
fail-fast: false
matrix:
+ idf_ver:
+ - *oldest
+ - *newest
ci_func: # names are functions in ci.sh
- esp32_build_cmod_spiram_s2
- esp32_build_s3_c3
- runs-on: ubuntu-20.04
+ - esp32_build_c2_c5_c6
+ - esp32_build_p4
+ exclude:
+ # Exclude some jobs on the oldest IDF version, to save resources
+ - idf_ver: *oldest
+ ci_func: esp32_build_c2_c5_c6
+ - idf_ver: *oldest
+ ci_func: esp32_build_p4
+ runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- - id: idf_ver
- name: Read the ESP-IDF version
- run: source tools/ci.sh && echo "IDF_VER=$IDF_VER" | tee "$GITHUB_OUTPUT"
+ # Only the newest IDF version will build the ESP-IDF lockfiles correctly,
+ # so we need to disable MICROPY_MAINTAINER_BUILD on older versions.
+ - name: Disable extra checks for older ESP-IDF
+ id: check_newest_ver
+ if: ${{ matrix.idf_ver != env.IDF_NEWEST_VER }}
+ run: echo "MICROPY_MAINTAINER_BUILD=0" >> ${GITHUB_ENV}
- - name: Cached ESP-IDF install
- id: cache_esp_idf
- uses: actions/cache@v4
- with:
- path: |
- ./esp-idf/
- ~/.espressif/
- !~/.espressif/dist/
- ~/.cache/pip/
- key: esp-idf-${{ steps.idf_ver.outputs.IDF_VER }}
-
- - name: Install ESP-IDF packages
- if: steps.cache_esp_idf.outputs.cache-hit != 'true'
- run: source tools/ci.sh && ci_esp32_idf_setup
-
- - name: ccache
- uses: hendrikmuhs/ccache-action@v1.2
+ - name: Setup ESP-IDF
+ uses: ./.github/actions/setup_esp32
with:
- key: esp32-${{ matrix.ci_func }}
+ idf_ver: ${{ matrix.idf_ver }}
+ ccache_key: ${{ matrix.ci_func }}
+
- - name: Build ci_${{matrix.ci_func }}
- run: source tools/ci.sh && ci_${{ matrix.ci_func }}
+ - name: Build ci_${{matrix.ci_func }} on ESP-IDF ${{ matrix.idf_ver }}
+ run: tools/ci.sh ${{ matrix.ci_func }}
diff --git a/.github/workflows/ports_esp8266.yml b/.github/workflows/ports_esp8266.yml
index 5236edf40b9..eb7f59cdc49 100644
--- a/.github/workflows/ports_esp8266.yml
+++ b/.github/workflows/ports_esp8266.yml
@@ -21,8 +21,8 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Install packages
- run: source tools/ci.sh && ci_esp8266_setup && ci_esp8266_path >> $GITHUB_PATH
+ run: tools/ci.sh esp8266_setup && tools/ci.sh esp8266_path >> $GITHUB_PATH
- name: Build
- run: source tools/ci.sh && ci_esp8266_build
+ run: tools/ci.sh esp8266_build
diff --git a/.github/workflows/ports_mimxrt.yml b/.github/workflows/ports_mimxrt.yml
index 9e782bf63b3..fd80f3f6329 100644
--- a/.github/workflows/ports_mimxrt.yml
+++ b/.github/workflows/ports_mimxrt.yml
@@ -19,15 +19,15 @@ concurrency:
jobs:
build:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
defaults:
run:
working-directory: 'micropython repo' # test build with space in path
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
with:
path: 'micropython repo'
- name: Install packages
- run: source tools/ci.sh && ci_mimxrt_setup
+ run: tools/ci.sh mimxrt_setup
- name: Build
- run: source tools/ci.sh && ci_mimxrt_build
+ run: tools/ci.sh mimxrt_build
diff --git a/.github/workflows/ports_nrf.yml b/.github/workflows/ports_nrf.yml
index d9cffb9778c..bec9a5dfb5b 100644
--- a/.github/workflows/ports_nrf.yml
+++ b/.github/workflows/ports_nrf.yml
@@ -19,10 +19,10 @@ concurrency:
jobs:
build:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Install packages
- run: source tools/ci.sh && ci_nrf_setup
+ run: tools/ci.sh nrf_setup
- name: Build
- run: source tools/ci.sh && ci_nrf_build
+ run: tools/ci.sh nrf_build
diff --git a/.github/workflows/ports_powerpc.yml b/.github/workflows/ports_powerpc.yml
index c41b13e5ddf..a883d026806 100644
--- a/.github/workflows/ports_powerpc.yml
+++ b/.github/workflows/ports_powerpc.yml
@@ -21,8 +21,8 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Install packages
- run: source tools/ci.sh && ci_powerpc_setup
+ run: tools/ci.sh powerpc_setup
- name: Build
- run: source tools/ci.sh && ci_powerpc_build
+ run: tools/ci.sh powerpc_build
diff --git a/.github/workflows/ports_qemu.yml b/.github/workflows/ports_qemu.yml
index 57192c43936..0ed95dbe5f9 100644
--- a/.github/workflows/ports_qemu.yml
+++ b/.github/workflows/ports_qemu.yml
@@ -20,13 +20,21 @@ concurrency:
jobs:
build_and_test_arm:
+ strategy:
+ fail-fast: false
+ matrix:
+ ci_func: # names are functions in ci.sh
+ - bigendian
+ - sabrelite
+ - thumb_softfp
+ - thumb_hardfp
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Install packages
- run: source tools/ci.sh && ci_qemu_setup_arm
- - name: Build and run test suite
- run: source tools/ci.sh && ci_qemu_build_arm
+ run: tools/ci.sh qemu_setup_arm
+ - name: Build and run test suite ci_qemu_build_arm_${{ matrix.ci_func }}
+ run: tools/ci.sh qemu_build_arm_${{ matrix.ci_func }}
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
@@ -34,11 +42,23 @@ jobs:
build_and_test_rv32:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
+ - name: Install packages
+ run: tools/ci.sh qemu_setup_rv32
+ - name: Build and run test suite
+ run: tools/ci.sh qemu_build_rv32
+ - name: Print failures
+ if: failure()
+ run: tests/run-tests.py --print-failures
+
+ build_and_test_rv64:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v6
- name: Install packages
- run: source tools/ci.sh && ci_qemu_setup_rv32
+ run: tools/ci.sh qemu_setup_rv64
- name: Build and run test suite
- run: source tools/ci.sh && ci_qemu_build_rv32
+ run: tools/ci.sh qemu_build_rv64
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
diff --git a/.github/workflows/ports_renesas-ra.yml b/.github/workflows/ports_renesas-ra.yml
index b1a30c2f117..920691eca70 100644
--- a/.github/workflows/ports_renesas-ra.yml
+++ b/.github/workflows/ports_renesas-ra.yml
@@ -19,11 +19,11 @@ concurrency:
jobs:
build_renesas_ra_board:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Install packages
- run: source tools/ci.sh && ci_renesas_ra_setup
+ run: tools/ci.sh renesas_ra_setup
- name: Build
- run: source tools/ci.sh && ci_renesas_ra_board_build
+ run: tools/ci.sh renesas_ra_board_build
diff --git a/.github/workflows/ports_rp2.yml b/.github/workflows/ports_rp2.yml
index 748f38e1438..ea19e2da7ff 100644
--- a/.github/workflows/ports_rp2.yml
+++ b/.github/workflows/ports_rp2.yml
@@ -24,10 +24,10 @@ jobs:
run:
working-directory: 'micropython repo' # test build with space in path
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
with:
path: 'micropython repo'
- name: Install packages
- run: source tools/ci.sh && ci_rp2_setup
+ run: tools/ci.sh rp2_setup
- name: Build
- run: source tools/ci.sh && ci_rp2_build
+ run: tools/ci.sh rp2_build
diff --git a/.github/workflows/ports_samd.yml b/.github/workflows/ports_samd.yml
index 5bf1826cd17..eb806ceb044 100644
--- a/.github/workflows/ports_samd.yml
+++ b/.github/workflows/ports_samd.yml
@@ -21,8 +21,8 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Install packages
- run: source tools/ci.sh && ci_samd_setup
+ run: tools/ci.sh samd_setup
- name: Build
- run: source tools/ci.sh && ci_samd_build
+ run: tools/ci.sh samd_build
diff --git a/.github/workflows/ports_stm32.yml b/.github/workflows/ports_stm32.yml
index f5e01dc1f62..2ed730eb4e8 100644
--- a/.github/workflows/ports_stm32.yml
+++ b/.github/workflows/ports_stm32.yml
@@ -26,11 +26,11 @@ jobs:
- stm32_pyb_build
- stm32_nucleo_build
- stm32_misc_build
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-22.04
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Install packages
- run: source tools/ci.sh && ci_stm32_setup
+ run: tools/ci.sh stm32_setup && tools/ci.sh stm32_path >> $GITHUB_PATH
- name: Build ci_${{matrix.ci_func }}
- run: source tools/ci.sh && ci_${{ matrix.ci_func }}
+ run: tools/ci.sh ${{ matrix.ci_func }}
diff --git a/.github/workflows/ports_unix.yml b/.github/workflows/ports_unix.yml
index 1707fdc9fb3..57f4a964b2f 100644
--- a/.github/workflows/ports_unix.yml
+++ b/.github/workflows/ports_unix.yml
@@ -23,11 +23,11 @@ jobs:
minimal:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Build
- run: source tools/ci.sh && ci_unix_minimal_build
+ run: tools/ci.sh unix_minimal_build
- name: Run main test suite
- run: source tools/ci.sh && ci_unix_minimal_run_tests
+ run: tools/ci.sh unix_minimal_run_tests
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
@@ -35,9 +35,9 @@ jobs:
reproducible:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Build with reproducible date
- run: source tools/ci.sh && ci_unix_minimal_build
+ run: tools/ci.sh unix_minimal_build
env:
SOURCE_DATE_EPOCH: 1234567890
- name: Check reproducible build date
@@ -46,11 +46,11 @@ jobs:
standard:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Build
- run: source tools/ci.sh && ci_unix_standard_build
+ run: tools/ci.sh unix_standard_build
- name: Run main test suite
- run: source tools/ci.sh && ci_unix_standard_run_tests
+ run: tools/ci.sh unix_standard_run_tests
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
@@ -58,11 +58,11 @@ jobs:
standard_v2:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Build
- run: source tools/ci.sh && ci_unix_standard_v2_build
+ run: tools/ci.sh unix_standard_v2_build
- name: Run main test suite
- run: source tools/ci.sh && ci_unix_standard_v2_run_tests
+ run: tools/ci.sh unix_standard_v2_run_tests
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
@@ -70,61 +70,99 @@ jobs:
coverage:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
+ - uses: actions/setup-python@v6
+ # Python 3.12 is the default for ubuntu-24.04, but that has compatibility issues with settrace tests.
+ # Can remove this step when ubuntu-latest uses a more recent Python 3.x as the default.
+ with:
+ python-version: '3.11'
- name: Install packages
- run: source tools/ci.sh && ci_unix_coverage_setup
+ run: tools/ci.sh unix_coverage_setup
- name: Build
- run: source tools/ci.sh && ci_unix_coverage_build
+ run: tools/ci.sh unix_coverage_build
- name: Run main test suite
- run: source tools/ci.sh && ci_unix_coverage_run_tests
+ run: tools/ci.sh unix_coverage_run_tests
- name: Test merging .mpy files
- run: source tools/ci.sh && ci_unix_coverage_run_mpy_merge_tests
+ run: tools/ci.sh unix_coverage_run_mpy_merge_tests
- name: Build native mpy modules
- run: source tools/ci.sh && ci_native_mpy_modules_build
+ run: tools/ci.sh native_mpy_modules_build
- name: Test importing .mpy generated by mpy_ld.py
- run: source tools/ci.sh && ci_unix_coverage_run_native_mpy_tests
+ run: tools/ci.sh unix_coverage_run_native_mpy_tests
- name: Run gcov coverage analysis
run: |
(cd ports/unix && gcov -o build-coverage/py ../../py/*.c || true)
(cd ports/unix && gcov -o build-coverage/extmod ../../extmod/*.c || true)
- name: Upload coverage to Codecov
- uses: codecov/codecov-action@v4
+ uses: codecov/codecov-action@v6
with:
- fail_ci_if_error: true
+ # Only fail the job on error if a token is set, or we're running against upstream repo.
+ # This avoids the annoying situation of the job failing on every push to a fork (if no token is set).
+ fail_ci_if_error: ${{ secrets.CODECOV_TOKEN != '' || github.repository_owner == 'micropython' }}
verbose: true
+ # note: when a fork opens a PR into MicroPython repo, the pull_request trigger can't access
+ # secrets so this token value will be empty (codecov will do a 'tokenless' upload).
token: ${{ secrets.CODECOV_TOKEN }}
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
coverage_32bit:
- runs-on: ubuntu-20.04 # use 20.04 to get libffi-dev:i386
+ runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
+ - uses: actions/setup-python@v6
+ # Python 3.12 is the default for ubuntu-24.04, but that has compatibility issues with settrace tests.
+ # Can remove this step when ubuntu-latest uses a more recent Python 3.x as the default.
+ with:
+ python-version: '3.11'
- name: Install packages
- run: source tools/ci.sh && ci_unix_32bit_setup
+ run: tools/ci.sh unix_32bit_setup
- name: Build
- run: source tools/ci.sh && ci_unix_coverage_32bit_build
+ run: tools/ci.sh unix_coverage_32bit_build
- name: Run main test suite
- run: source tools/ci.sh && ci_unix_coverage_32bit_run_tests
+ run: tools/ci.sh unix_coverage_32bit_run_tests
- name: Build native mpy modules
- run: source tools/ci.sh && ci_native_mpy_modules_32bit_build
+ run: tools/ci.sh native_mpy_modules_32bit_build
- name: Test importing .mpy generated by mpy_ld.py
- run: source tools/ci.sh && ci_unix_coverage_32bit_run_native_mpy_tests
+ run: tools/ci.sh unix_coverage_32bit_run_native_mpy_tests
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
nanbox:
- runs-on: ubuntu-20.04 # use 20.04 to get python2, and libffi-dev:i386
+ runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
+ - uses: actions/setup-python@v6
+ # Python 3.12 is the default for ubuntu-24.04, but that has compatibility issues with settrace tests.
+ # Can remove this step when ubuntu-latest uses a more recent Python 3.x as the default.
+ with:
+ python-version: '3.11'
+ - name: Install packages
+ run: tools/ci.sh unix_32bit_setup
+ - name: Build
+ run: tools/ci.sh unix_nanbox_build
+ - name: Run main test suite
+ run: tools/ci.sh unix_nanbox_run_tests
+ - name: Print failures
+ if: failure()
+ run: tests/run-tests.py --print-failures
+
+ longlong:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v6
+ - uses: actions/setup-python@v6
+ # Python 3.12 is the default for ubuntu-24.04, but that has compatibility issues with settrace tests.
+ # Can remove this step when ubuntu-latest uses a more recent Python 3.x as the default.
+ with:
+ python-version: '3.11'
- name: Install packages
- run: source tools/ci.sh && ci_unix_32bit_setup
+ run: tools/ci.sh unix_32bit_setup
- name: Build
- run: source tools/ci.sh && ci_unix_nanbox_build
+ run: tools/ci.sh unix_longlong_build
- name: Run main test suite
- run: source tools/ci.sh && ci_unix_nanbox_run_tests
+ run: tools/ci.sh unix_longlong_run_tests
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
@@ -132,78 +170,102 @@ jobs:
float:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Build
- run: source tools/ci.sh && ci_unix_float_build
+ run: tools/ci.sh unix_float_build
- name: Run main test suite
- run: source tools/ci.sh && ci_unix_float_run_tests
+ run: tools/ci.sh unix_float_run_tests
+ - name: Print failures
+ if: failure()
+ run: tests/run-tests.py --print-failures
+
+ gil_enabled:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v6
+ - name: Build
+ run: tools/ci.sh unix_gil_enabled_build
+ - name: Run main test suite
+ run: tools/ci.sh unix_gil_enabled_run_tests
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
stackless_clang:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Install packages
- run: source tools/ci.sh && ci_unix_clang_setup
+ run: tools/ci.sh unix_clang_setup
- name: Build
- run: source tools/ci.sh && ci_unix_stackless_clang_build
+ run: tools/ci.sh unix_stackless_clang_build
- name: Run main test suite
- run: source tools/ci.sh && ci_unix_stackless_clang_run_tests
+ run: tools/ci.sh unix_stackless_clang_run_tests
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
float_clang:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Install packages
- run: source tools/ci.sh && ci_unix_clang_setup
+ run: tools/ci.sh unix_clang_setup
- name: Build
- run: source tools/ci.sh && ci_unix_float_clang_build
+ run: tools/ci.sh unix_float_clang_build
- name: Run main test suite
- run: source tools/ci.sh && ci_unix_float_clang_run_tests
+ run: tools/ci.sh unix_float_clang_run_tests
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
- settrace:
+ settrace_stackless:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
+ - uses: actions/setup-python@v6
+ # Python 3.12 is the default for ubuntu-24.04, but that has compatibility issues with settrace tests.
+ # Can remove this step when ubuntu-latest uses a more recent Python 3.x as the default.
+ with:
+ python-version: '3.11'
- name: Build
- run: source tools/ci.sh && ci_unix_settrace_build
+ run: tools/ci.sh unix_settrace_stackless_build
- name: Run main test suite
- run: source tools/ci.sh && ci_unix_settrace_run_tests
+ run: tools/ci.sh unix_settrace_stackless_run_tests
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
- settrace_stackless:
+ repr_b:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
+ - uses: actions/setup-python@v6
+ # Python 3.12 is the default for ubuntu-24.04, but that has compatibility issues with settrace tests.
+ # Can remove this step when ubuntu-latest uses a more recent Python 3.x as the default.
+ with:
+ python-version: '3.11'
+ - name: Install packages
+ run: tools/ci.sh unix_32bit_setup
- name: Build
- run: source tools/ci.sh && ci_unix_settrace_stackless_build
+ run: tools/ci.sh unix_repr_b_build
- name: Run main test suite
- run: source tools/ci.sh && ci_unix_settrace_stackless_run_tests
+ run: tools/ci.sh unix_repr_b_run_tests
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
macos:
- runs-on: macos-latest
+ runs-on: macos-26
steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-python@v5
+ - uses: actions/checkout@v6
+ - uses: actions/setup-python@v6
with:
python-version: '3.8'
- name: Build
- run: source tools/ci.sh && ci_unix_macos_build
+ run: tools/ci.sh unix_macos_build
- name: Run tests
- run: source tools/ci.sh && ci_unix_macos_run_tests
+ run: tools/ci.sh unix_macos_run_tests
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
@@ -211,13 +273,18 @@ jobs:
qemu_mips:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
+ - uses: actions/setup-python@v6
+ # Python 3.12 is the default for ubuntu-24.04, but that has compatibility issues with settrace tests.
+ # Can remove this step when ubuntu-latest uses a more recent Python 3.x as the default.
+ with:
+ python-version: '3.11'
- name: Install packages
- run: source tools/ci.sh && ci_unix_qemu_mips_setup
+ run: tools/ci.sh unix_qemu_mips_setup
- name: Build
- run: source tools/ci.sh && ci_unix_qemu_mips_build
+ run: tools/ci.sh unix_qemu_mips_build
- name: Run main test suite
- run: source tools/ci.sh && ci_unix_qemu_mips_run_tests
+ run: tools/ci.sh unix_qemu_mips_run_tests
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
@@ -225,13 +292,18 @@ jobs:
qemu_arm:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
+ - uses: actions/setup-python@v6
+ # Python 3.12 is the default for ubuntu-24.04, but that has compatibility issues with settrace tests.
+ # Can remove this step when ubuntu-latest uses a more recent Python 3.x as the default.
+ with:
+ python-version: '3.11'
- name: Install packages
- run: source tools/ci.sh && ci_unix_qemu_arm_setup
+ run: tools/ci.sh unix_qemu_arm_setup
- name: Build
- run: source tools/ci.sh && ci_unix_qemu_arm_build
+ run: tools/ci.sh unix_qemu_arm_build
- name: Run main test suite
- run: source tools/ci.sh && ci_unix_qemu_arm_run_tests
+ run: tools/ci.sh unix_qemu_arm_run_tests
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
@@ -239,13 +311,68 @@ jobs:
qemu_riscv64:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
+ - uses: actions/setup-python@v6
+ # Python 3.12 is the default for ubuntu-24.04, but that has compatibility issues with settrace tests.
+ # Can remove this step when ubuntu-latest uses a more recent Python 3.x as the default.
+ with:
+ python-version: '3.11'
- name: Install packages
- run: source tools/ci.sh && ci_unix_qemu_riscv64_setup
+ run: tools/ci.sh unix_qemu_riscv64_setup
- name: Build
- run: source tools/ci.sh && ci_unix_qemu_riscv64_build
+ run: tools/ci.sh unix_qemu_riscv64_build
- name: Run main test suite
- run: source tools/ci.sh && ci_unix_qemu_riscv64_run_tests
+ run: tools/ci.sh unix_qemu_riscv64_run_tests
+ - name: Print failures
+ if: failure()
+ run: tests/run-tests.py --print-failures
+
+ sanitize_address:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v6
+ - uses: actions/setup-python@v6
+ # Python 3.12 is the default for ubuntu-24.04, but that has compatibility issues with settrace tests.
+ # Can remove this step when ubuntu-latest uses a more recent Python 3.x as the default.
+ with:
+ python-version: '3.11'
+ - name: Install packages
+ run: tools/ci.sh unix_coverage_setup
+ - name: Build
+ run: tools/ci.sh unix_sanitize_address_build
+ - name: Run main test suite
+ run: tools/ci.sh unix_sanitize_address_run_tests
+ - name: Test merging .mpy files
+ run: tools/ci.sh unix_coverage_run_mpy_merge_tests
+ - name: Build native mpy modules
+ run: tools/ci.sh native_mpy_modules_build
+ - name: Test importing .mpy generated by mpy_ld.py
+ run: tools/ci.sh unix_coverage_run_native_mpy_tests
+ - name: Print failures
+ if: failure()
+ run: tests/run-tests.py --print-failures
+
+ sanitize_undefined:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v6
+ - uses: actions/setup-python@v6
+ # Python 3.12 is the default for ubuntu-24.04, but that has compatibility issues with settrace tests.
+ # Can remove this step when ubuntu-latest uses a more recent Python 3.x as the default.
+ with:
+ python-version: '3.11'
+ - name: Install packages
+ run: tools/ci.sh unix_coverage_setup
+ - name: Build
+ run: tools/ci.sh unix_sanitize_undefined_build
+ - name: Run main test suite
+ run: tools/ci.sh unix_sanitize_undefined_run_tests
+ - name: Test merging .mpy files
+ run: tools/ci.sh unix_coverage_run_mpy_merge_tests
+ - name: Build native mpy modules
+ run: tools/ci.sh native_mpy_modules_build
+ - name: Test importing .mpy generated by mpy_ld.py
+ run: tools/ci.sh unix_coverage_run_native_mpy_tests
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
diff --git a/.github/workflows/ports_webassembly.yml b/.github/workflows/ports_webassembly.yml
index 880f15ab344..f6619cc8976 100644
--- a/.github/workflows/ports_webassembly.yml
+++ b/.github/workflows/ports_webassembly.yml
@@ -11,6 +11,7 @@ on:
- 'shared/**'
- 'lib/**'
- 'ports/webassembly/**'
+ - 'tests/**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@@ -20,13 +21,13 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Install packages
- run: source tools/ci.sh && ci_webassembly_setup
+ run: tools/ci.sh webassembly_setup
- name: Build
- run: source tools/ci.sh && ci_webassembly_build
+ run: tools/ci.sh webassembly_build
- name: Run tests
- run: source tools/ci.sh && ci_webassembly_run_tests
+ run: tools/ci.sh webassembly_run_tests
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
diff --git a/.github/workflows/ports_windows.yml b/.github/workflows/ports_windows.yml
index 91a3192a10a..1243366d413 100644
--- a/.github/workflows/ports_windows.yml
+++ b/.github/workflows/ports_windows.yml
@@ -25,51 +25,47 @@ jobs:
platform: [x86, x64]
configuration: [Debug, Release]
variant: [dev, standard]
- visualstudio: ['2017', '2019', '2022']
+ visualstudio: ['2019', '2022']
include:
- - visualstudio: '2017'
- runner: windows-latest
- vs_version: '[15, 16)'
- visualstudio: '2019'
- runner: windows-2019
- vs_version: '[16, 17)'
+ # The v142 toolset (VS 2019 compiler) is pre-installed on
+ # windows-2022 as a component of VS 2022. Use VS 2022's
+ # MSBuild and select the v142 toolset via PlatformToolset.
+ vs_version: '[17, 18)'
+ platform_toolset: v142
- visualstudio: '2022'
- runner: windows-2022
vs_version: '[17, 18)'
+ platform_toolset: v143
# trim down the number of jobs in the matrix
exclude:
- variant: standard
configuration: Debug
- visualstudio: '2019'
configuration: Debug
+ runs-on: windows-2022
env:
CI_BUILD_CONFIGURATION: ${{ matrix.configuration }}
- runs-on: ${{ matrix.runner }}
steps:
- - name: Install Visual Studio 2017
- if: matrix.visualstudio == '2017'
- run: |
- choco install visualstudio2017buildtools
- choco install visualstudio2017-workload-vctools
- choco install windows-sdk-8.1
- - uses: microsoft/setup-msbuild@v2
+ - name: Install Python 3.11
+ # As of 20260112 the default Python version in Windows image is 3.12, which breaks settrace tests
+ # Use 3.11 for now
+ uses: actions/setup-python@v6
with:
- vs-version: ${{ matrix.vs_version }}
- - uses: actions/setup-python@v5
- if: matrix.runner == 'windows-2019'
+ python-version: '3.11'
+ - uses: microsoft/setup-msbuild@v3
with:
- python-version: '3.9'
- - uses: actions/checkout@v4
+ vs-version: ${{ matrix.vs_version }}
+ - uses: actions/checkout@v6
- name: Build mpy-cross.exe
- run: msbuild mpy-cross\mpy-cross.vcxproj -maxcpucount -property:Configuration=${{ matrix.configuration }} -property:Platform=${{ matrix.platform }}
+ run: msbuild mpy-cross\mpy-cross.vcxproj -maxcpucount -property:Configuration=${{ matrix.configuration }} -property:Platform=${{ matrix.platform }} -property:PlatformToolset=${{ matrix.platform_toolset }}
- name: Update submodules
run: git submodule update --init lib/micropython-lib
- name: Build micropython.exe
- run: msbuild ports\windows\micropython.vcxproj -maxcpucount -property:Configuration=${{ matrix.configuration }} -property:Platform=${{ matrix.platform }} -property:PyVariant=${{ matrix.variant }}
+ run: msbuild ports\windows\micropython.vcxproj -maxcpucount -property:Configuration=${{ matrix.configuration }} -property:Platform=${{ matrix.platform }} -property:PyVariant=${{ matrix.variant }} -property:PlatformToolset=${{ matrix.platform_toolset }}
- name: Get micropython.exe path
id: get_path
run: |
- $exePath="$(msbuild ports\windows\micropython.vcxproj -nologo -v:m -t:ShowTargetPath -property:Configuration=${{ matrix.configuration }} -property:Platform=${{ matrix.platform }} -property:PyVariant=${{ matrix.variant }})"
+ $exePath="$(msbuild ports\windows\micropython.vcxproj -nologo -v:m -t:ShowTargetPath -property:Configuration=${{ matrix.configuration }} -property:Platform=${{ matrix.platform }} -property:PyVariant=${{ matrix.variant }} -property:PlatformToolset=${{ matrix.platform_toolset }})"
echo ("micropython=" + $exePath.Trim()) >> $env:GITHUB_OUTPUT
- name: Run tests
id: test
@@ -103,13 +99,18 @@ jobs:
env: i686
- sys: mingw64
env: x86_64
- runs-on: windows-2022
+ runs-on: windows-latest
env:
CHERE_INVOKING: enabled_from_arguments
defaults:
run:
shell: msys2 {0}
steps:
+ - uses: actions/setup-python@v6
+ # note: can go back to installing mingw-w64-${{ matrix.env }}-python after
+ # MSYS2 updates to Python >3.12 (due to settrace compatibility issue)
+ with:
+ python-version: '3.11'
- uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.sys }}
@@ -118,10 +119,10 @@ jobs:
make
mingw-w64-${{ matrix.env }}-gcc
pkg-config
- mingw-w64-${{ matrix.env }}-python3
git
diffutils
- - uses: actions/checkout@v4
+ path-type: inherit # Remove when setup-python is removed
+ - uses: actions/checkout@v6
- name: Build mpy-cross.exe
run: make -C mpy-cross -j2
- name: Update submodules
@@ -139,8 +140,8 @@ jobs:
cross-build-on-linux:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Install packages
- run: source tools/ci.sh && ci_windows_setup
+ run: tools/ci.sh windows_setup
- name: Build
- run: source tools/ci.sh && ci_windows_build
+ run: tools/ci.sh windows_build
diff --git a/.github/workflows/ports_zephyr.yml b/.github/workflows/ports_zephyr.yml
index 444b0973daf..330121d1de6 100644
--- a/.github/workflows/ports_zephyr.yml
+++ b/.github/workflows/ports_zephyr.yml
@@ -11,6 +11,7 @@ on:
- 'shared/**'
- 'lib/**'
- 'ports/zephyr/**'
+ - 'tests/**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@@ -23,21 +24,41 @@ jobs:
- uses: jlumbroso/free-disk-space@main
with:
# Only free up a few things so this step runs quickly.
+ # (android would save 9.6GiB, but takes about 13m)
+ # (large-packages would save 4.6GiB, but takes about 3m)
android: false
dotnet: true
haskell: true
large-packages: false
docker-images: false
+ tool-cache: true
swap-storage: false
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
+ - id: versions
+ name: Read Zephyr version
+ run: source tools/ci.sh && echo "ZEPHYR=$ZEPHYR_VERSION" | tee "$GITHUB_OUTPUT"
+ - name: Cached Zephyr Workspace
+ id: cache_workspace
+ uses: actions/cache@v5
+ with:
+ # note that the Zephyr CI docker image is 15GB. At time of writing
+ # GitHub caches are limited to 10GB total for a project. So we only
+ # cache the "workspace"
+ path: ./zephyrproject
+ key: zephyr-workspace-${{ steps.versions.outputs.ZEPHYR }}
+ - name: ccache
+ uses: hendrikmuhs/ccache-action@v1.2
+ with:
+ key: zephyr
- name: Install packages
- run: source tools/ci.sh && ci_zephyr_setup
+ run: tools/ci.sh zephyr_setup
- name: Install Zephyr
- run: source tools/ci.sh && ci_zephyr_install
+ if: steps.cache_workspace.outputs.cache-hit != 'true'
+ run: tools/ci.sh zephyr_install
- name: Build
- run: source tools/ci.sh && ci_zephyr_build
+ run: tools/ci.sh zephyr_build
- name: Run main test suite
- run: source tools/ci.sh && ci_zephyr_run_tests
+ run: tools/ci.sh zephyr_run_tests
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
diff --git a/.github/workflows/ruff.yml b/.github/workflows/ruff.yml
index 30ae27c0163..d32ea6d07e5 100644
--- a/.github/workflows/ruff.yml
+++ b/.github/workflows/ruff.yml
@@ -6,10 +6,10 @@ jobs:
ruff:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Initialize lv_bindings submodule
run: git submodule update --init --recursive user_modules/lv_binding_micropython
- # ruff version should be kept in sync with .pre-commit-config.yaml
- - run: pip install --user ruff==0.1.3
+ # ruff version should be kept in sync with .pre-commit-config.yaml & also micropython-lib
+ - run: pipx install ruff==0.11.6
- run: ruff check --output-format=github .
- run: ruff format --diff .
diff --git a/.gitignore b/.gitignore
index b9a3e59ed66..b57f42c242f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -70,3 +70,11 @@ TAGS
ports/javascript/node_modules
.vscode/
+
+# Created by ci.sh zephyr targets
+/.ccache
+/zephyrproject
+
+# Created by ci.sh esp8266 targets
+/xtensa-lx106-elf-standalone.tar.gz
+/xtensa-lx106-elf/
diff --git a/.gitmodules b/.gitmodules
index 3402338cb36..7d2e200cf81 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -35,7 +35,7 @@
url = https://github.com/bluekitchen/btstack.git
[submodule "lib/nxp_driver"]
path = lib/nxp_driver
- url = https://github.com/hathach/nxp_driver.git
+ url = https://github.com/micropython/nxp_driver.git
[submodule "lib/libhydrogen"]
path = lib/libhydrogen
url = https://github.com/jedisct1/libhydrogen.git
@@ -68,6 +68,12 @@
[submodule "lib/arduino-lib"]
path = lib/arduino-lib
url = https://github.com/arduino/arduino-lib-mpy.git
+[submodule "lib/alif_ensemble-cmsis-dfp"]
+ path = lib/alif_ensemble-cmsis-dfp
+ url = https://github.com/alifsemi/alif_ensemble-cmsis-dfp.git
+[submodule "lib/alif-security-toolkit"]
+ path = lib/alif-security-toolkit
+ url = https://github.com/micropython/alif-security-toolkit.git
[submodule "user_modules/lv_binding_micropython"]
path = user_modules/lv_binding_micropython
url = https://github.com/lvgl/lv_binding_micropython.git
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index a1c811339ad..ac9785bb592 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -12,14 +12,14 @@ repos:
verbose: true
stages: [commit-msg]
- repo: https://github.com/charliermarsh/ruff-pre-commit
- # Version should be kept in sync with .github/workflows/ruff.yml
- rev: v0.1.3
+ # Version should be kept in sync with .github/workflows/ruff.yml & also micropython-lib
+ rev: v0.11.6
hooks:
- id: ruff
- id: ruff-format
- repo: https://github.com/codespell-project/codespell
# Version should be kept in sync with .github/workflows/codespell.yml
- rev: v2.2.6
+ rev: v2.4.1
hooks:
- id: codespell
name: Spellcheck for changed files (codespell)
diff --git a/CODECONVENTIONS.md b/CODECONVENTIONS.md
index d6af0418e42..d3f71cb083d 100644
--- a/CODECONVENTIONS.md
+++ b/CODECONVENTIONS.md
@@ -206,14 +206,21 @@ adhere to the existing style and use `tools/codeformat.py` to check any changes.
The main conventions, and things not enforceable via the auto-formatter, are
described below.
-White space:
+As the MicroPython code base is over ten years old, not every source file
+conforms fully to these conventions. If making small changes to existing code,
+then it's usually acceptable to follow the existing code's style. New code or
+major changes should follow the conventions described here.
+
+## White space
+
- Expand tabs to 4 spaces.
- Don't leave trailing whitespace at the end of a line.
- For control blocks (if, for, while), put 1 space between the
keyword and the opening parenthesis.
- Put 1 space after a comma, and 1 space around operators.
-Braces:
+## Braces
+
- Use braces for all blocks, even no-line and single-line pieces of
code.
- Put opening braces on the end of the line it belongs to, not on
@@ -221,18 +228,43 @@ Braces:
- For else-statements, put the else on the same line as the previous
closing brace.
-Header files:
+## Header files
+
- Header files should be protected from multiple inclusion with #if
directives. See an existing header for naming convention.
-Names:
+## Names
+
- Use underscore_case, not camelCase for all names.
- Use CAPS_WITH_UNDERSCORE for enums and macros.
- When defining a type use underscore_case and put '_t' after it.
-Integer types: MicroPython runs on 16, 32, and 64 bit machines, so it's
-important to use the correctly-sized (and signed) integer types. The
-general guidelines are:
+### Public names (declared in headers)
+
+- MicroPython-specific names (especially any declared in `py/` and `extmod/`
+ directories) should generally start with `mp_` or `MP_`.
+- Functions and variables declared in a header should generally share a longer
+ common prefix. Usually the prefix matches the file name (i.e. items defined in
+ `py/obj.c` are declared in `py/obj.h` and should be prefixed `mp_obj_`). There
+ are exceptions, for example where one header file contains declarations
+ implemented in multiple source files for expediency.
+
+### Private names (specific to a single .c file)
+
+- For static functions and variables exposed to Python (i.e. a static C function
+ that is wrapped in `MP_DEFINE_CONST_FUN_...` and attached to a module), use
+ the file-level shared common prefix, i.e. name them as if the function or
+ variable was not static.
+- Other static definitions in source files (i.e. functions or variables defined
+ in a .c file that are only used within that .c file) don't need any prefix
+ (specifically: no `s_` or `_` prefix, and generally avoid adding the
+ file-level common prefix).
+
+## Integer types
+
+MicroPython runs on 16, 32, and 64 bit machines, so it's important to use the
+correctly-sized (and signed) integer types. The general guidelines are:
+
- For most cases use mp_int_t for signed and mp_uint_t for unsigned
integer values. These are guaranteed to be machine-word sized and
therefore big enough to hold the value from a MicroPython small-int
@@ -241,11 +273,13 @@ general guidelines are:
- You can use int/uint, but remember that they may be 16-bits wide.
- If in doubt, use mp_int_t/mp_uint_t.
-Comments:
+## Comments
+
- Be concise and only write comments for things that are not obvious.
- Use `// ` prefix, NOT `/* ... */`. No extra fluff.
-Memory allocation:
+## Memory allocation
+
- Use m_new, m_renew, m_del (and friends) to allocate and free heap memory.
These macros are defined in py/misc.h.
diff --git a/LICENSE b/LICENSE
index 550ed9574d0..28b5239e5fe 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2013-2024 Damien P. George
+Copyright (c) 2013-2026 Damien P. George
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 566a0f75dd1..6558a59888d 100644
--- a/README.md
+++ b/README.md
@@ -12,13 +12,10 @@ The MicroPython project
-This is the MicroPython project, which aims to put an implementation
-of Python 3.x on microcontrollers and small embedded systems.
+This is the MicroPython project, an implementation of Python 3.x for
+microcontrollers, embedded systems and other constrained platforms.
You can find the official website at [micropython.org](http://www.micropython.org).
-WARNING: this project is in beta stage and is subject to changes of the
-code-base, including project-wide name changes and API changes.
-
MicroPython implements the entire Python 3.4 syntax (including exceptions,
`with`, `yield from`, etc., and additionally `async`/`await` keywords from
Python 3.5 and some select features from later versions). The following core
@@ -59,6 +56,44 @@ the officially supported board from the
see the [schematics and pinouts](http://github.com/micropython/pyboard) and
[documentation](https://docs.micropython.org/en/latest/pyboard/quickref.html).
+MicroPython design values
+-------------------------
+
+"Perfection is achieved, not when there is nothing more to add, but when there
+is nothing left to take away." ―- Antoine de Saint-Exupéry.
+
+For its design and implementation, MicroPython aims to follow a set of values.
+Although not a strict set of rules, these values and principles serve as a
+useful guide for new and seasoned contributors, as well as maintainers.
+
+MicroPython is at heart a combination of "Micro" and "Python": it's about
+resource constrained systems running the Python programming language. Both of
+these concepts balance off against each other in all parts of MicroPython's
+design and implementation.
+
+The key concepts that focus the development of MicroPython are:
+- Minimalism: do lots with little.
+- Efficiency: engineering, build, execution, storage, power consumption.
+- Consistency: the whole system feels like it was designed at once.
+
+When using MicroPython, the Python language is used as the human interface to a
+system, giving fine control over the entities attached to that system.
+In a hardware setting, MicroPython aims to give the user a bare-metal feeling:
+one should feel like they have complete control over the system, with very
+little between the programmer and the physical world.
+
+MicroPython recognises that systems can be very complex. The existing Python
+libraries in combination with the MicroPython-specific libraries provide a
+user-friendly way to harness the complexity of a system.
+
+Python language compatibility is very important to MicroPython, and at first
+glance MicroPython should look just like regular Python. In the first instance,
+most Python scripts should run unchanged on MicroPython, even on devices with very
+tight resources. Beyond that, there are ways to extend MicroPython if needed to
+better match Python. The provided built-in modules are an efficient subset of
+the corresponding Python ones, without duplication of functionality, and allow
+extension in Python if needed.
+
Contributing
------------
@@ -86,9 +121,8 @@ This repository contains the following components:
- [examples/](examples/) -- a few example Python scripts.
"make" is used to build the components, or "gmake" on BSD-based systems.
-You will also need bash, gcc, and Python 3.3+ available as the command `python3`
-(if your system only has Python 2.7 then invoke make with the additional option
-`PYTHON=python2`). Some ports (rp2 and esp32) additionally use CMake.
+You will also need bash, gcc, and Python 3.3+ available as the command `python3`.
+Some ports (rp2 and esp32) additionally use CMake.
Supported platforms & architectures
-----------------------------------
@@ -105,28 +139,74 @@ development and testing of MicroPython itself, as well as providing
lightweight alternative to CPython on these platforms (in particular on
embedded Linux systems).
-The ["minimal"](ports/minimal) port provides an example of a very basic
-MicroPython port and can be compiled as both a standalone Linux binary as
-well as for ARM Cortex M4. Start with this if you want to port MicroPython to
-another microcontroller. Additionally the ["bare-arm"](ports/bare-arm) port
-is an example of the absolute minimum configuration, and is used to keep
-track of the code size of the core runtime and VM.
-
-In addition, the following ports are provided in this repository:
- - [cc3200](ports/cc3200) -- Texas Instruments CC3200 (including PyCom WiPy).
- - [esp32](ports/esp32) -- Espressif ESP32 SoC (including ESP32S2, ESP32S3, ESP32C3, ESP32C6).
- - [esp8266](ports/esp8266) -- Espressif ESP8266 SoC.
- - [mimxrt](ports/mimxrt) -- NXP m.iMX RT (including Teensy 4.x).
- - [nrf](ports/nrf) -- Nordic Semiconductor nRF51 and nRF52.
- - [pic16bit](ports/pic16bit) -- Microchip PIC 16-bit.
- - [powerpc](ports/powerpc) -- IBM PowerPC (including Microwatt)
- - [qemu](ports/qemu) -- QEMU-based emulated target (for testing)
- - [renesas-ra](ports/renesas-ra) -- Renesas RA family.
- - [rp2](ports/rp2) -- Raspberry Pi RP2040 (including Pico and Pico W).
- - [samd](ports/samd) -- Microchip (formerly Atmel) SAMD21 and SAMD51.
- - [stm32](ports/stm32) -- STMicroelectronics STM32 family (including F0, F4, F7, G0, G4, H7, L0, L4, WB)
- - [webassembly](ports/webassembly) -- Emscripten port targeting browsers and NodeJS.
- - [zephyr](ports/zephyr) -- Zephyr RTOS.
+Over twenty different MicroPython ports are provided in this repository,
+split across three
+[MicroPython Support Tiers](https://docs.micropython.org/en/latest/develop/support_tiers.html).
+
+Tier 1 Ports
+============
+
+👑 Ports in [Tier 1](https://docs.micropython.org/en/latest/develop/support_tiers.html)
+are mature and have the most active development, support and testing:
+
+| Port | Target | Quick Reference |
+|--------------------------|----------------------------------------------------------------------------------------|----------------------------------------------------------------------|
+| [esp32](ports/esp32)* | Espressif ESP32 SoCs (ESP32, ESP32S2, ESP32S3, ESP32C3, ESP32C6) | [here](https://docs.micropython.org/en/latest/esp32/quickref.html) |
+| [mimxrt](ports/mimxrt) | NXP m.iMX RT | [here](https://docs.micropython.org/en/latest/mimxrt/quickref.html) |
+| [rp2](ports/rp2) | Raspberry Pi RP2040 and RP2350 | [here](https://docs.micropython.org/en/latest/rp2/quickref.html) |
+| [samd](ports/samd) | Microchip (formerly Atmel) SAMD21 and SAMD51 | [here](https://docs.micropython.org/en/latest/samd/quickref.html) |
+| [stm32](ports/stm32) | STMicroelectronics STM32 MCUs (F0, F4, F7, G0, G4, H5, H7, L0, L1, L4, N6, WB, WL) | [here](https://docs.micropython.org/en/latest/pyboard/quickref.html) |
+| [unix](ports/unix) | Linux, BSD, macOS, WSL | [here](https://docs.micropython.org/en/latest/unix/quickref.html) |
+| [windows](ports/windows) | Microsoft Windows | [here](https://docs.micropython.org/en/latest/unix/quickref.html) |
+
+An asterisk indicates that the port has ongoing financial support from the vendor.
+
+Tier 2 Ports
+============
+
+✔ Ports in [Tier 2](https://docs.micropython.org/en/latest/develop/support_tiers.html)
+are less mature and less actively developed and tested than Tier 1, but
+still fully supported:
+
+| Port | Target | Quick Reference |
+|----------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------|
+| [alif](ports/alif) | Alif Semiconductor Ensemble MCUs (E3, E7) | |
+| [embed](ports/embed) | Generates a set of .c/.h files for embedding into a project | |
+| [nrf](ports/nrf) | Nordic Semiconductor nRF51 and nRF52 | |
+| [renesas-ra](ports/renesas-ra) | Renesas RA family | [here](https://docs.micropython.org/en/latest/renesas-ra/quickref.html) |
+| [webassembly](ports/webassembly) | Emscripten port targeting browsers and NodeJS | |
+| [zephyr](ports/zephyr) | Zephyr RTOS | [here](https://docs.micropython.org/en/latest/zephyr/quickref.html) |
+
+Tier 3 Ports
+============
+
+Ports in [Tier 3](https://docs.micropython.org/en/latest/develop/support_tiers.html)
+are built in CI but not regularly tested by the MicroPython maintainers:
+
+| Port | Target | Quick Reference |
+|----------------------------|-------------------------------------------------------------------|-------------------------------------------------------------------------|
+| [cc3200](ports/cc3200) | Texas Instruments CC3200 | [For WiPy](https://docs.micropython.org/en/latest/wipy/quickref.html) |
+| [esp8266](ports/esp8266) | Espressif ESP8266 SoC | [here](https://docs.micropython.org/en/latest/esp8266/quickref.html) |
+| [pic16bit](ports/pic16bit) | Microchip PIC 16-bit | |
+| [powerpc](ports/powerpc) | IBM PowerPC (including Microwatt) | |
+
+Additional Ports
+================
+
+In addition to the above there is a Tier M containing ports that are used
+primarily for maintenance, development and testing:
+
+- The ["bare-arm"](ports/bare-arm) port is an example of the absolute minimum
+ configuration that still includes the compiler, and is used to keep track
+ of the code size of the core runtime and VM.
+
+- The ["minimal"](ports/minimal) port provides an example of a very basic
+ MicroPython port and can be compiled as both a standalone Linux binary as
+ well as for ARM Cortex-M4. Start with this if you want to port MicroPython
+ to another microcontroller.
+
+- The [qemu](ports/qemu) port is a QEMU-based emulated target for Cortex-A,
+ Cortex-M, RISC-V 32-bit and RISC-V 64-bit architectures.
The MicroPython cross-compiler, mpy-cross
-----------------------------------------
diff --git a/docs/README.md b/docs/README.md
index 892726ba17f..9b3b036e063 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -13,8 +13,7 @@ Building the documentation locally
If you're making changes to the documentation, you may want to build the
documentation locally so that you can preview your changes.
-Install Sphinx, and optionally (for the RTD-styling), sphinx_rtd_theme,
-preferably in a virtualenv:
+Install Sphinx and sphinx_rtd_theme, preferably in a virtualenv:
pip install sphinx
pip install sphinx_rtd_theme
@@ -25,6 +24,21 @@ In `micropython/docs`, build the docs:
You'll find the index page at `micropython/docs/build/html/index.html`.
+Documentation autobuild
+-----------------------
+
+For a more convenient development experience, you can use `sphinx-autobuild`
+to automatically rebuild and serve the documentation when you make changes:
+
+ pip install sphinx-autobuild
+
+Then run from the `micropython/docs` directory:
+
+ sphinx-autobuild . build/html
+
+This will start a local web server (typically at `http://127.0.0.1:8000`)
+and automatically rebuild the documentation whenever you save changes to the source files.
+
Having readthedocs.org build the documentation
----------------------------------------------
diff --git a/docs/conf.py b/docs/conf.py
index 32cc2be10e3..f80ca97edca 100755
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -36,6 +36,9 @@
"is_release": micropy_version != "latest",
}
+# Authors used in various parts of the documentation.
+micropy_authors = "MicroPython authors and contributors"
+
# -- General configuration ------------------------------------------------
@@ -52,6 +55,7 @@
"sphinx.ext.todo",
"sphinx.ext.coverage",
"sphinxcontrib.jquery",
+ "sphinx_rtd_theme",
]
# Add any paths that contain templates here, relative to this directory.
@@ -68,7 +72,7 @@
# General information about the project.
project = "MicroPython"
-copyright = "- The MicroPython Documentation is Copyright © 2014-2024, Damien P. George, Paul Sokolovsky, and contributors"
+copyright = "- The MicroPython Documentation is Copyright © 2014-2026, " + micropy_authors
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
@@ -125,20 +129,9 @@
# -- Options for HTML output ----------------------------------------------
-# on_rtd is whether we are on readthedocs.org
-on_rtd = os.environ.get("READTHEDOCS", None) == "True"
-
-if not on_rtd: # only import and set the theme if we're building docs locally
- try:
- import sphinx_rtd_theme
+import sphinx_rtd_theme
- html_theme = "sphinx_rtd_theme"
- html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), "."]
- except:
- html_theme = "default"
- html_theme_path = ["."]
-else:
- html_theme_path = ["."]
+html_theme = "sphinx_rtd_theme"
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
@@ -244,7 +237,7 @@
master_doc,
"MicroPython.tex",
"MicroPython Documentation",
- "Damien P. George, Paul Sokolovsky, and contributors",
+ micropy_authors,
"manual",
),
]
@@ -281,7 +274,7 @@
"index",
"micropython",
"MicroPython Documentation",
- ["Damien P. George, Paul Sokolovsky, and contributors"],
+ [micropy_authors],
1,
),
]
@@ -300,7 +293,7 @@
master_doc,
"MicroPython",
"MicroPython Documentation",
- "Damien P. George, Paul Sokolovsky, and contributors",
+ micropy_authors,
"MicroPython",
"One line description of project.",
"Miscellaneous",
diff --git a/docs/develop/cmodules.rst b/docs/develop/cmodules.rst
index c5aa919b764..ec20e65f477 100644
--- a/docs/develop/cmodules.rst
+++ b/docs/develop/cmodules.rst
@@ -8,8 +8,8 @@ limitations with the Python environment, often due to an inability to access
certain hardware resources or Python speed limitations.
If your limitations can't be resolved with suggestions in :ref:`speed_python`,
-writing some or all of your module in C (and/or C++ if implemented for your port)
-is a viable option.
+writing some or all of your module in C (and/or
+:ref:`C++ if implemented for your port`) is a viable option.
If your module is designed to access or work with commonly available
hardware or libraries please consider implementing it inside the MicroPython
@@ -285,3 +285,73 @@ can now be accessed in Python just like any other builtin module, e.g.
sleep_ms(1000)
print(watch.time())
# should display approximately 1000
+
+
+.. _c_heap:
+
+C Dynamic Memory Allocation
+---------------------------
+
+MicroPython uses its own "Python heap" for `memorymanagement`,
+which is not the same as the "C heap" used by C library functions ``malloc()``,
+``free()``, etc. Not every MicroPython port comes with a "C heap" at all.
+
+Tier 1 & 2 ports have varying support for C dynamic memory allocation via a "C
+heap":
+
+- unix, windows, esp32 and webassembly ports support C dynamic memory
+ allocation.
+- rp2 port will fail to allocate any memory at runtime unless the firmware is
+ built with ``MICROPY_C_HEAP_SIZE=n`` to reserve ``n`` bytes of memory for a C
+ heap. This memory will not be available for Python code to use.
+- alif, mimxrt, nrf, renesas-ra, samd, and stm32 port builds that include
+ dynamic C allocation will fail at link-time with errors such as ``undefined
+ reference to `malloc'``. MicroPython has no built-in support for dynamic C
+ allocation on these ports. Any solution requires manually adding a C heap
+ implementation to the custom build.
+- zephyr port currently does not support building with user modules.
+
+Python heap as C heap
+~~~~~~~~~~~~~~~~~~~~~
+
+It may be practical for C code to call "Python heap" dynamic allocation
+functions such ``m_malloc()``, ``m_malloc0()`` and ``m_free()`` instead.
+
+See `python_memory_from_c` for more information about this approach.
+
+.. _cxx_support:
+
+C++ Modules
+-----------
+
+Most Tier 1 & 2 MicroPython ports (and some Tier 3) support building C++ user
+modules, using the C++-specific environment variables described above.
+
+Integrating C++ and MicroPython successfully involves some additional
+considerations:
+
+C++ Dynamic Memory Allocation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+C++ programs (as well as C++ Standard Library features) typically use dynamic
+memory allocation. The C++ default memory allocator (i.e. operators ``new`` and
+``delete``) is typically implemented as a layer on top of `c_heap`.
+
+For MicroPython ports which don't include C dynamic memory allocation support,
+C++ dynamic memory allocation can be supported in one of two ways:
+
+- Implement C dynamic memory allocation in your custom build.
+- Implement a custom C++ allocator in your custom build.
+
+Linkage Considerations
+~~~~~~~~~~~~~~~~~~~~~~
+
+Because MicroPython is a C-based project, any symbols which link to or from
+MicroPython need to be qualified ``extern "C"`` in C++ code.
+
+It's strongly recommended to follow the pattern demonstrated in
+`examples/usercmodule/cppexample
+`_,
+where the Python module is implemented in a minimal C file wrapper around the
+C++ code.
+
diff --git a/docs/develop/gettingstarted.rst b/docs/develop/gettingstarted.rst
index c1fd338c54c..a6afc5cad84 100644
--- a/docs/develop/gettingstarted.rst
+++ b/docs/develop/gettingstarted.rst
@@ -106,7 +106,7 @@ See the `ARM GCC
toolchain `_
for the latest details.
-Python is also required. Python 2 is supported for now, but we recommend using Python 3.
+Python 3 is also required.
Check that you have Python available on your system:
.. code-block:: bash
@@ -278,10 +278,86 @@ To run a selection of tests on a board/device connected over USB use:
.. code-block:: bash
$ cd tests
- $ ./run-tests.py --target minimal --device /dev/ttyACM0
+ $ ./run-tests.py -t /dev/ttyACM0
See also :ref:`writingtests`.
+Additional make targets for developers
+--------------------------------------
+
+In all ``make``-based ports, there is a target to print the size of a specific object file.
+When a change is confined to a single file, this is useful when testing variations to find smaller alternatives.
+
+For instance, to print the size of ``objstr.o`` in the ``py/`` directory when making a unix standard build:
+
+.. code-block:: bash
+
+ $ make build-standard/py/objstr.sz
+
+Similarly, there is a target to save the preprocessed version of a file:
+
+.. code-block:: bash
+
+ $ make build-standard/py/objstr.pp
+
+In ``ports/unix`` there are additional targets related to running tests:
+
+.. code-block:: bash
+
+ $ make test//int # Run all tests matching the pattern "int"
+ $ make test/ports/unix # Run all tests in ports/unix
+ $ make test-failures # Re-run only the failed tests
+ $ make print-failures # print the differences for failed tests
+ $ make clean-failures # delete the .exp and .out files from failed tests
+
+Using ci.sh locally
+-------------------
+
+MicroPython uses GitHub Actions for continuous integration.
+To reduce dependence on any specific CI system, the actual build steps for Unix-based builds are in the file ``tools/ci.sh``.
+This can also be used as a script on developer desktops, with caveats:
+
+* For most steps, An Ubuntu/Debian system similar to the one used during CI is assumed.
+* Some specific steps assume specific Ubuntu versions.
+* The setup steps may invoke the system package manager to install packages,
+ download and install software from the internet, etc.
+
+To get a usage message including the list of commands, run:
+
+.. code-block:: bash
+
+ $ tools/ci.sh --help
+
+As an example, you can build and test the unix minimal port with:
+
+.. code-block:: bash
+
+ $ tools/ci.sh unix_minimal_build unix_minimal_run_tests
+
+If you use the bash shell, you can add a ``ci`` command with tab completion:
+
+.. code-block:: bash
+
+ $ eval $(tools/ci.sh --bash-completion)
+
+For the zsh shell, replace ``--bash-completion`` with ``--zsh-completion``.
+For the fish shell, replace ``--bash-completion`` with ``--fish-completion``.
+
+Then, typing:
+
+.. code-block:: bash
+
+ $ ci unix_cov
+
+This will complete the ci step name to ``unix_coverage_``.
+Pressing tab a second time will show the list of matching steps:
+
+.. code-block:: bash
+
+ $ ci unix_coverage_
+ unix_coverage_32bit_build
+ unix_coverage_32bit_run_native_mpy_tests…
+
Folder structure
----------------
diff --git a/docs/develop/index.rst b/docs/develop/index.rst
index 327038f1978..1026b43d0c3 100644
--- a/docs/develop/index.rst
+++ b/docs/develop/index.rst
@@ -24,3 +24,4 @@ MicroPython to a new platform and implementing a core MicroPython library.
publiccapi.rst
extendingmicropython.rst
porting.rst
+ support_tiers.rst
diff --git a/docs/develop/library.rst b/docs/develop/library.rst
index 830211d81c8..6ff9bfe023d 100644
--- a/docs/develop/library.rst
+++ b/docs/develop/library.rst
@@ -26,15 +26,9 @@ Implementing a core module
--------------------------
Like CPython, MicroPython has core builtin modules that can be accessed through import statements.
-An example is the ``gc`` module discussed in :ref:`memorymanagement`.
+An example is the :mod:`gc` module discussed in :ref:`memorymanagement`.
-.. code-block:: bash
-
- >>> import gc
- >>> gc.enable()
- >>>
-
-MicroPython has several other builtin standard/core modules like ``io``, ``array`` etc.
+MicroPython has several other builtin standard/core modules like :mod:`io`, :mod:`array`, etc.
Adding a new core module involves several modifications.
First, create the ``C`` file in the ``py/`` directory. In this example we are adding a
diff --git a/docs/develop/memorymgt.rst b/docs/develop/memorymgt.rst
index 5b1690cc827..4ae80120044 100644
--- a/docs/develop/memorymgt.rst
+++ b/docs/develop/memorymgt.rst
@@ -4,43 +4,80 @@ Memory Management
=================
Unlike programming languages such as C/C++, MicroPython hides memory management
-details from the developer by supporting automatic memory management.
-Automatic memory management is a technique used by operating systems or applications to automatically manage
-the allocation and deallocation of memory. This eliminates challenges such as forgetting to
-free the memory allocated to an object. Automatic memory management also avoids the critical issue of using memory
-that is already released. Automatic memory management takes many forms, one of them being
-garbage collection (GC).
-
-The garbage collector usually has two responsibilities;
-
-#. Allocate new objects in available memory.
-#. Free unused memory.
-
-There are many GC algorithms but MicroPython uses the
-`Mark and Sweep `_
-policy for managing memory. This algorithm has a mark phase that traverses the heap marking all
-live objects while the sweep phase goes through the heap reclaiming all unmarked objects.
-
-Garbage collection functionality in MicroPython is available through the ``gc`` built-in
-module:
-
-.. code-block:: bash
-
- >>> x = 5
- >>> x
- 5
- >>> import gc
- >>> gc.enable()
- >>> gc.mem_alloc()
- 1312
- >>> gc.mem_free()
- 2071392
- >>> gc.collect()
- 19
- >>> gc.disable()
- >>>
-
-Even when ``gc.disable()`` is invoked, collection can be triggered with ``gc.collect()``.
+details from the developer by supporting automatic memory management of a
+":ref:`Python heap`" that holds all Python objects. MicroPython uses
+garbage collection (GC) for automatic memory management. The garbage collector
+is responsible for freeing memory which is no longer in use.
+
+Specifically, MicroPython uses a `Mark and Sweep
+`_
+garbage collection algorithm. This algorithm has a mark phase that scans the
+heap marking all live objects, and then a sweep phase goes through the heap
+reclaiming all unmarked objects.
+
+The MicroPython garbage collector is by default automatic, but manual control is
+available through the :mod:`gc` built-in module.
+
+.. _python_memory_from_c:
+
+MicroPython Memory from C code
+------------------------------
+
+Awareness of the garbage collector is needed when writing C code that allocates
+memory from the "Python heap" (i.e. functions ``m_malloc()``, ``m_malloc0()``,
+``m_free()``, etc).
+
+The mark phase of the garbage collector scans for live pointers to heap memory
+starting from the following roots:
+
+- The stack of the main Python runtime (or REPL).
+- The stacks of each "Python thread", for ports which implement Python threads
+ on top of native operating system threads or tasks.
+- The "root pointers" defined in C code using the macro
+ ``MP_REGISTER_ROOT_POINTER``. These are the recommended way to have statically
+ scoped pointers to the Python heap.
+- Tracked allocations made with the ``m_tracked_calloc()``, ``m_tracked_realloc``
+ and ``m_tracked_free()`` functions. These special functions allow allocating a
+ block of memory which is always considered live by the garbage collector.
+ Similar to memory allocation in C, this memory is only freed by calling
+ ``m_tracked_free()`` or by soft reset. There is a small memory usage and
+ runtime overhead to each tracked allocation. This feature is not enabled by
+ default on all ports.
+
+The garbage collector then recursively scans and marks all the memory pointed to
+by the root pointers, until all addresses are exhausted. This is sufficient to
+find all Python objects that are still in use by the MicroPython runtime.
+
+However, the following memory will **not** be scanned by the garbage collector
+and could be freed prematurely:
+
+- Static or global C variables which contain pointers to heap memory.
+- Pointers which don't point to the "head" of an allocated buffer (i.e. to the
+ exact address returned by ``m_malloc()``), but instead to an address inside
+ the allocated buffer (for example, a pointer to a nested struct). For
+ performance reasons, the garbage collector doesn't mark the enclosing buffer
+ in these cases.
+- The stack of any thread or RTOS task which isn't running Python code or
+ manually registered as a "Python thread" (for ports which support native
+ threads or tasks).
+
+Ways to avoid use-after-free in these scenarios:
+
+- Use the tracked allocation API ``m_tracked_calloc()``, ``m_tracked_realloc()``
+ and ``m_tracked_free()``.
+- Register a root pointer (see above), instead of storing a pointer in a static
+ variable.
+- Restructure the code, for example by having an API where Python code
+ initialises a singleton Python object (implemented in C) which holds all of the
+ relevant pointers instead of having them in static variables.
+
+.. note:: :ref:`soft_reset` always clears the Python heap and frees all memory.
+ It's important not to hold any pointers to the heap after a soft
+ reset, as they will become dangling pointers to freed memory.
+
+ Some ports support a "C heap" as well (see `c_heap`), in which case
+ you can allocate memory that will stay valid over soft reset by
+ calling standard C functions ``malloc``, etc.
The object model
----------------
diff --git a/docs/develop/natmod.rst b/docs/develop/natmod.rst
index 502ea1c4c68..e0f7bdaaa89 100644
--- a/docs/develop/natmod.rst
+++ b/docs/develop/natmod.rst
@@ -39,11 +39,18 @@ options for the ``ARCH`` variable, see below):
* ``armv7emsp`` (ARM Thumb 2, single precision float, eg Cortex-M4F, Cortex-M7)
* ``armv7emdp`` (ARM Thumb 2, double precision float, eg Cortex-M7)
* ``xtensa`` (non-windowed, eg ESP8266)
-* ``xtensawin`` (windowed with window size 8, eg ESP32)
+* ``xtensawin`` (windowed with window size 8, eg ESP32, ESP32S3)
+* ``rv32imc`` (RISC-V 32 bits with compressed instructions, eg ESP32C3, ESP32C6)
+* ``rv64imc`` (RISC-V 64 bits with compressed instructions)
+
+If the chosen platform supports explicit architecture flags and you want to let
+the output .mpy file carry those flags' value, you must pass them to the
+``ARCH_FLAGS`` flags variable when building the .mpy file.
When compiling and linking the native .mpy file the architecture must be chosen
-and the corresponding file can only be imported on that architecture. For more
-details about .mpy files see :ref:`mpy_files`.
+and the corresponding file can only be imported on that architecture (and if
+architecture flags are present, only if they match the target's capabilities).
+For more details about .mpy files see :ref:`mpy_files`.
Native code must be compiled as position independent code (PIC) and use a global
offset table (GOT), although the details of this varies from architecture to
@@ -66,14 +73,31 @@ The known limitations are:
* static BSS variables are not supported; workaround: use global BSS variables
+* thread-local storage variables are not supported on rv32imc; workaround: use
+ global BSS variables or allocate some space on the heap to store them
+
So, if your C code has writable data, make sure the data is defined globally,
without an initialiser, and only written to within functions.
+The native module is not automatically linked against the standard static libraries
+like ``libm.a`` and ``libgcc.a``, which can lead to ``undefined symbol`` errors.
+You can link the runtime libraries by setting ``LINK_RUNTIME = 1``
+in your Makefile. Custom static libraries can also be linked by adding
+``MPY_LD_FLAGS += -l path/to/library.a``. Note that these are linked into
+the native module and will not be shared with other modules or the system.
+
Linker limitation: the native module is not linked against the symbol table of the
full MicroPython firmware. Rather, it is linked against an explicit table of exported
symbols found in ``mp_fun_table`` (in ``py/nativeglue.h``), that is fixed at firmware
build time. It is thus not possible to simply call some arbitrary HAL/OS/RTOS/system
-function, for example.
+function, for example, unless that resides at a fixed address. In that case, the path
+of a linkerscript containing a series of symbol names and their fixed address can be
+passed to ``mpy_ld.py`` via the ``--externs`` command line argument. That way symbols
+appearing in the linkerscript will take precedence over what is provided from object
+files, but at the moment the object files' implementation will still reside in the
+final MPY file. The linkerscript parser is limited in its capabilities, and is
+currently used only for parsing the ESP8266 port ROM symbols list (see
+``ports/esp8266/boards/eagle.rom.addr.v6.ld``).
New symbols can be added to the end of the table and the firmware rebuilt.
The symbols also need to be added to ``tools/mpy_ld.py``'s ``fun_table`` dict in the
@@ -105,7 +129,8 @@ The filesystem layout consists of two main parts, the source files and the Makef
location of the MicroPython repository (to find header files, the relevant Makefile
fragment, and the ``mpy_ld.py`` tool), ``MOD`` as the name of the module, ``SRC``
as the list of source files, optionally specify the machine architecture via ``ARCH``,
- and then include ``py/dynruntime.mk``.
+ along with optional machine architecture flags specified via ``ARCH_FLAGS``, and
+ then include ``py/dynruntime.mk``.
Minimal example
---------------
@@ -172,7 +197,7 @@ The file ``Makefile`` contains:
# Source files (.c or .py)
SRC = factorial.c
- # Architecture to build for (x86, x64, armv6m, armv7m, xtensa, xtensawin)
+ # Architecture to build for (x86, x64, armv6m, armv7m, xtensa, xtensawin, rv32imc, rv64imc)
ARCH = x64
# Include to get the rules for compiling and linking the module
@@ -198,6 +223,10 @@ Without modifying the Makefile you can specify the target architecture via::
$ make ARCH=armv7m
+Same applies for optional architecture flags via::
+
+ $ make ARCH=rv32imc ARCH_FLAGS=zba
+
Module usage in MicroPython
---------------------------
@@ -210,6 +239,26 @@ other module, for example::
print(factorial.factorial(10))
# should display 3628800
+Using Picolibc when building modules
+------------------------------------
+
+Using `Picolibc `_ as your C standard
+library is not only supported, but in fact it is the default for the rv32imc and
+rv64imc platforms. However, there are a couple of things worth mentioning to make
+sure you don't run into problems later when building code.
+
+Some pre-built Picolibc versions (for example, those provided by Ubuntu Linux
+as the ``picolibc-arm-none-eabi``, ``picolibc-riscv64-unknown-elf``, and
+``picolibc-xtensa-lx106-elf`` packages) assume thread-local storage (TLS) is
+available at runtime, but unfortunately MicroPython modules do not support that
+on some architectures (namely ``rv32imc`` and ``rv64imc``). This means that some
+functionalities provided by Picolibc will default to use TLS, returning an
+error either during compilation or during linking.
+
+For an example on how this may affect you, the ``examples/natmod/btree``
+example module contains a workaround to make sure ``errno`` works (look for
+``__PICOLIBC_ERRNO_FUNCTION`` in the Makefile and follow the trail from there).
+
Further examples
----------------
diff --git a/docs/develop/porting.rst b/docs/develop/porting.rst
index 99725e1000b..28d7b3dd513 100644
--- a/docs/develop/porting.rst
+++ b/docs/develop/porting.rst
@@ -42,7 +42,6 @@ The basic MicroPython firmware is implemented in the main port file, e.g ``main.
#include "py/compile.h"
#include "py/gc.h"
#include "py/mperrno.h"
- #include "py/stackctrl.h"
#include "shared/runtime/gchelper.h"
#include "shared/runtime/pyexec.h"
@@ -51,7 +50,7 @@ The basic MicroPython firmware is implemented in the main port file, e.g ``main.
int main(int argc, char **argv) {
// Initialise the MicroPython runtime.
- mp_stack_ctrl_init();
+ mp_cstack_init_with_sp_here(2048);
gc_init(heap, heap + sizeof(heap));
mp_init();
@@ -162,8 +161,6 @@ The following is an example of an ``mpconfigport.h`` file:
// Type definitions for the specific machine.
- typedef intptr_t mp_int_t; // must be pointer size
- typedef uintptr_t mp_uint_t; // must be pointer size
typedef long mp_off_t;
// We need to provide a declaration/definition of alloca().
@@ -244,10 +241,12 @@ That should give a MicroPython REPL. You can then run commands like:
.. code-block:: bash
- MicroPython v1.13 on 2021-01-01; example-board with unknown-cpu
- >>> import sys
- >>> sys.implementation
- ('micropython', (1, 13, 0))
+ MicroPython v1.26.0-preview on 2025-08-01; minimal with unknown-cpu
+ >>> def sum(n, m):
+ ... return n + m
+ ...
+ >>> 3, 4, sum(3, 4)
+ (3, 4, 7)
>>>
Use Ctrl-D to exit, and then run ``reset`` to reset the terminal.
diff --git a/docs/develop/support_tiers.rst b/docs/develop/support_tiers.rst
new file mode 100644
index 00000000000..f49ee4124f8
--- /dev/null
+++ b/docs/develop/support_tiers.rst
@@ -0,0 +1,68 @@
+MicroPython Support Tiers
+=========================
+
+MicroPython operates with a set of Support Tier levels for the various ports.
+Tiers 1, 2 and 3 are the main Tier levels with Tier 1 being the most mature and
+actively maintained. There is also Tier M for additional ports used primarily
+for maintenance, development and testing. These Tier levels are defined in the
+table below.
+
+.. table::
+ :widths: 40 9 9 9 9
+
+ +-----------------------------------------------+--------+--------+--------+--------+
+ | | Tier 1 | Tier 2 | Tier 3 | Tier M |
+ +-----------------------------------------------+--------+--------+--------+--------+
+ | builds pass under CI | ✔ | ✔ | ✔ | ✔ |
+ +-----------------------------------------------+--------+--------+--------+--------+
+ | tests run under CI (where possible) | ✔ | ✔ | ✔ | ✔ |
+ +-----------------------------------------------+--------+--------+--------+--------+
+ | actively maintained | ✔ | ✔ | | ✔ |
+ +-----------------------------------------------+--------+--------+--------+--------+
+ | stable Python API | ✔ | ✔ | | |
+ +-----------------------------------------------+--------+--------+--------+--------+
+ | new features actively developed | ✔ | ✔ | | |
+ +-----------------------------------------------+--------+--------+--------+--------+
+ | tested on hardware for releases | ✔ | ✔ | | |
+ +-----------------------------------------------+--------+--------+--------+--------+
+ | prioritized bug reports | ✔ | | | ✔ |
+ +-----------------------------------------------+--------+--------+--------+--------+
+ | regressions warrant a patch release | ✔ | | | ✔ |
+ +-----------------------------------------------+--------+--------+--------+--------+
+ | has port-specific documentation | ✔ | | | |
+ +-----------------------------------------------+--------+--------+--------+--------+
+
+Lower Tiers may tick more boxes, but the above table defines the minimum requirements
+for a port to belong to a Tier.
+
+Tier 1 ports:
+
+ - esp32
+ - mimxrt
+ - rp2
+ - samd
+ - stm32
+ - unix
+ - windows
+
+Tier 2 ports:
+
+ - alif
+ - embed
+ - nrf
+ - renesas-ra
+ - webassembly
+ - zephyr
+
+Tier 3 ports:
+
+ - cc3200
+ - esp8266
+ - pic16bit
+ - powerpc
+
+Tier M ports:
+
+ - bare-arm
+ - minimal
+ - qemu
diff --git a/docs/develop/writingtests.rst b/docs/develop/writingtests.rst
index 9bb5178f55f..fd3daf91c1e 100644
--- a/docs/develop/writingtests.rst
+++ b/docs/develop/writingtests.rst
@@ -60,7 +60,7 @@ Then to run on a board:
.. code-block:: bash
- $ ./run-tests.py --target minimal --device /dev/ttyACM0
+ $ ./run-tests.py -t /dev/ttyACM0
And to run only a certain set of tests (eg a directory):
@@ -68,3 +68,76 @@ And to run only a certain set of tests (eg a directory):
$ ./run-tests.py -d basics
$ ./run-tests.py float/builtin*.py
+
+Using run-tests.py
+------------------
+
+The ``run-tests.py`` script supports several parameters to customize test execution:
+
+**Target and Device Selection:**
+
+* ``-t, --test-instance``
+
+The -t option accepts the following for the test instance:
+
+- **unix** - use the unix port of MicroPython, specified by the MICROPY_MICROPYTHON
+ environment variable (which defaults to the standard variant of either the unix
+ or windows ports, depending on the host platform)
+- **webassembly** - use the webassembly port of MicroPython, specified by the
+ MICROPY_MICROPYTHON_MJS environment variable (which defaults to the standard
+ variant of the webassembly port)
+- **port:** - connect to and use the given serial port device
+- **a** - connect to and use /dev/ttyACM
+- **u** - connect to and use /dev/ttyUSB
+- **c** - connect to and use COM
+- **exec:** - execute a command and attach to it's stdin/stdout
+- **execpty:** - execute a command and attach to the printed /dev/pts/ device
+- **...** - connect to the given IPv4 address
+- anything else specifies a serial port
+
+**Test Selection:**
+
+* ``-d, --test-dirs`` - Specify one or more test directories to run
+* ``-i, --include REGEX`` - Include tests matching regex pattern
+* ``-e, --exclude REGEX`` - Exclude tests matching regex pattern
+* ``files`` - Specific test files to run
+
+**Execution Options:**
+
+* ``--emit `` - MicroPython emitter, EMITTER can be bytecode or native. Default: bytecode
+* ``--via-mpy`` - Compile .py files to .mpy first
+* ``--heapsize`` - Set heap size for tests
+* ``-j, --jobs N`` - Number of tests to run simultaneously
+
+Set the MICROPY_MPYCROSS environment variable to use a specific version of ``mpy-cross`` when using ``--via-mpy``.
+
+**Result Management:**
+
+* ``-r, --result-dir`` - Directory for test results. Default: results/
+* ``--print-failures`` - Show diff of failed tests and exit
+* ``--clean-failures`` - Delete .exp and .out files from prior failed tests
+* ``--run-failures`` - Re-run only previously failed tests
+
+**Examples:**
+
+.. code-block:: bash
+
+ # Run only basic tests with native emitter
+ $ ./run-tests.py --emit native -d basics extmod
+
+ # Run tests excluding async functionality
+ $ ./run-tests.py -e async
+
+ # Run tests matching *_pep_*
+ $ ./run-tests.py -i *_pep_*
+
+ # Run specific test files in parallel
+ $ ./run-tests.py -j 4 basics/list*.py
+
+ # Test on connected ESP32 board
+ $ ./run-tests.py -t /dev/ttyUSB0
+ # or
+ $ ./run-tests.py -t u0
+
+ # Re-run only failed tests from previous run
+ $ ./run-tests.py --run-failures
diff --git a/docs/differences/python_36.rst b/docs/differences/python_36.rst
index 3315b0594da..18da79f8f84 100644
--- a/docs/differences/python_36.rst
+++ b/docs/differences/python_36.rst
@@ -25,7 +25,8 @@ Python 3.6 beta 1 was released on 12 Sep 2016, and a summary of the new features
+--------------------------------------------------------+--------------------------------------------------+-----------------+
| `PEP 468 `_ | Preserving the order of *kwargs* in a function | |
+--------------------------------------------------------+--------------------------------------------------+-----------------+
- | `PEP 487 `_ | Simpler customization of class creation | |
+ | `PEP 487 `_ | Simpler customization of class creation | Partial |
+ | | | [#setname]_ |
+--------------------------------------------------------+--------------------------------------------------+-----------------+
| `PEP 520 `_ | Preserving Class Attribute Definition Order | |
+--------------------------------------------------------+--------------------------------------------------+-----------------+
@@ -198,3 +199,7 @@ Changes to built-in modules:
+--------------------------------------------------------------------------------------------------------------+----------------+
| The *compress()* and *decompress()* functions now accept keyword arguments | |
+--------------------------------------------------------------------------------------------------------------+----------------+
+
+.. rubric:: Notes
+
+.. [#setname] Currently, only :func:`__set_name__` is implemented.
diff --git a/docs/esp32/quickref.rst b/docs/esp32/quickref.rst
index 3ab4e8f5ecd..b4961fd4ed4 100644
--- a/docs/esp32/quickref.rst
+++ b/docs/esp32/quickref.rst
@@ -79,34 +79,34 @@ Networking
WLAN
^^^^
-The :mod:`network` module::
+The :class:`network.WLAN` class in the :mod:`network` module::
import network
- wlan = network.WLAN(network.STA_IF) # create station interface
- wlan.active(True) # activate the interface
- wlan.scan() # scan for access points
- wlan.isconnected() # check if the station is connected to an AP
+ wlan = network.WLAN() # create station interface (the default, see below for an access point interface)
+ wlan.active(True) # activate the interface
+ wlan.scan() # scan for access points
+ wlan.isconnected() # check if the station is connected to an AP
wlan.connect('ssid', 'key') # connect to an AP
- wlan.config('mac') # get the interface's MAC address
- wlan.ipconfig('addr4') # get the interface's IPv4 addresses
+ wlan.config('mac') # get the interface's MAC address
+ wlan.ipconfig('addr4') # get the interface's IPv4 addresses
- ap = network.WLAN(network.AP_IF) # create access-point interface
- ap.config(ssid='ESP-AP') # set the SSID of the access point
- ap.config(max_clients=10) # set how many clients can connect to the network
- ap.active(True) # activate the interface
+ ap = network.WLAN(network.WLAN.IF_AP) # create access-point interface
+ ap.config(ssid='ESP-AP') # set the SSID of the access point
+ ap.config(max_clients=10) # set how many clients can connect to the network
+ ap.active(True) # activate the interface
A useful function for connecting to your local WiFi network is::
def do_connect():
- import network
- wlan = network.WLAN(network.STA_IF)
+ import machine, network
+ wlan = network.WLAN()
wlan.active(True)
if not wlan.isconnected():
print('connecting to network...')
wlan.connect('ssid', 'key')
while not wlan.isconnected():
- pass
+ machine.idle()
print('network config:', wlan.ipconfig('addr4'))
Once the network is established the :mod:`socket ` module can be used
@@ -121,10 +121,20 @@ calling ``wlan.config(reconnects=n)``, where n are the number of desired reconne
attempts (0 means it won't retry, -1 will restore the default behaviour of trying
to reconnect forever).
+.. _esp32_network_lan:
+
LAN
^^^
-To use the wired interfaces one has to specify the pins and mode ::
+Built-in MAC (original ESP32)
+"""""""""""""""""""""""""""""
+
+The original ESP32 SoC has a built-in Ethernet MAC. Using this MAC requires an
+external Ethernet PHY to be wired to the chip's EMAC pins. Most of the EMAC pin
+assignments are fixed, consult the ESP32 datasheet for details.
+
+If the PHY is connected, the internal Ethernet MAC can be configured via
+the :class:`network.LAN` constructor::
import network
@@ -133,20 +143,34 @@ To use the wired interfaces one has to specify the pins and mode ::
lan.ipconfig('addr4') # get the interface's IPv4 addresses
-The keyword arguments for the constructor defining the PHY type and interface are:
+Required keyword arguments for the constructor:
+
+- ``mdc`` and ``mdio`` - :class:`machine.Pin` objects (or integers) specifying
+ the MDC and MDIO pins.
+- ``phy_type`` - Select the PHY device type. Supported devices are
+ ``PHY_GENERIC``,
+ ``PHY_LAN8710``, ``PHY_LAN8720``, ``PHY_IP101``, ``PHY_RTL8201``,
+ ``PHY_DP83848``, ``PHY_KSZ8041`` and ``PHY_KSZ8081``. These values are all
+ constants defined in the ``network`` module.
+- ``phy_addr`` - The address number of the PHY device. Must be an integer in the
+ range 0x00 to 0x1f, inclusive. Common values are ``0`` and ``1``.
+
+All of the above keyword arguments must be present to configure the interface.
+
+Optional keyword arguments:
-- mdc=pin-object # set the mdc and mdio pins.
-- mdio=pin-object
-- reset=pin-object # set the reset pin of the PHY device.
-- power=pin-object # set the pin which switches the power of the PHY device.
-- phy_type= # Select the PHY device type. Supported devices are PHY_LAN8710,
- PHY_LAN8720, PH_IP101, PHY_RTL8201, PHY_DP83848 and PHY_KSZ8041
-- phy_addr=number # The address number of the PHY device.
-- ref_clk_mode=mode # Defines, whether the ref_clk at the ESP32 is an input
- or output. Suitable values are Pin.IN and Pin.OUT.
-- ref_clk=pin-object # defines the Pin used for ref_clk.
+- ``reset`` - :class:`machine.Pin` object (or integer) specifying the PHY reset pin.
+- ``power`` - :class:`machine.Pin` object (or integer) specifying a pin which
+ switches the power of the PHY device.
+- ``ref_clk`` - :class:`machine.Pin` object (or integer) specifying the pin used
+ for the EMAC ``ref_clk`` signal. If not specified, the board default is used
+ (typically GPIO 0, but may be different if a particular board has Ethernet.)
+- ``ref_clk_mode`` - Defines whether the EMAC ``ref_clk`` pin of the ESP32
+ should be an input or an output. Suitable values are ``machine.Pin.IN`` and
+ ``machine.Pin.OUT``. If not specified, the board default is used
+ (typically input, but may be different if a particular board has Ethernet.)
-These are working configurations for LAN interfaces of popular boards::
+These are working configurations for LAN interfaces of some popular ESP32 boards::
# Olimex ESP32-GATEWAY: power controlled by Pin(5)
# Olimex ESP32 PoE and ESP32-PoE ISO: power controlled by Pin(12)
@@ -171,6 +195,66 @@ These are working configurations for LAN interfaces of popular boards::
lan = network.LAN(id=0, mdc=Pin(23), mdio=Pin(18), power=Pin(5),
phy_type=network.PHY_IP101, phy_addr=1)
+
+.. _esp32_spi_ethernet:
+
+SPI Ethernet Interface
+""""""""""""""""""""""
+
+All ESP32 SoCs support external SPI Ethernet interface chips. These are Ethernet
+interfaces that connect via a SPI bus, rather than an Ethernet RMII interface.
+
+.. note:: The only exception is the ESP32 ``d2wd`` variant, where this feature is disabled
+ to save code size.
+
+SPI Ethernet uses the same :class:`network.LAN` constructor, with a different
+set of keyword arguments::
+
+ import machine, network
+
+ spi = machine.SPI(1, sck=SCK_PIN, mosi=MOSI_PIN, miso=MISO_PIN)
+ lan = network.LAN(spi=spi, cs=CS_PIN, ...) # Set the pin and mode configuration
+ lan.active(True) # activate the interface
+ lan.ipconfig('addr4') # get the interface's IPv4 addresses
+
+Required keyword arguments for the constructor:
+
+- ``spi`` - Should be a :class:`machine.SPI` object configured for this
+ connection. Note that any clock speed configured on the SPI object is ignored,
+ the SPI Ethernet clock speed is configured at compile time.
+- ``cs`` - :class:`machine.Pin` object (or integer) specifying the CS pin
+ connected to the interface.
+- ``int`` - :class:`machine.Pin` object (or integer) specifying the INT pin
+ connected to the interface.
+- ``phy_type`` - Select the SPI Ethernet interface type. Supported devices are
+ ``PHY_KSZ8851SNL``, ``PHY_DM9051``, ``PHY_W5500``. These values are all
+ constants defined in the ``network`` module.
+- ``phy_addr`` - The address number of the PHY device. Must be an integer in the
+ range 0x00 to 0x1f, inclusive. This is usually ``0`` for SPI Ethernet devices.
+
+All of the above keyword arguments must be present to configure the interface.
+
+Optional keyword arguments for the constructor:
+
+- ``reset`` - :class:`machine.Pin` object (or integer) specifying the SPI Ethernet
+ interface reset pin.
+- ``power`` - :class:`machine.Pin` object (or integer) specifying a pin which
+ switches the power of the SPI Ethernet interface.
+
+Here is a sample configuration for a WIZNet W5500 chip connected to pins on
+an ESP32-S3 development board::
+
+ import machine, network
+ from machine import Pin, SPI
+
+ spi = SPI(1, sck=Pin(12), mosi=Pin(13), miso=Pin(14))
+ lan = network.LAN(spi=spi, phy_type=network.PHY_W5500, phy_addr=0,
+ cs=Pin(10), int=Pin(11))
+
+.. note:: WIZnet W5500 Ethernet is also supported on some other MicroPython
+ ports, but using a :ref:`different software interface
+ `.
+
Delay and timing
----------------
@@ -187,8 +271,10 @@ Use the :mod:`time