From ab32fc2b5b94c13a3aa832048e70c0373a18d8dd Mon Sep 17 00:00:00 2001 From: foamyguy Date: Thu, 14 Aug 2025 09:25:45 -0500 Subject: [PATCH 1/2] fix subimport finding for auto-files that are not in the root. --- circup/command_utils.py | 34 +++++++++++++++++++++++++++------- tests/mock_device/boot_out.txt | 2 +- tests/test_circup.py | 4 +++- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/circup/command_utils.py b/circup/command_utils.py index a1472d6..1aab0b7 100644 --- a/circup/command_utils.py +++ b/circup/command_utils.py @@ -673,14 +673,15 @@ def imports_from_code(full_content): return sorted(imports) -def get_all_imports( - backend, auto_file_content, mod_names, current_module, visited=None +def get_all_imports( # pylint: disable=too-many-arguments,too-many-locals, too-many-branches + backend, auto_file_content, auto_file_path, mod_names, current_module, visited=None ): """ Recursively retrieve imports from files on the backend :param Backend backend: The current backend object :param str auto_file_content: Content of the python file to analyse + :param str auto_file_path: Path to the python file to analyse :param list mod_names: Lits of supported bundle mod names :param str current_module: Name of the call context module if recursive call :param set visited: Modules previously visited @@ -714,18 +715,35 @@ def get_all_imports( install_module = install # possible files for the module: .py or __init__.py (if directory) file_name = os.path.join(*install_module.split(".")) + ".py" - exists = backend.file_exists(file_name) + try: + file_location = os.path.join( + *auto_file_path.replace(str(backend.device_location), "").split( + "/" + )[:-1] + ) + full_location = os.path.join(file_location, file_name) + except TypeError: + # file is in root of CIRCUITPY + full_location = file_name + + exists = backend.file_exists(full_location) if not exists: file_name = os.path.join(*install_module.split("."), "__init__.py") - exists = backend.file_exists(file_name) + full_location = os.path.join(file_location, file_name) + exists = backend.file_exists(full_location) if not exists: continue install_module += ".__init__" # get the content and parse it recursively - auto_file_content = backend.get_file_content(file_name) + auto_file_content = backend.get_file_content(full_location) if auto_file_content: sub_imports = get_all_imports( - backend, auto_file_content, mod_names, install_module, visited + backend, + auto_file_content, + auto_file_path, + mod_names, + install_module, + visited, ) requested_installs.extend(sub_imports) @@ -775,7 +793,9 @@ def libraries_from_auto_file(backend, auto_file, mod_names): # from file name to module name (in case it's in a subpackage) click.secho(f"Finding imports from: {auto_file}", fg="green") current_module = auto_file.rstrip(".py").replace(os.path.sep, ".") - return get_all_imports(backend, auto_file_content, mod_names, current_module) + return get_all_imports( + backend, auto_file_content, auto_file, mod_names, current_module + ) def get_device_path(host, port, password, path): diff --git a/tests/mock_device/boot_out.txt b/tests/mock_device/boot_out.txt index 38172a5..e829b9d 100644 --- a/tests/mock_device/boot_out.txt +++ b/tests/mock_device/boot_out.txt @@ -1,3 +1,3 @@ -Adafruit CircuitPython 9.0.0 on 2019-08-02; Adafruit CircuitPlayground Express with samd21g18 +Adafruit CircuitPython 10.0.0-alpha.6 on 2019-08-02; Adafruit CircuitPlayground Express with samd21g18 Board ID:this_is_a_board UID:AAAABBBBCCCC diff --git a/tests/test_circup.py b/tests/test_circup.py index fedffb0..b21061d 100644 --- a/tests/test_circup.py +++ b/tests/test_circup.py @@ -1185,7 +1185,9 @@ def test_get_all_imports(): with open(test_file, "r", encoding="utf8") as fp: test_data = fp.read() - result = get_all_imports(backend, test_data, mod_names, current_module="") + result = get_all_imports( + backend, test_data, test_file, mod_names, current_module="" + ) assert result == [ "adafruit_bus_device", From 18a4687739e46baa9818709383d8e652d078867b Mon Sep 17 00:00:00 2001 From: foamyguy Date: Thu, 14 Aug 2025 10:21:11 -0500 Subject: [PATCH 2/2] use 9.x in all test mock devices. Fix package subimport logic. Fix tests. Update from_auto_files_local test to mimic Fruit Jam OS usage. --- circup/command_utils.py | 4 +++- tests/mock_device/apps/test_app/import_styles.py | 11 +++++++++++ tests/mock_device/apps/test_app/import_styles_sub.py | 5 +++++ tests/mock_device/boot_out.txt | 2 +- tests/mock_device/import_styles.py | 11 +++++++++++ tests/mock_device_2/boot_out.txt | 2 +- tests/mock_device_2/import_styles_sub.py | 5 +++++ tests/test_circup.py | 9 +++++++-- 8 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 tests/mock_device/apps/test_app/import_styles.py create mode 100644 tests/mock_device/apps/test_app/import_styles_sub.py create mode 100644 tests/mock_device/import_styles.py create mode 100644 tests/mock_device_2/import_styles_sub.py diff --git a/circup/command_utils.py b/circup/command_utils.py index 1aab0b7..fc8e483 100644 --- a/circup/command_utils.py +++ b/circup/command_utils.py @@ -721,7 +721,9 @@ def get_all_imports( # pylint: disable=too-many-arguments,too-many-locals, too- "/" )[:-1] ) + full_location = os.path.join(file_location, file_name) + except TypeError: # file is in root of CIRCUITPY full_location = file_name @@ -729,7 +731,7 @@ def get_all_imports( # pylint: disable=too-many-arguments,too-many-locals, too- exists = backend.file_exists(full_location) if not exists: file_name = os.path.join(*install_module.split("."), "__init__.py") - full_location = os.path.join(file_location, file_name) + full_location = file_name exists = backend.file_exists(full_location) if not exists: continue diff --git a/tests/mock_device/apps/test_app/import_styles.py b/tests/mock_device/apps/test_app/import_styles.py new file mode 100644 index 0000000..fc78e23 --- /dev/null +++ b/tests/mock_device/apps/test_app/import_styles.py @@ -0,0 +1,11 @@ +# SPDX-FileCopyrightText: 2021 Jeff Epler for Adafruit Industries +# +# SPDX-License-Identifier: MIT +# pylint: disable=all +import os, sys +import adafruit_bus_device +from adafruit_button import Button +from adafruit_esp32spi import adafruit_esp32spi_socketpool +from adafruit_display_text import wrap_text_to_pixels, wrap_text_to_lines +import adafruit_hid.consumer_control +import import_styles_sub diff --git a/tests/mock_device/apps/test_app/import_styles_sub.py b/tests/mock_device/apps/test_app/import_styles_sub.py new file mode 100644 index 0000000..99cab83 --- /dev/null +++ b/tests/mock_device/apps/test_app/import_styles_sub.py @@ -0,0 +1,5 @@ +# SPDX-FileCopyrightText: 2025 Neradoc +# +# SPDX-License-Identifier: MIT +# pylint: disable=all +import adafruit_ntp diff --git a/tests/mock_device/boot_out.txt b/tests/mock_device/boot_out.txt index e829b9d..38172a5 100644 --- a/tests/mock_device/boot_out.txt +++ b/tests/mock_device/boot_out.txt @@ -1,3 +1,3 @@ -Adafruit CircuitPython 10.0.0-alpha.6 on 2019-08-02; Adafruit CircuitPlayground Express with samd21g18 +Adafruit CircuitPython 9.0.0 on 2019-08-02; Adafruit CircuitPlayground Express with samd21g18 Board ID:this_is_a_board UID:AAAABBBBCCCC diff --git a/tests/mock_device/import_styles.py b/tests/mock_device/import_styles.py new file mode 100644 index 0000000..fc78e23 --- /dev/null +++ b/tests/mock_device/import_styles.py @@ -0,0 +1,11 @@ +# SPDX-FileCopyrightText: 2021 Jeff Epler for Adafruit Industries +# +# SPDX-License-Identifier: MIT +# pylint: disable=all +import os, sys +import adafruit_bus_device +from adafruit_button import Button +from adafruit_esp32spi import adafruit_esp32spi_socketpool +from adafruit_display_text import wrap_text_to_pixels, wrap_text_to_lines +import adafruit_hid.consumer_control +import import_styles_sub diff --git a/tests/mock_device_2/boot_out.txt b/tests/mock_device_2/boot_out.txt index 55feaff..38172a5 100644 --- a/tests/mock_device_2/boot_out.txt +++ b/tests/mock_device_2/boot_out.txt @@ -1,3 +1,3 @@ -Adafruit CircuitPython 8.1.0 on 2019-08-02; Adafruit CircuitPlayground Express with samd21g18 +Adafruit CircuitPython 9.0.0 on 2019-08-02; Adafruit CircuitPlayground Express with samd21g18 Board ID:this_is_a_board UID:AAAABBBBCCCC diff --git a/tests/mock_device_2/import_styles_sub.py b/tests/mock_device_2/import_styles_sub.py new file mode 100644 index 0000000..99cab83 --- /dev/null +++ b/tests/mock_device_2/import_styles_sub.py @@ -0,0 +1,5 @@ +# SPDX-FileCopyrightText: 2025 Neradoc +# +# SPDX-License-Identifier: MIT +# pylint: disable=all +import adafruit_ntp diff --git a/tests/test_circup.py b/tests/test_circup.py index b21061d..95e68c0 100644 --- a/tests/test_circup.py +++ b/tests/test_circup.py @@ -1186,7 +1186,11 @@ def test_get_all_imports(): test_data = fp.read() result = get_all_imports( - backend, test_data, test_file, mod_names, current_module="" + backend, + test_data, + os.path.join(backend.device_location, "import_styles.py"), + mod_names, + current_module="", ) assert result == [ @@ -1215,7 +1219,7 @@ def test_libraries_from_auto_file_local(): "adafruit_ntp", ] - auto_file = "./tests/import_styles.py" + auto_file = "apps/test_app/import_styles.py" with mock.patch("circup.logger.info") as mock_logger, mock.patch( "circup.os.path.isfile", return_value=True @@ -1267,6 +1271,7 @@ def test_libraries_from_auto_file_board(): result = libraries_from_auto_file(backend, auto_file, mod_names) assert result == [ + "adafruit_ntp", "adafruit_spd1608", "adafruit_spd1656", "adafruit_ssd1675",