From c5f8b40570e2285f512c1fd304ca8d158684560f Mon Sep 17 00:00:00 2001 From: Dark-Avery Date: Mon, 16 Mar 2026 21:39:04 +0300 Subject: [PATCH] fix(android): normalize Chaquopy Java list inputs for proxy config --- .../src/main/python/android_proxy_bridge.py | 19 ++++++- tests/test_android_proxy_bridge.py | 50 +++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 tests/test_android_proxy_bridge.py diff --git a/android/app/src/main/python/android_proxy_bridge.py b/android/app/src/main/python/android_proxy_bridge.py index 1ade094..144854e 100644 --- a/android/app/src/main/python/android_proxy_bridge.py +++ b/android/app/src/main/python/android_proxy_bridge.py @@ -18,7 +18,24 @@ def _remember_error(message: str) -> None: def _normalize_dc_ip_list(dc_ip_list: Iterable[object]) -> list[str]: - return [str(item).strip() for item in dc_ip_list if str(item).strip()] + if dc_ip_list is None: + return [] + + values: list[object] + try: + values = list(dc_ip_list) + except TypeError: + # Chaquopy may expose Kotlin's List as java.util.ArrayList, + # which isn't always directly iterable from Python. + if hasattr(dc_ip_list, "toArray"): + values = list(dc_ip_list.toArray()) + elif hasattr(dc_ip_list, "size") and hasattr(dc_ip_list, "get"): + size = int(dc_ip_list.size()) + values = [dc_ip_list.get(i) for i in range(size)] + else: + values = [dc_ip_list] + + return [str(item).strip() for item in values if str(item).strip()] def start_proxy(app_dir: str, host: str, port: int, diff --git a/tests/test_android_proxy_bridge.py b/tests/test_android_proxy_bridge.py new file mode 100644 index 0000000..590ea29 --- /dev/null +++ b/tests/test_android_proxy_bridge.py @@ -0,0 +1,50 @@ +import sys +import unittest +from pathlib import Path + + +sys.path.insert(0, str( + Path(__file__).resolve().parents[1] / "android" / "app" / "src" / "main" / "python" +)) + +import android_proxy_bridge # noqa: E402 + + +class FakeJavaArrayList: + def __init__(self, items): + self._items = list(items) + + def size(self): + return len(self._items) + + def get(self, index): + return self._items[index] + + +class AndroidProxyBridgeTests(unittest.TestCase): + def test_normalize_dc_ip_list_with_python_iterable(self): + result = android_proxy_bridge._normalize_dc_ip_list([ + "2:149.154.167.220", + " ", + "4:149.154.167.220 ", + ]) + + self.assertEqual(result, [ + "2:149.154.167.220", + "4:149.154.167.220", + ]) + + def test_normalize_dc_ip_list_with_java_array_list_shape(self): + result = android_proxy_bridge._normalize_dc_ip_list(FakeJavaArrayList([ + "2:149.154.167.220", + "4:149.154.167.220", + ])) + + self.assertEqual(result, [ + "2:149.154.167.220", + "4:149.154.167.220", + ]) + + +if __name__ == "__main__": + unittest.main()