Skip to content

Commit 3a22c96

Browse files
authored
use importlib_resources instead of __file__ (#1107)
* use importlib_resources instead of __file__
1 parent c86925b commit 3a22c96

File tree

5 files changed

+56
-19
lines changed

5 files changed

+56
-19
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ lxml = "*"
1515
adbutils = "^2.9.1"
1616
Pillow = "*"
1717
retry2 = "^0.9.5"
18+
importlib-resources = {version = "*", markers = "python_version < \"3.9\""}
1819

1920
[tool.poetry.group.dev.dependencies]
2021
pytest = "^8.1.1"

tests/test_utils.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,16 @@ def foo():
8888
pass
8989

9090
with pytest.warns(DeprecationWarning):
91-
foo()
91+
foo()
92+
93+
94+
def test_with_package_resource():
95+
with utils.with_package_resource("assets/sync.sh") as asset_path:
96+
assert asset_path.exists()
97+
assert asset_path.is_file()
98+
assert asset_path.name == "sync.sh"
99+
100+
# Test that the context manager works properly
101+
with pytest.raises(FileNotFoundError):
102+
with utils.with_package_resource("nonexistent_file.xyz") as _:
103+
pass

uiautomator2/_input.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
from uiautomator2.abstract import AbstractShell
2020
from uiautomator2.exceptions import AdbBroadcastError, DeviceError, InputIMEError
21-
from uiautomator2.utils import deprecated
21+
from uiautomator2.utils import deprecated, with_package_resource
2222

2323

2424
logger = logging.getLogger(__name__)
@@ -69,13 +69,12 @@ def is_input_ime_installed(self) -> bool:
6969

7070
def _setup_ime(self):
7171
logger.debug("installing AdbKeyboard ime")
72-
assets_dir = Path(__file__).parent / "assets"
73-
ime_apk_path = assets_dir / 'app-uiautomator.apk'
74-
try:
75-
self.adb_device.install(str(ime_apk_path), nolaunch=True, uninstall=True)
76-
except adbutils.AdbError as e:
77-
self.adb_device.uninstall(self.__ime_id.split('/')[0])
78-
self.adb_device.install(str(ime_apk_path), nolaunch=True, uninstall=True)
72+
with with_package_resource("assets/app-uiautomator.apk") as ime_apk_path:
73+
try:
74+
self.adb_device.install(str(ime_apk_path), nolaunch=True, uninstall=True)
75+
except adbutils.AdbError as e:
76+
self.adb_device.uninstall(self.__ime_id.split('/')[0])
77+
self.adb_device.install(str(ime_apk_path), nolaunch=True, uninstall=True)
7978

8079
# wait for ime registered
8180
for _ in range(10):

uiautomator2/core.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from uiautomator2.exceptions import AccessibilityServiceAlreadyRegisteredError, APKSignatureError, HTTPError, \
2424
HTTPTimeoutError, LaunchUiAutomationError, RPCInvalidError, RPCStackOverflowError, RPCUnknownError, \
2525
UiAutomationNotConnectedError, UiObjectNotFoundError
26-
from uiautomator2.utils import is_version_compatiable
26+
from uiautomator2.utils import with_package_resource
2727
from uiautomator2.version import __apk_version__
2828

2929
logger = logging.getLogger(__name__)
@@ -236,14 +236,13 @@ def start_uiautomator(self):
236236
self._wait_ready()
237237

238238
def _setup_jar(self):
239-
assets_dir = Path(__file__).parent / "assets"
240-
jar_path = assets_dir / "u2.jar"
241-
target_path = "/data/local/tmp/u2.jar"
242-
if self._check_device_file_hash(jar_path, target_path):
243-
logger.debug("file u2.jar already pushed")
244-
else:
245-
logger.debug("push %s -> %s", jar_path, target_path)
246-
self._dev.sync.push(jar_path, target_path, check=True)
239+
with with_package_resource("assets/u2.jar") as jar_path:
240+
target_path = "/data/local/tmp/u2.jar"
241+
if self._check_device_file_hash(jar_path, target_path):
242+
logger.debug("file u2.jar already pushed")
243+
else:
244+
logger.debug("push %s -> %s", jar_path, target_path)
245+
self._dev.sync.push(jar_path, target_path, check=True)
247246

248247
def _check_device_file_hash(self, local_file: Union[str, Path], remote_file: str) -> bool:
249248
""" check if remote file hash is correct """

uiautomator2/utils.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,45 @@
11
# coding: utf-8
22
#
33

4+
import contextlib
45
import functools
56
import inspect
7+
import pathlib
68
import shlex
79
import threading
810
import typing
9-
from typing import Union
1011
import warnings
12+
from typing import Union
13+
1114
from PIL import Image
1215

1316
from uiautomator2._proto import Direction
1417
from uiautomator2.exceptions import SessionBrokenError, UiObjectNotFoundError
1518

1619

20+
@contextlib.contextmanager
21+
def with_package_resource(filename: str) -> typing.Generator[pathlib.Path, None, None]:
22+
"""
23+
Context manager to access a package asset file using importlib.resources.
24+
25+
Args:
26+
filename (str): The name of the file to locate.
27+
28+
Yields:
29+
str: The full path to the located file.
30+
"""
31+
try:
32+
from importlib.resources import as_file, files
33+
except ImportError:
34+
# For Python < 3.9
35+
from importlib_resources import as_file, files
36+
anchor = files("uiautomator2") / filename
37+
with as_file(anchor) as f:
38+
if not f.exists():
39+
raise FileNotFoundError(f"Resource {filename} not found in uiautomator2 package.")
40+
yield f
41+
42+
1743
def check_alive(fn):
1844
@functools.wraps(fn)
1945
def inner(self, *args, **kwargs):

0 commit comments

Comments
 (0)