summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Epler <jepler@gmail.com>2025-08-08 10:09:13 -0500
committerDamien George <damien@micropython.org>2025-09-15 14:53:32 +1000
commitf0c6f16b9eeedc11f3b042704109fddb9aa3532f (patch)
tree49c6d1923e0f5f488ce589c300e6df19e0176226
parentd441788975a6dfb277ad9a3d54d651ae48817d16 (diff)
all: Remove Python 2.7 support.
Python 2.7 has been EOL since January 2020. Ubuntu oldoldlts (Focal Fossa, 20.04) has Python 3.8. Debian oldoldstable (Buster, from 2019) has Python 3.7. RHEL 8 (from 2019) has Python 3.6. It's easier than ever to install a modern Python using uv. Given this, it seems like a fine idea to drop Python 2.7 support. Even though the build is not tested on Python as old as 3.3, I left comments stating that "3.3+" is the baseline Python version. However, it might make sense to bump this to e.g., 3.10, the oldest Python 3 version used during CI. Or, using uv or another method actually test on the oldest Python interpreter that is desirable to support (uv goes back to Python 3.7 easily; in October 2025, the oldest supported Python interpreter version will be 3.10) Signed-off-by: Jeff Epler <jepler@gmail.com>
-rw-r--r--.github/workflows/mpy_format.yml2
-rw-r--r--.github/workflows/ports_unix.yml4
-rw-r--r--README.md5
-rw-r--r--docs/develop/gettingstarted.rst2
-rw-r--r--ports/stm32/boards/pllvalues.py5
-rw-r--r--ports/stm32/make-stmconst.py24
-rw-r--r--py/makeqstrdata.py11
-rw-r--r--py/makeqstrdefs.py2
-rw-r--r--py/makeversionhdr.py14
-rwxr-xr-xtools/ci.sh11
-rwxr-xr-xtools/mpy-tool.py38
-rwxr-xr-xtools/pydfu.py6
12 files changed, 31 insertions, 93 deletions
diff --git a/.github/workflows/mpy_format.yml b/.github/workflows/mpy_format.yml
index 4043b6328..9d3cd139e 100644
--- a/.github/workflows/mpy_format.yml
+++ b/.github/workflows/mpy_format.yml
@@ -15,7 +15,7 @@ concurrency:
jobs:
test:
- runs-on: ubuntu-22.04 # use 22.04 to get python2
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Install packages
diff --git a/.github/workflows/ports_unix.yml b/.github/workflows/ports_unix.yml
index 8fd8e1aec..20a0e8796 100644
--- a/.github/workflows/ports_unix.yml
+++ b/.github/workflows/ports_unix.yml
@@ -121,7 +121,7 @@ jobs:
run: tests/run-tests.py --print-failures
nanbox:
- runs-on: ubuntu-22.04 # use 22.04 to get python2, and libffi-dev:i386
+ runs-on: ubuntu-22.04 # use 22.04 to get libffi-dev:i386
steps:
- uses: actions/checkout@v5
- name: Install packages
@@ -135,7 +135,7 @@ jobs:
run: tests/run-tests.py --print-failures
longlong:
- runs-on: ubuntu-22.04 # use 22.04 to get python2, and libffi-dev:i386
+ runs-on: ubuntu-22.04 # use 22.04 to get libffi-dev:i386
steps:
- uses: actions/checkout@v5
- name: Install packages
diff --git a/README.md b/README.md
index c78a23846..9025da644 100644
--- a/README.md
+++ b/README.md
@@ -80,9 +80,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
-----------------------------------
diff --git a/docs/develop/gettingstarted.rst b/docs/develop/gettingstarted.rst
index fed632ea1..329d218a8 100644
--- a/docs/develop/gettingstarted.rst
+++ b/docs/develop/gettingstarted.rst
@@ -106,7 +106,7 @@ See the `ARM GCC
toolchain <https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads>`_
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
diff --git a/ports/stm32/boards/pllvalues.py b/ports/stm32/boards/pllvalues.py
index ae042d999..987b784a6 100644
--- a/ports/stm32/boards/pllvalues.py
+++ b/ports/stm32/boards/pllvalues.py
@@ -105,7 +105,7 @@ def compute_pll2(hse, sys, relax_pll48):
# VCO_OUT must be between 192MHz and 432MHz
if sys * P not in mcu.range_vco_out:
continue
- NbyM = float(sys * P) / hse # float for Python 2
+ NbyM = sys * P / hse
# scan M
M_min = mcu.range_n[0] // int(round(NbyM)) # starting value
while mcu.range_vco_in[-1] * M_min < hse:
@@ -121,7 +121,7 @@ def compute_pll2(hse, sys, relax_pll48):
# N is restricted
if N not in mcu.range_n:
continue
- Q = float(sys * P) / 48 # float for Python 2
+ Q = sys * P / 48
# Q must be an integer in a set range
if close_int(Q) and round(Q) in mcu.range_q:
# found valid values
@@ -142,7 +142,6 @@ def compute_pll2(hse, sys, relax_pll48):
def compute_derived(hse, pll):
- hse = float(hse) # float for Python 2
M, N, P, Q = pll
vco_in = hse / M
vco_out = hse * N / M
diff --git a/ports/stm32/make-stmconst.py b/ports/stm32/make-stmconst.py
index 4ef6143bd..ff84977ad 100644
--- a/ports/stm32/make-stmconst.py
+++ b/ports/stm32/make-stmconst.py
@@ -9,25 +9,13 @@ from __future__ import print_function
import argparse
import re
-# Python 2/3 compatibility
-import platform
-if platform.python_version_tuple()[0] == "2":
-
- def convert_bytes_to_str(b):
- return b
-
-elif platform.python_version_tuple()[0] == "3":
-
- def convert_bytes_to_str(b):
- try:
- return str(b, "utf8")
- except ValueError:
- # some files have invalid utf8 bytes, so filter them out
- return "".join(chr(l) for l in b if l <= 126)
-
-
-# end compatibility code
+def convert_bytes_to_str(b):
+ try:
+ return str(b, "utf8")
+ except ValueError:
+ # some files have invalid utf8 bytes, so filter them out
+ return "".join(chr(l) for l in b if l <= 126)
# given a list of (name,regex) pairs, find the first one that matches the given line
diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py
index 3a9c7aff5..8cd9bdc70 100644
--- a/py/makeqstrdata.py
+++ b/py/makeqstrdata.py
@@ -1,7 +1,7 @@
"""
Process raw qstr file and output qstr data with length, hash and data bytes.
-This script works with Python 2.6, 2.7, 3.3 and 3.4.
+This script works with Python 3.3+.
"""
from __future__ import print_function
@@ -9,13 +9,7 @@ from __future__ import print_function
import re
import sys
-# Python 2/3/MicroPython compatibility:
-# - iterating through bytes is different
-# - codepoint2name from html.entities is hard-coded
-if sys.version_info[0] == 2:
- bytes_cons = lambda val, enc=None: bytearray(val)
-elif sys.version_info[0] == 3: # Also handles MicroPython
- bytes_cons = bytes
+bytes_cons = bytes
# fmt: off
codepoint2name = {
@@ -57,7 +51,6 @@ codepoint2name = {
253: "yacute", 165: "yen", 255: "yuml", 950: "zeta", 8205: "zwj", 8204: "zwnj"
}
# fmt: on
-# end compatibility code
codepoint2name[ord("-")] = "hyphen"
diff --git a/py/makeqstrdefs.py b/py/makeqstrdefs.py
index 8e930ef50..3f53e1ff3 100644
--- a/py/makeqstrdefs.py
+++ b/py/makeqstrdefs.py
@@ -2,7 +2,7 @@
This script processes the output from the C preprocessor and extracts all
qstr. Each qstr is transformed into a qstr definition of the form 'Q(...)'.
-This script works with Python 2.6, 2.7, 3.3 and 3.4.
+This script works with Python 3.3+.
"""
from __future__ import print_function
diff --git a/py/makeversionhdr.py b/py/makeversionhdr.py
index 5c73501b3..aec95f08e 100644
--- a/py/makeversionhdr.py
+++ b/py/makeversionhdr.py
@@ -1,7 +1,7 @@
"""
Generate header file with macros defining MicroPython version info.
-This script works with Python 2.6, 2.7, 3.3 and 3.4.
+This script works with Python 3.3+.
"""
from __future__ import print_function
@@ -22,12 +22,6 @@ import subprocess
# "vX.Y.Z-preview.N.gHASH.dirty" -- building at any subsequent commit in the cycle
# with local changes
def get_version_info_from_git(repo_path):
- # Python 2.6 doesn't have check_output, so check for that
- try:
- subprocess.check_output
- except AttributeError:
- return None
-
# Note: git describe doesn't work if no tag is available
try:
git_tag = subprocess.check_output(
@@ -57,12 +51,6 @@ def get_version_info_from_git(repo_path):
def get_hash_from_git(repo_path):
- # Python 2.6 doesn't have check_output, so check for that.
- try:
- subprocess.check_output
- except AttributeError:
- return None
-
try:
return subprocess.check_output(
["git", "rev-parse", "--short", "HEAD"],
diff --git a/tools/ci.sh b/tools/ci.sh
index 69e595087..901059991 100755
--- a/tools/ci.sh
+++ b/tools/ci.sh
@@ -130,15 +130,12 @@ function ci_code_size_build {
function ci_mpy_format_setup {
sudo apt-get update
- sudo apt-get install python2.7
sudo pip3 install pyelftools
- python2.7 --version
python3 --version
}
function ci_mpy_format_test {
# Test mpy-tool.py dump feature on bytecode
- python2.7 ./tools/mpy-tool.py -xd tests/frozen/frozentest.mpy
python3 ./tools/mpy-tool.py -xd tests/frozen/frozentest.mpy
# Build MicroPython
@@ -683,12 +680,11 @@ function ci_unix_coverage_run_native_mpy_tests {
function ci_unix_32bit_setup {
sudo dpkg --add-architecture i386
sudo apt-get update
- sudo apt-get install gcc-multilib g++-multilib libffi-dev:i386 python2.7
+ sudo apt-get install gcc-multilib g++-multilib libffi-dev:i386
sudo pip3 install setuptools
sudo pip3 install pyelftools
sudo pip3 install ar
gcc --version
- python2.7 --version
python3 --version
}
@@ -706,13 +702,12 @@ function ci_unix_coverage_32bit_run_native_mpy_tests {
}
function ci_unix_nanbox_build {
- # Use Python 2 to check that it can run the build scripts
- ci_unix_build_helper PYTHON=python2.7 VARIANT=nanbox CFLAGS_EXTRA="-DMICROPY_PY_MATH_CONSTANTS=1"
+ ci_unix_build_helper VARIANT=nanbox CFLAGS_EXTRA="-DMICROPY_PY_MATH_CONSTANTS=1"
ci_unix_build_ffi_lib_helper gcc -m32
}
function ci_unix_nanbox_run_tests {
- ci_unix_run_tests_full_no_native_helper nanbox PYTHON=python2.7
+ ci_unix_run_tests_full_no_native_helper nanbox
}
function ci_unix_longlong_build {
diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py
index 5c63f5be6..c87c656ff 100755
--- a/tools/mpy-tool.py
+++ b/tools/mpy-tool.py
@@ -24,41 +24,21 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
-# Python 2/3/MicroPython compatibility code
-from __future__ import print_function
+import struct
import sys
+from binascii import hexlify
-if sys.version_info[0] == 2:
- from binascii import hexlify as hexlify_py2
-
- str_cons = lambda val, enc=None: str(val)
- bytes_cons = lambda val, enc=None: bytearray(val)
- is_str_type = lambda o: isinstance(o, str)
- is_bytes_type = lambda o: type(o) is bytearray
- is_int_type = lambda o: isinstance(o, int) or isinstance(o, long) # noqa: F821
-
- def hexlify_to_str(b):
- x = hexlify_py2(b)
- return ":".join(x[i : i + 2] for i in range(0, len(x), 2))
-
-elif sys.version_info[0] == 3: # Also handles MicroPython
- from binascii import hexlify
+str_cons = str
+bytes_cons = bytes
+is_str_type = lambda o: isinstance(o, str)
+is_bytes_type = lambda o: isinstance(o, bytes)
+is_int_type = lambda o: isinstance(o, int)
- str_cons = str
- bytes_cons = bytes
- is_str_type = lambda o: isinstance(o, str)
- is_bytes_type = lambda o: isinstance(o, bytes)
- is_int_type = lambda o: isinstance(o, int)
- def hexlify_to_str(b):
- return str(hexlify(b, ":"), "ascii")
+def hexlify_to_str(b):
+ return str(hexlify(b, ":"), "ascii")
-# end compatibility code
-
-import sys
-import struct
-
sys.path.append(sys.path[0] + "/../py")
import makeqstrdata as qstrutil
diff --git a/tools/pydfu.py b/tools/pydfu.py
index cd7354818..8822b07be 100755
--- a/tools/pydfu.py
+++ b/tools/pydfu.py
@@ -75,11 +75,7 @@ __verbose = None
# USB DFU interface
__DFU_INTERFACE = 0
-# Python 3 deprecated getargspec in favour of getfullargspec, but
-# Python 2 doesn't have the latter, so detect which one to use
-getargspec = getattr(inspect, "getfullargspec", getattr(inspect, "getargspec", None))
-
-if "length" in getargspec(usb.util.get_string).args:
+if "length" in inspect.getfullargspec(usb.util.get_string).args:
# PyUSB 1.0.0.b1 has the length argument
def get_string(dev, index):
return usb.util.get_string(dev, 255, index)