pymobiledevice3 4.14.6__py3-none-any.whl → 7.0.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. misc/plist_sniffer.py +15 -15
  2. misc/remotexpc_sniffer.py +29 -28
  3. misc/understanding_idevice_protocol_layers.md +15 -10
  4. pymobiledevice3/__main__.py +317 -127
  5. pymobiledevice3/_version.py +22 -4
  6. pymobiledevice3/bonjour.py +358 -113
  7. pymobiledevice3/ca.py +253 -16
  8. pymobiledevice3/cli/activation.py +31 -23
  9. pymobiledevice3/cli/afc.py +49 -40
  10. pymobiledevice3/cli/amfi.py +16 -21
  11. pymobiledevice3/cli/apps.py +87 -42
  12. pymobiledevice3/cli/backup.py +160 -90
  13. pymobiledevice3/cli/bonjour.py +44 -40
  14. pymobiledevice3/cli/cli_common.py +204 -198
  15. pymobiledevice3/cli/companion_proxy.py +14 -14
  16. pymobiledevice3/cli/crash.py +105 -56
  17. pymobiledevice3/cli/developer/__init__.py +62 -0
  18. pymobiledevice3/cli/developer/accessibility/__init__.py +65 -0
  19. pymobiledevice3/cli/developer/accessibility/settings.py +43 -0
  20. pymobiledevice3/cli/developer/arbitration.py +50 -0
  21. pymobiledevice3/cli/developer/condition.py +33 -0
  22. pymobiledevice3/cli/developer/core_device.py +294 -0
  23. pymobiledevice3/cli/developer/debugserver.py +244 -0
  24. pymobiledevice3/cli/developer/dvt/__init__.py +438 -0
  25. pymobiledevice3/cli/developer/dvt/core_profile_session.py +295 -0
  26. pymobiledevice3/cli/developer/dvt/simulate_location.py +56 -0
  27. pymobiledevice3/cli/developer/dvt/sysmon/__init__.py +69 -0
  28. pymobiledevice3/cli/developer/dvt/sysmon/process.py +188 -0
  29. pymobiledevice3/cli/developer/fetch_symbols.py +108 -0
  30. pymobiledevice3/cli/developer/simulate_location.py +51 -0
  31. pymobiledevice3/cli/diagnostics/__init__.py +75 -0
  32. pymobiledevice3/cli/diagnostics/battery.py +47 -0
  33. pymobiledevice3/cli/idam.py +42 -0
  34. pymobiledevice3/cli/lockdown.py +108 -103
  35. pymobiledevice3/cli/mounter.py +158 -99
  36. pymobiledevice3/cli/notification.py +38 -26
  37. pymobiledevice3/cli/pcap.py +45 -24
  38. pymobiledevice3/cli/power_assertion.py +18 -17
  39. pymobiledevice3/cli/processes.py +17 -23
  40. pymobiledevice3/cli/profile.py +165 -109
  41. pymobiledevice3/cli/provision.py +35 -34
  42. pymobiledevice3/cli/remote.py +217 -129
  43. pymobiledevice3/cli/restore.py +159 -143
  44. pymobiledevice3/cli/springboard.py +63 -53
  45. pymobiledevice3/cli/syslog.py +193 -86
  46. pymobiledevice3/cli/usbmux.py +73 -33
  47. pymobiledevice3/cli/version.py +5 -7
  48. pymobiledevice3/cli/webinspector.py +376 -214
  49. pymobiledevice3/common.py +3 -1
  50. pymobiledevice3/exceptions.py +182 -58
  51. pymobiledevice3/irecv.py +52 -53
  52. pymobiledevice3/irecv_devices.py +1489 -464
  53. pymobiledevice3/lockdown.py +473 -275
  54. pymobiledevice3/lockdown_service_provider.py +15 -8
  55. pymobiledevice3/osu/os_utils.py +27 -9
  56. pymobiledevice3/osu/posix_util.py +34 -15
  57. pymobiledevice3/osu/win_util.py +14 -8
  58. pymobiledevice3/pair_records.py +102 -21
  59. pymobiledevice3/remote/common.py +8 -4
  60. pymobiledevice3/remote/core_device/app_service.py +94 -67
  61. pymobiledevice3/remote/core_device/core_device_service.py +17 -14
  62. pymobiledevice3/remote/core_device/device_info.py +5 -5
  63. pymobiledevice3/remote/core_device/diagnostics_service.py +19 -4
  64. pymobiledevice3/remote/core_device/file_service.py +53 -23
  65. pymobiledevice3/remote/remote_service_discovery.py +79 -45
  66. pymobiledevice3/remote/remotexpc.py +73 -44
  67. pymobiledevice3/remote/tunnel_service.py +442 -317
  68. pymobiledevice3/remote/utils.py +14 -13
  69. pymobiledevice3/remote/xpc_message.py +145 -125
  70. pymobiledevice3/resources/dsc_uuid_map.py +19 -19
  71. pymobiledevice3/resources/firmware_notifications.py +20 -16
  72. pymobiledevice3/resources/notifications.txt +144 -0
  73. pymobiledevice3/restore/asr.py +27 -27
  74. pymobiledevice3/restore/base_restore.py +110 -21
  75. pymobiledevice3/restore/consts.py +87 -66
  76. pymobiledevice3/restore/device.py +59 -12
  77. pymobiledevice3/restore/fdr.py +46 -48
  78. pymobiledevice3/restore/ftab.py +19 -19
  79. pymobiledevice3/restore/img4.py +163 -0
  80. pymobiledevice3/restore/mbn.py +587 -0
  81. pymobiledevice3/restore/recovery.py +151 -151
  82. pymobiledevice3/restore/restore.py +562 -544
  83. pymobiledevice3/restore/restore_options.py +131 -110
  84. pymobiledevice3/restore/restored_client.py +51 -31
  85. pymobiledevice3/restore/tss.py +385 -267
  86. pymobiledevice3/service_connection.py +252 -59
  87. pymobiledevice3/services/accessibilityaudit.py +202 -120
  88. pymobiledevice3/services/afc.py +962 -365
  89. pymobiledevice3/services/amfi.py +24 -30
  90. pymobiledevice3/services/companion.py +23 -19
  91. pymobiledevice3/services/crash_reports.py +71 -47
  92. pymobiledevice3/services/debugserver_applist.py +3 -3
  93. pymobiledevice3/services/device_arbitration.py +8 -8
  94. pymobiledevice3/services/device_link.py +101 -79
  95. pymobiledevice3/services/diagnostics.py +973 -967
  96. pymobiledevice3/services/dtfetchsymbols.py +8 -8
  97. pymobiledevice3/services/dvt/dvt_secure_socket_proxy.py +4 -4
  98. pymobiledevice3/services/dvt/dvt_testmanaged_proxy.py +4 -4
  99. pymobiledevice3/services/dvt/instruments/activity_trace_tap.py +85 -74
  100. pymobiledevice3/services/dvt/instruments/application_listing.py +2 -3
  101. pymobiledevice3/services/dvt/instruments/condition_inducer.py +7 -6
  102. pymobiledevice3/services/dvt/instruments/core_profile_session_tap.py +466 -384
  103. pymobiledevice3/services/dvt/instruments/device_info.py +20 -11
  104. pymobiledevice3/services/dvt/instruments/energy_monitor.py +1 -1
  105. pymobiledevice3/services/dvt/instruments/graphics.py +1 -1
  106. pymobiledevice3/services/dvt/instruments/location_simulation.py +1 -1
  107. pymobiledevice3/services/dvt/instruments/location_simulation_base.py +10 -10
  108. pymobiledevice3/services/dvt/instruments/network_monitor.py +17 -17
  109. pymobiledevice3/services/dvt/instruments/notifications.py +1 -1
  110. pymobiledevice3/services/dvt/instruments/process_control.py +35 -10
  111. pymobiledevice3/services/dvt/instruments/screenshot.py +2 -2
  112. pymobiledevice3/services/dvt/instruments/sysmontap.py +15 -15
  113. pymobiledevice3/services/dvt/testmanaged/xcuitest.py +42 -52
  114. pymobiledevice3/services/file_relay.py +10 -10
  115. pymobiledevice3/services/heartbeat.py +9 -8
  116. pymobiledevice3/services/house_arrest.py +16 -15
  117. pymobiledevice3/services/idam.py +20 -0
  118. pymobiledevice3/services/installation_proxy.py +173 -81
  119. pymobiledevice3/services/lockdown_service.py +20 -10
  120. pymobiledevice3/services/misagent.py +22 -19
  121. pymobiledevice3/services/mobile_activation.py +147 -64
  122. pymobiledevice3/services/mobile_config.py +331 -294
  123. pymobiledevice3/services/mobile_image_mounter.py +141 -113
  124. pymobiledevice3/services/mobilebackup2.py +203 -145
  125. pymobiledevice3/services/notification_proxy.py +11 -11
  126. pymobiledevice3/services/os_trace.py +134 -74
  127. pymobiledevice3/services/pcapd.py +314 -302
  128. pymobiledevice3/services/power_assertion.py +10 -9
  129. pymobiledevice3/services/preboard.py +4 -4
  130. pymobiledevice3/services/remote_fetch_symbols.py +21 -14
  131. pymobiledevice3/services/remote_server.py +176 -146
  132. pymobiledevice3/services/restore_service.py +16 -16
  133. pymobiledevice3/services/screenshot.py +15 -12
  134. pymobiledevice3/services/simulate_location.py +7 -7
  135. pymobiledevice3/services/springboard.py +15 -15
  136. pymobiledevice3/services/syslog.py +5 -5
  137. pymobiledevice3/services/web_protocol/alert.py +11 -11
  138. pymobiledevice3/services/web_protocol/automation_session.py +251 -239
  139. pymobiledevice3/services/web_protocol/cdp_screencast.py +46 -37
  140. pymobiledevice3/services/web_protocol/cdp_server.py +19 -19
  141. pymobiledevice3/services/web_protocol/cdp_target.py +411 -373
  142. pymobiledevice3/services/web_protocol/driver.py +114 -111
  143. pymobiledevice3/services/web_protocol/element.py +124 -111
  144. pymobiledevice3/services/web_protocol/inspector_session.py +106 -102
  145. pymobiledevice3/services/web_protocol/selenium_api.py +49 -49
  146. pymobiledevice3/services/web_protocol/session_protocol.py +18 -12
  147. pymobiledevice3/services/web_protocol/switch_to.py +30 -27
  148. pymobiledevice3/services/webinspector.py +189 -155
  149. pymobiledevice3/tcp_forwarder.py +87 -69
  150. pymobiledevice3/tunneld/__init__.py +0 -0
  151. pymobiledevice3/tunneld/api.py +63 -0
  152. pymobiledevice3/tunneld/server.py +603 -0
  153. pymobiledevice3/usbmux.py +198 -147
  154. pymobiledevice3/utils.py +14 -11
  155. {pymobiledevice3-4.14.6.dist-info → pymobiledevice3-7.0.6.dist-info}/METADATA +55 -28
  156. pymobiledevice3-7.0.6.dist-info/RECORD +188 -0
  157. {pymobiledevice3-4.14.6.dist-info → pymobiledevice3-7.0.6.dist-info}/WHEEL +1 -1
  158. pymobiledevice3/cli/developer.py +0 -1215
  159. pymobiledevice3/cli/diagnostics.py +0 -99
  160. pymobiledevice3/tunneld.py +0 -524
  161. pymobiledevice3-4.14.6.dist-info/RECORD +0 -168
  162. {pymobiledevice3-4.14.6.dist-info → pymobiledevice3-7.0.6.dist-info}/entry_points.txt +0 -0
  163. {pymobiledevice3-4.14.6.dist-info → pymobiledevice3-7.0.6.dist-info/licenses}/LICENSE +0 -0
  164. {pymobiledevice3-4.14.6.dist-info → pymobiledevice3-7.0.6.dist-info}/top_level.txt +0 -0
