general: 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>
This commit is contained in:
parent
593ae04eeb
commit
d2817bb168
12 changed files with 35 additions and 93 deletions
2
.github/workflows/mpy_format.yml
vendored
2
.github/workflows/mpy_format.yml
vendored
|
|
@ -15,7 +15,7 @@ concurrency:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
runs-on: ubuntu-22.04 # use 22.04 to get python2
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Install packages
|
- name: Install packages
|
||||||
|
|
|
||||||
4
.github/workflows/ports_unix.yml
vendored
4
.github/workflows/ports_unix.yml
vendored
|
|
@ -121,7 +121,7 @@ jobs:
|
||||||
run: tests/run-tests.py --print-failures
|
run: tests/run-tests.py --print-failures
|
||||||
|
|
||||||
nanbox:
|
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:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Install packages
|
- name: Install packages
|
||||||
|
|
@ -135,7 +135,7 @@ jobs:
|
||||||
run: tests/run-tests.py --print-failures
|
run: tests/run-tests.py --print-failures
|
||||||
|
|
||||||
longlong:
|
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:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Install packages
|
- name: Install packages
|
||||||
|
|
|
||||||
|
|
@ -80,9 +80,8 @@ This repository contains the following components:
|
||||||
- [examples/](examples/) -- a few example Python scripts.
|
- [examples/](examples/) -- a few example Python scripts.
|
||||||
|
|
||||||
"make" is used to build the components, or "gmake" on BSD-based systems.
|
"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`
|
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
|
Some ports (rp2 and esp32) additionally use CMake.
|
||||||
`PYTHON=python2`). Some ports (rp2 and esp32) additionally use CMake.
|
|
||||||
|
|
||||||
Supported platforms & architectures
|
Supported platforms & architectures
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ See the `ARM GCC
|
||||||
toolchain <https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads>`_
|
toolchain <https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads>`_
|
||||||
for the latest details.
|
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:
|
Check that you have Python available on your system:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ def compute_pll2(hse, sys, relax_pll48):
|
||||||
# VCO_OUT must be between 192MHz and 432MHz
|
# VCO_OUT must be between 192MHz and 432MHz
|
||||||
if sys * P not in mcu.range_vco_out:
|
if sys * P not in mcu.range_vco_out:
|
||||||
continue
|
continue
|
||||||
NbyM = float(sys * P) / hse # float for Python 2
|
NbyM = sys * P / hse
|
||||||
# scan M
|
# scan M
|
||||||
M_min = mcu.range_n[0] // int(round(NbyM)) # starting value
|
M_min = mcu.range_n[0] // int(round(NbyM)) # starting value
|
||||||
while mcu.range_vco_in[-1] * M_min < hse:
|
while mcu.range_vco_in[-1] * M_min < hse:
|
||||||
|
|
@ -121,7 +121,7 @@ def compute_pll2(hse, sys, relax_pll48):
|
||||||
# N is restricted
|
# N is restricted
|
||||||
if N not in mcu.range_n:
|
if N not in mcu.range_n:
|
||||||
continue
|
continue
|
||||||
Q = float(sys * P) / 48 # float for Python 2
|
Q = sys * P / 48
|
||||||
# Q must be an integer in a set range
|
# Q must be an integer in a set range
|
||||||
if close_int(Q) and round(Q) in mcu.range_q:
|
if close_int(Q) and round(Q) in mcu.range_q:
|
||||||
# found valid values
|
# found valid values
|
||||||
|
|
@ -142,7 +142,6 @@ def compute_pll2(hse, sys, relax_pll48):
|
||||||
|
|
||||||
|
|
||||||
def compute_derived(hse, pll):
|
def compute_derived(hse, pll):
|
||||||
hse = float(hse) # float for Python 2
|
|
||||||
M, N, P, Q = pll
|
M, N, P, Q = pll
|
||||||
vco_in = hse / M
|
vco_in = hse / M
|
||||||
vco_out = hse * N / M
|
vco_out = hse * N / M
|
||||||
|
|
|
||||||
|
|
@ -9,25 +9,13 @@ from __future__ import print_function
|
||||||
import argparse
|
import argparse
|
||||||
import re
|
import re
|
||||||
|
|
||||||
# Python 2/3 compatibility
|
|
||||||
import platform
|
|
||||||
|
|
||||||
if platform.python_version_tuple()[0] == "2":
|
def convert_bytes_to_str(b):
|
||||||
|
try:
|
||||||
def convert_bytes_to_str(b):
|
return str(b, "utf8")
|
||||||
return b
|
except ValueError:
|
||||||
|
# some files have invalid utf8 bytes, so filter them out
|
||||||
elif platform.python_version_tuple()[0] == "3":
|
return "".join(chr(l) for l in b if l <= 126)
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
# given a list of (name,regex) pairs, find the first one that matches the given line
|
# given a list of (name,regex) pairs, find the first one that matches the given line
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
"""
|
"""
|
||||||
Process raw qstr file and output qstr data with length, hash and data bytes.
|
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
|
from __future__ import print_function
|
||||||
|
|
@ -9,13 +9,7 @@ from __future__ import print_function
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
# Python 2/3/MicroPython compatibility:
|
bytes_cons = bytes
|
||||||
# - 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
|
|
||||||
|
|
||||||
# fmt: off
|
# fmt: off
|
||||||
codepoint2name = {
|
codepoint2name = {
|
||||||
|
|
@ -57,7 +51,6 @@ codepoint2name = {
|
||||||
253: "yacute", 165: "yen", 255: "yuml", 950: "zeta", 8205: "zwj", 8204: "zwnj"
|
253: "yacute", 165: "yen", 255: "yuml", 950: "zeta", 8205: "zwj", 8204: "zwnj"
|
||||||
}
|
}
|
||||||
# fmt: on
|
# fmt: on
|
||||||
# end compatibility code
|
|
||||||
|
|
||||||
codepoint2name[ord("-")] = "hyphen"
|
codepoint2name[ord("-")] = "hyphen"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
This script processes the output from the C preprocessor and extracts all
|
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(...)'.
|
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
|
from __future__ import print_function
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
"""
|
"""
|
||||||
Generate header file with macros defining MicroPython version info.
|
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
|
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
|
# "vX.Y.Z-preview.N.gHASH.dirty" -- building at any subsequent commit in the cycle
|
||||||
# with local changes
|
# with local changes
|
||||||
def get_version_info_from_git(repo_path):
|
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
|
# Note: git describe doesn't work if no tag is available
|
||||||
try:
|
try:
|
||||||
git_tag = subprocess.check_output(
|
git_tag = subprocess.check_output(
|
||||||
|
|
@ -48,12 +42,6 @@ def get_version_info_from_git(repo_path):
|
||||||
|
|
||||||
|
|
||||||
def get_hash_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:
|
try:
|
||||||
return subprocess.check_output(
|
return subprocess.check_output(
|
||||||
["git", "rev-parse", "--short", "HEAD"],
|
["git", "rev-parse", "--short", "HEAD"],
|
||||||
|
|
|
||||||
11
tools/ci.sh
11
tools/ci.sh
|
|
@ -127,15 +127,12 @@ function ci_code_size_build {
|
||||||
|
|
||||||
function ci_mpy_format_setup {
|
function ci_mpy_format_setup {
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install python2.7
|
|
||||||
sudo pip3 install pyelftools
|
sudo pip3 install pyelftools
|
||||||
python2.7 --version
|
|
||||||
python3 --version
|
python3 --version
|
||||||
}
|
}
|
||||||
|
|
||||||
function ci_mpy_format_test {
|
function ci_mpy_format_test {
|
||||||
# Test mpy-tool.py dump feature on bytecode
|
# 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
|
python3 ./tools/mpy-tool.py -xd tests/frozen/frozentest.mpy
|
||||||
|
|
||||||
# Build MicroPython
|
# Build MicroPython
|
||||||
|
|
@ -666,12 +663,11 @@ function ci_unix_coverage_run_native_mpy_tests {
|
||||||
function ci_unix_32bit_setup {
|
function ci_unix_32bit_setup {
|
||||||
sudo dpkg --add-architecture i386
|
sudo dpkg --add-architecture i386
|
||||||
sudo apt-get update
|
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 setuptools
|
||||||
sudo pip3 install pyelftools
|
sudo pip3 install pyelftools
|
||||||
sudo pip3 install ar
|
sudo pip3 install ar
|
||||||
gcc --version
|
gcc --version
|
||||||
python2.7 --version
|
|
||||||
python3 --version
|
python3 --version
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -689,13 +685,12 @@ function ci_unix_coverage_32bit_run_native_mpy_tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
function ci_unix_nanbox_build {
|
function ci_unix_nanbox_build {
|
||||||
# Use Python 2 to check that it can run the build scripts
|
ci_unix_build_helper VARIANT=nanbox CFLAGS_EXTRA="-DMICROPY_PY_MATH_CONSTANTS=1"
|
||||||
ci_unix_build_helper PYTHON=python2.7 VARIANT=nanbox CFLAGS_EXTRA="-DMICROPY_PY_MATH_CONSTANTS=1"
|
|
||||||
ci_unix_build_ffi_lib_helper gcc -m32
|
ci_unix_build_ffi_lib_helper gcc -m32
|
||||||
}
|
}
|
||||||
|
|
||||||
function ci_unix_nanbox_run_tests {
|
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 {
|
function ci_unix_longlong_build {
|
||||||
|
|
|
||||||
|
|
@ -24,40 +24,20 @@
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
# THE SOFTWARE.
|
# THE SOFTWARE.
|
||||||
|
|
||||||
# Python 2/3/MicroPython compatibility code
|
|
||||||
from __future__ import print_function
|
|
||||||
import sys
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
def hexlify_to_str(b):
|
|
||||||
return str(hexlify(b, ":"), "ascii")
|
|
||||||
|
|
||||||
|
|
||||||
# end compatibility code
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import struct
|
import struct
|
||||||
|
import sys
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
def hexlify_to_str(b):
|
||||||
|
return str(hexlify(b, ":"), "ascii")
|
||||||
|
|
||||||
|
|
||||||
sys.path.append(sys.path[0] + "/../py")
|
sys.path.append(sys.path[0] + "/../py")
|
||||||
import makeqstrdata as qstrutil
|
import makeqstrdata as qstrutil
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ __DFU_INTERFACE = 0
|
||||||
|
|
||||||
# Python 3 deprecated getargspec in favour of getfullargspec, but
|
# Python 3 deprecated getargspec in favour of getfullargspec, but
|
||||||
# Python 2 doesn't have the latter, so detect which one to use
|
# Python 2 doesn't have the latter, so detect which one to use
|
||||||
getargspec = getattr(inspect, "getfullargspec", getattr(inspect, "getargspec", None))
|
getargspec = inspect.getfullargspec
|
||||||
|
|
||||||
if "length" in getargspec(usb.util.get_string).args:
|
if "length" in getargspec(usb.util.get_string).args:
|
||||||
# PyUSB 1.0.0.b1 has the length argument
|
# PyUSB 1.0.0.b1 has the length argument
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue