diff --git a/product/runtime/src/main/python/java/android/importer.py b/product/runtime/src/main/python/java/android/importer.py index 8a9a22a7da..95f0e62fe8 100644 --- a/product/runtime/src/main/python/java/android/importer.py +++ b/product/runtime/src/main/python/java/android/importer.py @@ -84,6 +84,12 @@ def hook(path): # get_importer returns. site.addsitedir(finder.extract_root) + if sys.version_info[:2] == (3, 9): + from importlib import _common + global fallback_resources_original + fallback_resources_original = _common.fallback_resources + _common.fallback_resources = fallback_resources_39 + global spec_from_file_location_original spec_from_file_location_original = util.spec_from_file_location util.spec_from_file_location = spec_from_file_location_override @@ -96,6 +102,14 @@ def hook(path): machinery.ExtensionFileLoader.create_module = extension_create_module_override +# Python 3.9 only supports importlib.resources.files for the standard importers. +def fallback_resources_39(spec): + if isinstance(spec.loader, AssetLoader): + return spec.loader.get_resource_reader(spec.name).files() + else: + return fallback_resources_original(spec) + + def spec_from_file_location_override(name, location=None, *args, loader=None, **kwargs): if location and not loader: head, tail = split(location) diff --git a/product/runtime/src/test/python/chaquopy/test/android/test_import.py b/product/runtime/src/test/python/chaquopy/test/android/test_import.py index 2c35165118..0ce7d2a8e3 100644 --- a/product/runtime/src/test/python/chaquopy/test/android/test_import.py +++ b/product/runtime/src/test/python/chaquopy/test/android/test_import.py @@ -19,6 +19,7 @@ from unittest import skipIf import types from warnings import catch_warnings, filterwarnings +import zipfile from java.android import importer @@ -953,6 +954,20 @@ def test_resources_new(self): "// MurmurHash2 was written by Austin Appleby") self.check_resource_new(REQS_ABI_ZIP, pkg, "mrmr.so", b"\x7fELF") + # Stdlib + pkg_path = resources.files("email") + self.assertIsInstance(pkg_path, zipfile.Path) + self.assertTrue(pkg_path.is_dir()) + + children = [child.name for child in pkg_path.iterdir()] + self.assertIn("mime", children) + self.assertTrue((pkg_path / "mime").is_dir()) + + self.assertIn("parser.pyc", children) + path = pkg_path / "parser.pyc" + self.assertFalse(path.is_dir()) + self.assertPredicate(path.read_bytes().startswith, MAGIC_NUMBER) + def check_resource_dir(self, path, children): self.assertTrue(path.exists()) self.assertTrue(path.is_dir())