@@ -3,17 +3,20 @@ import datetime
3
3
  import shutil
4
4
  import struct
5
5
  import warnings
6
+ from collections.abc import Iterable, Mapping, Sequence
6
7
  from pathlib import Path
8
+ from typing import Any, Callable, Optional, cast
7
9
 
8
10
  from pymobiledevice3.exceptions import NotEnoughDiskSpaceError, PyMobileDevice3Exception
11
+ from pymobiledevice3.service_connection import ServiceConnection
9
12
 
10
- SIZE_FORMAT = '>I'
11
- CODE_FORMAT = '>B'
12
- CODE_FILE_DATA = 0xc
13
- CODE_ERROR_REMOTE = 0xb
13
+ SIZE_FORMAT = ">I"
14
+ CODE_FORMAT = ">B"
15
+ CODE_FILE_DATA = 0xC
16
+ CODE_ERROR_REMOTE = 0xB
14
17
  CODE_ERROR_LOCAL = 0x6
15
18
  CODE_SUCCESS = 0
16
- FILE_TRANSFER_TERMINATOR = b'\x00\x00\x00\x00'
19
+ FILE_TRANSFER_TERMINATOR = b"\x00\x00\x00\x00"
17
20
  BULK_OPERATION_ERROR = -13
18
21
  APPLE_EPOCH = 978307200
