Skip to content

Commit c208f70

Browse files
Start on improving Python project structure
1 parent b0e45dd commit c208f70

File tree

165 files changed

+108
-33
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

165 files changed

+108
-33
lines changed

tools/cmake/mbed_python_interpreter.cmake

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,54 @@
66

77
option(MBED_CREATE_PYTHON_VENV "If true, Mbed OS will create its own virtual environment (venv) and install its Python packages there. This removes the need to manually install Python packages." TRUE)
88

9+
get_filename_component(MBED_CE_TOOLS_BASE_DIR "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE)
10+
911
if(MBED_CREATE_PYTHON_VENV)
1012
# Use the venv.
1113

1214
# Note: venv is stored in the source directory as it can be shared between all the build directories
1315
# (not target specific)
1416
set(MBED_VENV_LOCATION ${MBED_SOURCE_DIR}/venv)
1517
set(VENV_STAMP_FILE ${MBED_VENV_LOCATION}/mbed-venv.stamp)
16-
set(MBED_REQUIREMENTS_TXT_LOCATION "${CMAKE_CURRENT_LIST_DIR}/../requirements.txt")
18+
set(MBED_PYPROJECT_TOML_LOCATION "${MBED_CE_TOOLS_BASE_DIR}/pyproject.toml")
1719

18-
# Make it so modifying requirements.txt will trigger a reconfigure
19-
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${MBED_REQUIREMENTS_TXT_LOCATION})
20+
# Make it so modifying pyproject.toml will trigger a reconfigure
21+
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${MBED_PYPROJECT_TOML_LOCATION})
2022

21-
# Find Python3, using the venv if it already exists
22-
set (ENV{VIRTUAL_ENV} ${MBED_VENV_LOCATION})
23-
set (Python3_FIND_VIRTUALENV FIRST)
24-
find_package(Python3 REQUIRED COMPONENTS Interpreter)
23+
# Find Python3 (this will get the one in the venv if we already found it)
24+
set(ENV{VIRTUAL_ENV} ${MBED_VENV_LOCATION})
25+
set(Python3_FIND_VIRTUALENV FIRST)
26+
find_package(Python3 COMPONENTS Interpreter)
2527
include(CheckPythonPackage)
2628

2729
set(NEED_TO_CREATE_VENV FALSE)
2830
set(NEED_TO_INSTALL_PACKAGES FALSE)
29-
if(NOT EXISTS "${VENV_STAMP_FILE}")
31+
32+
# Special situation: if we have a cached interpreter location in the venv dir, but Python could be found,
33+
# this means that the venv was deleted or symlinks to a missing python install location.
34+
# So, use the system python and recreate it.
35+
if("${Python3_EXECUTABLE}" MATCHES "${MBED_VENV_LOCATION}" AND NOT Python3_FOUND)
36+
message(STATUS "Python venv deleted or unusable. Recreating using system Python...")
37+
38+
# Launch a new search for Python3
39+
unset(Python3_EXECUTABLE)
40+
unset(_Python3_EXECUTABLE CACHE)
41+
unset(_Python3_INTERPRETER_PROPERTIES CACHE)
42+
unset(_Python3_INTERPRETER_SIGNATURE CACHE)
43+
set (Python3_FIND_VIRTUALENV STANDARD)
44+
find_package(Python3 REQUIRED COMPONENTS Interpreter)
45+
46+
set(NEED_TO_CREATE_VENV TRUE)
47+
set(NEED_TO_INSTALL_PACKAGES TRUE)
48+
elseif(NOT EXISTS "${VENV_STAMP_FILE}")
3049
set(NEED_TO_CREATE_VENV TRUE)
3150
set(NEED_TO_INSTALL_PACKAGES TRUE)
32-
elseif("${MBED_REQUIREMENTS_TXT_LOCATION}" IS_NEWER_THAN "${VENV_STAMP_FILE}")
51+
elseif(NOT ("${Python3_EXECUTABLE}" MATCHES "${MBED_VENV_LOCATION}"))
52+
# Alternately if we think we have the venv but FindPython didn't use it, that likely means it's
53+
# missing or corrupted and we need to recreate it
54+
set(NEED_TO_CREATE_VENV TRUE)
55+
set(NEED_TO_INSTALL_PACKAGES TRUE)
56+
elseif("${MBED_PYPROJECT_TOML_LOCATION}" IS_NEWER_THAN "${VENV_STAMP_FILE}")
3357
set(NEED_TO_INSTALL_PACKAGES TRUE)
3458
endif()
3559

@@ -47,7 +71,8 @@ if(MBED_CREATE_PYTHON_VENV)
4771
unset(_Python3_EXECUTABLE CACHE)
4872
unset(_Python3_INTERPRETER_PROPERTIES CACHE)
4973
unset(_Python3_INTERPRETER_SIGNATURE CACHE)
50-
## Launch a new search for Python3
74+
75+
## Launch a new search for Python3 in the venv
5176
find_package (Python3 REQUIRED COMPONENTS Interpreter)
5277
endif()
5378

@@ -59,7 +84,7 @@ if(MBED_CREATE_PYTHON_VENV)
5984
COMMAND_ERROR_IS_FATAL ANY
6085
)
6186
execute_process(
62-
COMMAND ${Python3_EXECUTABLE} -m pip install -r ${MBED_REQUIREMENTS_TXT_LOCATION}
87+
COMMAND ${Python3_EXECUTABLE} -m pip install ${MBED_CE_TOOLS_BASE_DIR}
6388
COMMAND_ERROR_IS_FATAL ANY
6489
)
6590

@@ -75,25 +100,12 @@ else()
75100
find_package(Python3 REQUIRED COMPONENTS Interpreter)
76101
include(CheckPythonPackage)
77102