19
22
  ERRNO_TO_DEVICE_ERROR = {
@@ -26,55 +29,70 @@ ERRNO_TO_DEVICE_ERROR = {
26
29
  28: -15,
27
30
  }
28
31
 
32
+ DLMessage = Sequence[Any]
33
+ ProgressCallback = Callable[[Any], None]
34
+ DLHandler = Callable[[DLMessage], None]
35
+
29
36
 
30
37
  class DeviceLink:
31
- def __init__(self, service, root_path: Path):
32
- self.service = service
33
- self.root_path = root_path
34
- self._dl_handlers = {
35
- 'DLMessageCreateDirectory': self.create_directory,
36
- 'DLMessageUploadFiles': self.upload_files,
37
- 'DLMessageGetFreeDiskSpace': self.get_free_disk_space,
38
- 'DLMessageMoveItems': self.move_items,
39
- 'DLMessageRemoveItems': self.remove_items,
40
- 'DLMessageDownloadFiles': self.download_files,
41
- 'DLContentsOfDirectory': self.contents_of_directory,
42
- 'DLMessageCopyItem': self.copy_item,
43
- 'DLMessagePurgeDiskSpace': self.purge_disk_space
38
+ def __init__(self, service: ServiceConnection, root_path: Path) -> None:
39
+ self.service: ServiceConnection = service
40
+ self.root_path: Path = root_path
41
+ self._dl_handlers: dict[str, DLHandler] = {
42
+ "DLMessageCreateDirectory": self.create_directory,
43
+ "DLMessageUploadFiles": self.upload_files,
44
+ "DLMessageGetFreeDiskSpace": self.get_free_disk_space,
45
+ "DLMessageMoveItems": self.move_items,
46
+ "DLMessageRemoveItems": self.remove_items,
47
+ "DLMessageDownloadFiles": self.download_files,
48
+ "DLContentsOfDirectory": self.contents_of_directory,
49
+ "DLMessageCopyItem": self.copy_item,
50
+ "DLMessagePurgeDiskSpace": self.purge_disk_space,
44
51
  }
45
52
 
46
- def dl_loop(self, progress_callback=lambda x: None):
53
+ def dl_loop(self, progress_callback: Optional[ProgressCallback] = None) -> Any:
54
+ def _noop(_: Any) -> None:
55
+ return None
56
+
57
+ callback: ProgressCallback = progress_callback if progress_callback is not None else _noop
58
+
47
59
  while True:
48
60
  message = self.receive_message()
49
61
  command = message[0]
50
62
 
51
- if command in ('DLMessageDownloadFiles', 'DLMessageMoveFiles', 'DLMessageMoveItems', 'DLMessageRemoveFiles',
52
- 'DLMessageRemoveItems'):
53
- progress_callback(message[3])
54
- elif command == 'DLMessageUploadFiles':
55
- progress_callback(message[2])
56
-
57
- if command == 'DLMessageProcessMessage':
58
- if not message[1]['ErrorCode']:
59
- return message[1].get('Content')
63
+ if command in (
64
+ "DLMessageDownloadFiles",
65
+ "DLMessageMoveFiles",
66
+ "DLMessageMoveItems",
67
+ "DLMessageRemoveFiles",
68
+ "DLMessageRemoveItems",
69
+ ):
70
+ callback(message[3])
71
+ elif command == "DLMessageUploadFiles":
72
+ callback(message[2])
73
+
74
+ if command == "DLMessageProcessMessage":
75
+ if not message[1]["ErrorCode"]:
76
+ return message[1].get("Content")
60
77
  else:
61
- raise PyMobileDevice3Exception(f'Device link error: {message[1]}')
78
+ raise PyMobileDevice3Exception(f"Device link error: {message[1]}")
62
79
  self._dl_handlers[command](message)
63
80
 
64
- def version_exchange(self):
81
+ def version_exchange(self) -> None:
65
82
  dl_message_version_exchange = self.receive_message()
66
83
  version_major = dl_message_version_exchange[1]
67
- self.service.send_plist(['DLMessageVersionExchange', 'DLVersionsOk', version_major])
84
+ self.service.send_plist(["DLMessageVersionExchange", "DLVersionsOk", version_major])
68
85
  dl_message_device_ready = self.receive_message()
69
- if dl_message_device_ready[0] != 'DLMessageDeviceReady':
70
- raise PyMobileDevice3Exception('Device link didn\'t return ready state')
86
+ if dl_message_device_ready[0] != "DLMessageDeviceReady":
87
+ raise PyMobileDevice3Exception("Device link didn't return ready state")
71
88
 
72
- def send_process_message(self, message):
73
- self.service.send_plist(['DLMessageProcessMessage', message])
89
+ def send_process_message(self, message: Mapping[str, Any]) -> None:
90
+ self.service.send_plist(["DLMessageProcessMessage", message])
74
91
 
75
- def download_files(self, message):
76
- status = {}
77
- for file in message[1]:
92
+ def download_files(self, message: DLMessage) -> None:
93
+ status: dict[str, dict[str, Any]] = {}
94
+ files = cast(Iterable[str], message[1])
95
+ for file in files:
78
96
  self.service.sendall(struct.pack(SIZE_FORMAT, len(file)))
79
97
  self.service.sendall(file.encode())
80
98
 
@@ -85,7 +103,7 @@ class DeviceLink:
85
103
  # https://github.com/doronz88/pymobiledevice3/issues/1165#issuecomment-2376815692
86
104
  chunk_size = 128 * 1024 * 1024 # 128 MB
87
105
 
88
- with file_path.open('rb') as file_handle:
106
+ with file_path.open("rb") as file_handle:
89
107
  while True:
90
108
  chunk_data = file_handle.read(chunk_size)
91
109
  if not chunk_data:
@@ -95,76 +113,79 @@ class DeviceLink:
95
113
 
96
114
  buffer = struct.pack(SIZE_FORMAT, struct.calcsize(CODE_FORMAT)) + struct.pack(CODE_FORMAT, CODE_SUCCESS)
97
115
  self.service.sendall(buffer)
98
- except IOError as e:
116
+ except OSError as e:
99
117
  status[file] = {
100
- 'DLFileErrorString': e.strerror,
101
- 'DLFileErrorCode': ctypes.c_uint64(ERRNO_TO_DEVICE_ERROR[e.errno]).value
118
+ "DLFileErrorString": e.strerror,
119
+ "DLFileErrorCode": ctypes.c_uint64(ERRNO_TO_DEVICE_ERROR[e.errno]).value,
102
120
  }
103
121
  self.service.sendall(struct.pack(SIZE_FORMAT, len(e.strerror) + struct.calcsize(CODE_FORMAT)))
104
122
  self.service.sendall(struct.pack(CODE_FORMAT, CODE_ERROR_LOCAL) + e.strerror.encode())
105
123
 
106
124
  self.service.sendall(FILE_TRANSFER_TERMINATOR)
107
125
  if status:
108
- self.status_response(BULK_OPERATION_ERROR, 'Multi status', status)
126
+ self.status_response(BULK_OPERATION_ERROR, "Multi status", status)
109
127
  else:
110
128
  self.status_response(0)
111
129
 
112
- def contents_of_directory(self, message):
130
+ def contents_of_directory(self, message: DLMessage) -> None:
113
131
  data = {}
114
- path = self.root_path / message[1]
132
+ path = self.root_path / cast(str, message[1])
115
133
  for file in path.iterdir():
116
- ftype = 'DLFileTypeUnknown'
134
+ ftype = "DLFileTypeUnknown"
117
135
  if file.is_dir():
118
- ftype = 'DLFileTypeDirectory'
136
+ ftype = "DLFileTypeDirectory"
119
137
  if file.is_file():
120
- ftype = 'DLFileTypeRegular'
138
+ ftype = "DLFileTypeRegular"
121
139
  modifications_data = datetime.datetime.fromtimestamp(file.stat().st_mtime - APPLE_EPOCH)
122
140
  modifications_data = modifications_data.replace(tzinfo=None)
123
141
  data[file.name] = {
124
- 'DLFileType': ftype,
125
- 'DLFileSize': file.stat().st_size,
126
- 'DLFileModificationDate': modifications_data
142
+ "DLFileType": ftype,
143
+ "DLFileSize": file.stat().st_size,
144
+ "DLFileModificationDate": modifications_data,
127
145
  }
128
146
  self.status_response(0, status_dict=data)
129
147
 
130
- def upload_files(self, message):
148
+ def upload_files(self, _message: DLMessage) -> None:
131
149
  while True:
132
150
  device_name = self._prefixed_recv()
133
151
  if not device_name:
134
152
  break
135
153
  file_name = self._prefixed_recv()
136
- size, = struct.unpack(SIZE_FORMAT, self.service.recvall(struct.calcsize(SIZE_FORMAT)))
137
- code, = struct.unpack(CODE_FORMAT, self.service.recvall(struct.calcsize(CODE_FORMAT)))
154
+ (size,) = struct.unpack(SIZE_FORMAT, self.service.recvall(struct.calcsize(SIZE_FORMAT)))
155
+ (code,) = struct.unpack(CODE_FORMAT, self.service.recvall(struct.calcsize(CODE_FORMAT)))
138
156
  size -= struct.calcsize(CODE_FORMAT)
139
- with open(self.root_path / file_name, 'wb') as fd:
157
+ with open(self.root_path / file_name, "wb") as fd:
140
158
  while size and code == CODE_FILE_DATA:
141
159
  fd.write(self.service.recvall(size))
142
- size, = struct.unpack(SIZE_FORMAT, self.service.recvall(struct.calcsize(SIZE_FORMAT)))
143
- code, = struct.unpack(CODE_FORMAT, self.service.recvall(struct.calcsize(CODE_FORMAT)))
160
+ (size,) = struct.unpack(SIZE_FORMAT, self.service.recvall(struct.calcsize(SIZE_FORMAT)))
161
+ (code,) = struct.unpack(CODE_FORMAT, self.service.recvall(struct.calcsize(CODE_FORMAT)))
144
162
  size -= struct.calcsize(CODE_FORMAT)
145
163
  if code == CODE_ERROR_REMOTE:
146
164
  # iOS 17 beta devices give this error for: backup_manifest.db
147
165
  error_message = self.service.recvall(size).decode()
148
- warnings.warn(f'Failed to fully upload: {file_name}. Device file name: {device_name}. Reason: '
149
- f'{error_message}')
166
+ warnings.warn(
167
+ f"Failed to fully upload: {file_name}. Device file name: {device_name}. Reason: {error_message}",
168
+ stacklevel=2,
169
+ )
150
170
  continue
151
171
  assert code == CODE_SUCCESS
152
172
  self.status_response(0)
153
173
 
154
- def get_free_disk_space(self, message):
174
+ def get_free_disk_space(self, _message: DLMessage) -> None:
155
175
  freespace = shutil.disk_usage(self.root_path).free
156
176
  self.status_response(0, status_dict=freespace)
157
177
 
158
- def move_items(self, message):
159
- for src, dst in message[1].items():
178
+ def move_items(self, message: DLMessage) -> None:
179
+ items = cast(Mapping[str, str], message[1])
180
+ for src, dst in items.items():
160
181
  dest = self.root_path / dst
161
182
  dest.parent.mkdir(parents=True, exist_ok=True)
162
183
  shutil.move(self.root_path / src, dest)
163
184
  self.status_response(0)
164
185
 
165
- def copy_item(self, message):
166
- src = self.root_path / message[1]
167
- dest = self.root_path / message[2]
186
+ def copy_item(self, message: DLMessage) -> None:
187
+ src = self.root_path / cast(str, message[1])
188
+ dest = self.root_path / cast(str, message[2])
168
189
  dest.parent.mkdir(parents=True, exist_ok=True)
169
190
  if src.is_dir():
170
191
  shutil.copytree(src, dest)
@@ -172,11 +193,11 @@ class DeviceLink:
172
193
  shutil.copy(src, dest)
173
194
  self.status_response(0)
174
195
 
175
- def purge_disk_space(self, message) -> None:
196
+ def purge_disk_space(self, _message: DLMessage) -> None:
176
197
  raise NotEnoughDiskSpaceError()
177
198
 
178
- def remove_items(self, message):
179
- for path in message[1]:
199
+ def remove_items(self, message: DLMessage) -> None:
200
+ for path in cast(Iterable[str], message[1]):
180
201
  rm_path = self.root_path / path
181
202
  if rm_path.is_dir():
182
203
  shutil.rmtree(rm_path)
@@ -184,24 +205,25 @@ class DeviceLink:
184
205
  rm_path.unlink(missing_ok=True)
185
206
  self.status_response(0)
186
207
 
187
- def create_directory(self, message):
188
- path = message[1]
208
+ def create_directory(self, message: DLMessage) -> None:
209
+ path = cast(str, message[1])
189
210
  (self.root_path / path).mkdir(parents=True, exist_ok=True)
190
211
  self.status_response(0)
191
212
 
192
- def status_response(self, status_code, status_str='', status_dict=None):
213
+ def status_response(self, status_code: int, status_str: str = "", status_dict: Any = None) -> None:
193
214
  self.service.send_plist([
194
- 'DLMessageStatusResponse', ctypes.c_uint64(status_code).value,
195
- status_str if status_str else '___EmptyParameterString___',
215
+ "DLMessageStatusResponse",
216
+ ctypes.c_uint64(status_code).value,
217
+ status_str if status_str else "___EmptyParameterString___",
196
218
  status_dict if status_dict is not None else {},
197
219
  ])
198
220
 
199
- def receive_message(self):
200
- return self.service.recv_plist()
221
+ def receive_message(self) -> DLMessage:
222
+ return cast(DLMessage, self.service.recv_plist())
201
223
 
202
- def disconnect(self):
203
- self.service.send_plist(['DLMessageDisconnect', '___EmptyParameterString___'])
224
+ def disconnect(self) -> None:
225
+ self.service.send_plist(["DLMessageDisconnect", "___EmptyParameterString___"])
204
226
 
205
- def _prefixed_recv(self):
206
- size, = struct.unpack(SIZE_FORMAT, self.service.recvall(struct.calcsize(SIZE_FORMAT)))
227
+ def _prefixed_recv(self) -> str:
228
+ (size,) = struct.unpack(SIZE_FORMAT, self.service.recvall(struct.calcsize(SIZE_FORMAT)))
207
229
  return self.service.recvall(size).decode()