103+
# The cmsis_mcu_descr module was written from scratch by Mbed CE.
104+
# So, this check will ensure that the user has installed the Mbed CE version of mbed_tools
105+
# and not the PyPI version (which we cannot do anything with because it's owned by ARM)
106+
check_python_package(mbed_tools.cli.cmsis_mcu_descr HAVE_MBED_CE_TOOLS)
78107

79-
# Check python packages
80-
set(PYTHON_PACKAGES_TO_CHECK intelhex prettytable future jinja2)
81-
foreach(PACKAGE_NAME ${PYTHON_PACKAGES_TO_CHECK})
82-
string(TOUPPER ${PACKAGE_NAME} PACKAGE_NAME_UCASE) # Ucase name needed for CMake variable
83-
string(TOLOWER ${PACKAGE_NAME} PACKAGE_NAME_LCASE) # Lcase name needed for import statement
84-
85-
check_python_package(${PACKAGE_NAME_LCASE} HAVE_PYTHON_${PACKAGE_NAME_UCASE})
86-
if(NOT HAVE_PYTHON_${PACKAGE_NAME_UCASE})
87-
message(WARNING "Missing Python dependency ${PACKAGE_NAME}")
88-
endif()
89-
endforeach()
90-
91-
# Check deps for memap
92-
if(Python3_FOUND AND HAVE_PYTHON_INTELHEX AND HAVE_PYTHON_PRETTYTABLE)
93-
set(HAVE_MEMAP_DEPS TRUE)
94-
else()
95-
set(HAVE_MEMAP_DEPS FALSE)
96-
message(STATUS "Missing Python dependencies (at least one of: python3, intelhex, prettytable) so the memory map cannot be printed")
108+
if(NOT HAVE_MBED_CE_TOOLS)
109+
message(FATAL_ERROR "Did not detect the Mbed CE Python tools installed into the python interpreter ${Python3_EXECUTABLE}. Install them with a command like: ${Python3_EXECUTABLE} -m pip install ${MBED_CE_TOOLS_BASE_DIR}")
97110
endif()
98-
99111
endif()

tools/pyproject.toml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
[build-system]
2+
requires = ["hatchling"]
3+
build-backend = "hatchling.build"
4+
5+
[project]
6+
name = "mbed-ce-tools"
7+
version = "0.0.1"
8+
description = 'Tools for building and testing Mbed OS Community Edition'
9+
requires-python = ">=3.8"
10+
license = "Apache-2.0"
11+
dependencies = [
12+
# memap dependencies ---------------------------------------------------------------------
13+
"intelhex>=2.3.0,<3.0.0",
14+
15+
# 3.12.0 both added HRuleStyle and deprecated the old constants in one single release :/
16+
"prettytable>=2.0,<3.12.0; python_version < '3.9'",
17+
"prettytable>=3.12.0; python_version >= '3.9'",
18+
19+
# mbed_tools dependencies ----------------------------------------------------------------
20+
"jinja2>=2.11.3",
21+
"python-dotenv",
22+
"Click>=7.1",
23+
"GitPython",
24+
"tqdm",
25+
"tabulate",
26+
"requests>=2.20",
27+
"typing-extensions",
28+
"pyserial",
29+
"appdirs",
30+
"pyjson5>=1.6",
31+
"humanize>=4.9.0",
32+
33+
# Needed for downloading CMSIS MCU descriptions
34+
"cmsis-pack-manager>=0.5.0",
35+
36+
# USB device detection on Mac
37+
"pywin32; platform_system=='Windows'",
38+
39+
# USB device detection on Linux
40+
"psutil; platform_system=='Linux'",
41+
"pyudev; platform_system=='Linux'",
42+
43+
# USB device detection on Mac
44+
"beautifulsoup4; sys_platform == 'darwin'",
45+
"lxml; sys_platform == 'darwin'",
46+
47+
# mbed_os_tools.test dependencies ---------------------------------------------------------
48+
"junit-xml>=1.0",
49+
"lockfile",
50+
"colorama",
51+
52+
# needed for signing secure images --------------------------------------------------------
53+
"cryptography",
54+
"cbor",
55+
"cysecuretools~=6.0",
56+
]
57+
58+
[tool.hatch.build.targets.wheel]
59+
packages = ["python"]
60+
61+
[project.scripts]
62+
memap = "memap.memap:main"

tools/python/mbed_os_tools/test/host_tests/base_host_test.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
# limitations under the License.
1515

1616
import inspect
17-
import six
1817
from time import time
1918
from inspect import isfunction, ismethod
2019

@@ -227,15 +226,15 @@ def register_callback(self, key, callback, force=False):
227226
# Check if callback has all three required parameters (key, value, timestamp)
228227
# When callback is class method should have 4 arguments (self, key, value, timestamp)
229228
if ismethod(callback):
230-
arg_count = six.get_function_code(callback).co_argcount
229+
arg_count = callback.__code__.co_argcount
231230
if arg_count != 4:
232231
err_msg = "callback 'self.%s('%s', ...)' defined with %d arguments"% (callback.__name__, key, arg_count)
233232
err_msg += ", should have 4 arguments: self.%s(self, key, value, timestamp)"% callback.__name__
234233
raise TypeError(err_msg)
235234

236235
# When callback is just a function should have 3 arguments func(key, value, timestamp)
237236
if isfunction(callback):
238-
arg_count = six.get_function_code(callback).co_argcount
237+
arg_count = callback.__code__.co_argcount
239238
if arg_count != 3:
240239
err_msg = "callback '%s('%s', ...)' defined with %d arguments"% (callback.__name__, key, arg_count)
241240
err_msg += ", should have 3 arguments: %s(key, value, timestamp)"% callback.__name__
File renamed without changes.

0 commit comments

Comments
 (0)