pymobiledevice3 4.27.4__py3-none-any.whl → 5.1.2__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 (143) hide show
  1. misc/plist_sniffer.py +15 -15
  2. misc/remotexpc_sniffer.py +29 -28
  3. pymobiledevice3/__main__.py +123 -98
  4. pymobiledevice3/_version.py +2 -2
  5. pymobiledevice3/bonjour.py +351 -117
  6. pymobiledevice3/ca.py +32 -24
  7. pymobiledevice3/cli/activation.py +7 -7
  8. pymobiledevice3/cli/afc.py +19 -19
  9. pymobiledevice3/cli/amfi.py +4 -4
  10. pymobiledevice3/cli/apps.py +51 -39
  11. pymobiledevice3/cli/backup.py +58 -32
  12. pymobiledevice3/cli/bonjour.py +27 -20
  13. pymobiledevice3/cli/cli_common.py +112 -81
  14. pymobiledevice3/cli/companion_proxy.py +4 -4
  15. pymobiledevice3/cli/completions.py +10 -10
  16. pymobiledevice3/cli/crash.py +37 -31
  17. pymobiledevice3/cli/developer.py +601 -519
  18. pymobiledevice3/cli/diagnostics.py +38 -33
  19. pymobiledevice3/cli/lockdown.py +82 -72
  20. pymobiledevice3/cli/mounter.py +84 -67
  21. pymobiledevice3/cli/notification.py +10 -10
  22. pymobiledevice3/cli/pcap.py +19 -14
  23. pymobiledevice3/cli/power_assertion.py +12 -10
  24. pymobiledevice3/cli/processes.py +10 -10
  25. pymobiledevice3/cli/profile.py +88 -77
  26. pymobiledevice3/cli/provision.py +17 -17
  27. pymobiledevice3/cli/remote.py +188 -111
  28. pymobiledevice3/cli/restore.py +43 -40
  29. pymobiledevice3/cli/springboard.py +30 -28
  30. pymobiledevice3/cli/syslog.py +85 -58
  31. pymobiledevice3/cli/usbmux.py +21 -20
  32. pymobiledevice3/cli/version.py +3 -2
  33. pymobiledevice3/cli/webinspector.py +156 -78
  34. pymobiledevice3/common.py +1 -1
  35. pymobiledevice3/exceptions.py +154 -60
  36. pymobiledevice3/irecv.py +49 -53
  37. pymobiledevice3/irecv_devices.py +1489 -492
  38. pymobiledevice3/lockdown.py +400 -251
  39. pymobiledevice3/lockdown_service_provider.py +5 -7
  40. pymobiledevice3/osu/os_utils.py +18 -9
  41. pymobiledevice3/osu/posix_util.py +28 -15
  42. pymobiledevice3/osu/win_util.py +14 -8
  43. pymobiledevice3/pair_records.py +19 -19
  44. pymobiledevice3/remote/common.py +4 -4
  45. pymobiledevice3/remote/core_device/app_service.py +94 -67
  46. pymobiledevice3/remote/core_device/core_device_service.py +17 -14
  47. pymobiledevice3/remote/core_device/device_info.py +5 -5
  48. pymobiledevice3/remote/core_device/diagnostics_service.py +10 -8
  49. pymobiledevice3/remote/core_device/file_service.py +47 -33
  50. pymobiledevice3/remote/remote_service_discovery.py +53 -35
  51. pymobiledevice3/remote/remotexpc.py +64 -42
  52. pymobiledevice3/remote/tunnel_service.py +383 -297
  53. pymobiledevice3/remote/utils.py +14 -13
  54. pymobiledevice3/remote/xpc_message.py +145 -125
  55. pymobiledevice3/resources/dsc_uuid_map.py +19 -19
  56. pymobiledevice3/resources/firmware_notifications.py +16 -16
  57. pymobiledevice3/restore/asr.py +27 -27
  58. pymobiledevice3/restore/base_restore.py +90 -47
  59. pymobiledevice3/restore/consts.py +87 -66
  60. pymobiledevice3/restore/device.py +11 -11
  61. pymobiledevice3/restore/fdr.py +46 -46
  62. pymobiledevice3/restore/ftab.py +19 -19
  63. pymobiledevice3/restore/img4.py +130 -133
  64. pymobiledevice3/restore/mbn.py +587 -0
  65. pymobiledevice3/restore/recovery.py +125 -135
  66. pymobiledevice3/restore/restore.py +535 -523
  67. pymobiledevice3/restore/restore_options.py +122 -115
  68. pymobiledevice3/restore/restored_client.py +25 -22
  69. pymobiledevice3/restore/tss.py +378 -270
  70. pymobiledevice3/service_connection.py +50 -46
  71. pymobiledevice3/services/accessibilityaudit.py +137 -127
  72. pymobiledevice3/services/afc.py +352 -292
  73. pymobiledevice3/services/amfi.py +21 -18
  74. pymobiledevice3/services/companion.py +23 -19
  75. pymobiledevice3/services/crash_reports.py +61 -47
  76. pymobiledevice3/services/debugserver_applist.py +3 -3
  77. pymobiledevice3/services/device_arbitration.py +8 -8
  78. pymobiledevice3/services/device_link.py +56 -48
  79. pymobiledevice3/services/diagnostics.py +971 -968
  80. pymobiledevice3/services/dtfetchsymbols.py +8 -8
  81. pymobiledevice3/services/dvt/dvt_secure_socket_proxy.py +4 -4
  82. pymobiledevice3/services/dvt/dvt_testmanaged_proxy.py +4 -4
  83. pymobiledevice3/services/dvt/instruments/activity_trace_tap.py +85 -74
  84. pymobiledevice3/services/dvt/instruments/application_listing.py +2 -3
  85. pymobiledevice3/services/dvt/instruments/condition_inducer.py +7 -6
  86. pymobiledevice3/services/dvt/instruments/core_profile_session_tap.py +466 -384
  87. pymobiledevice3/services/dvt/instruments/device_info.py +11 -11
  88. pymobiledevice3/services/dvt/instruments/energy_monitor.py +1 -1
  89. pymobiledevice3/services/dvt/instruments/graphics.py +1 -1
  90. pymobiledevice3/services/dvt/instruments/location_simulation.py +1 -1
  91. pymobiledevice3/services/dvt/instruments/location_simulation_base.py +10 -10
  92. pymobiledevice3/services/dvt/instruments/network_monitor.py +17 -17
  93. pymobiledevice3/services/dvt/instruments/notifications.py +1 -1
  94. pymobiledevice3/services/dvt/instruments/process_control.py +25 -10
  95. pymobiledevice3/services/dvt/instruments/screenshot.py +2 -2
  96. pymobiledevice3/services/dvt/instruments/sysmontap.py +15 -15
  97. pymobiledevice3/services/dvt/testmanaged/xcuitest.py +42 -52
  98. pymobiledevice3/services/file_relay.py +10 -10
  99. pymobiledevice3/services/heartbeat.py +8 -7
  100. pymobiledevice3/services/house_arrest.py +12 -15
  101. pymobiledevice3/services/installation_proxy.py +119 -100
  102. pymobiledevice3/services/lockdown_service.py +12 -5
  103. pymobiledevice3/services/misagent.py +22 -19
  104. pymobiledevice3/services/mobile_activation.py +84 -72
  105. pymobiledevice3/services/mobile_config.py +331 -301
  106. pymobiledevice3/services/mobile_image_mounter.py +137 -116
  107. pymobiledevice3/services/mobilebackup2.py +188 -150
  108. pymobiledevice3/services/notification_proxy.py +11 -11
  109. pymobiledevice3/services/os_trace.py +128 -74
  110. pymobiledevice3/services/pcapd.py +306 -306
  111. pymobiledevice3/services/power_assertion.py +10 -9
  112. pymobiledevice3/services/preboard.py +4 -4
  113. pymobiledevice3/services/remote_fetch_symbols.py +16 -14
  114. pymobiledevice3/services/remote_server.py +176 -146
  115. pymobiledevice3/services/restore_service.py +16 -16
  116. pymobiledevice3/services/screenshot.py +13 -10
  117. pymobiledevice3/services/simulate_location.py +7 -7
  118. pymobiledevice3/services/springboard.py +15 -15
  119. pymobiledevice3/services/syslog.py +5 -5
  120. pymobiledevice3/services/web_protocol/alert.py +3 -3
  121. pymobiledevice3/services/web_protocol/automation_session.py +183 -179
  122. pymobiledevice3/services/web_protocol/cdp_screencast.py +44 -36
  123. pymobiledevice3/services/web_protocol/cdp_server.py +19 -19
  124. pymobiledevice3/services/web_protocol/cdp_target.py +411 -373
  125. pymobiledevice3/services/web_protocol/driver.py +47 -45
  126. pymobiledevice3/services/web_protocol/element.py +74 -63
  127. pymobiledevice3/services/web_protocol/inspector_session.py +106 -102
  128. pymobiledevice3/services/web_protocol/selenium_api.py +3 -3
  129. pymobiledevice3/services/web_protocol/session_protocol.py +15 -10
  130. pymobiledevice3/services/web_protocol/switch_to.py +11 -12
  131. pymobiledevice3/services/webinspector.py +142 -116
  132. pymobiledevice3/tcp_forwarder.py +35 -22
  133. pymobiledevice3/tunneld/api.py +20 -15
  134. pymobiledevice3/tunneld/server.py +310 -193
  135. pymobiledevice3/usbmux.py +197 -148
  136. pymobiledevice3/utils.py +14 -11
  137. {pymobiledevice3-4.27.4.dist-info → pymobiledevice3-5.1.2.dist-info}/METADATA +1 -2
  138. pymobiledevice3-5.1.2.dist-info/RECORD +173 -0
  139. pymobiledevice3-4.27.4.dist-info/RECORD +0 -172
  140. {pymobiledevice3-4.27.4.dist-info → pymobiledevice3-5.1.2.dist-info}/WHEEL +0 -0
  141. {pymobiledevice3-4.27.4.dist-info → pymobiledevice3-5.1.2.dist-info}/entry_points.txt +0 -0
  142. {pymobiledevice3-4.27.4.dist-info → pymobiledevice3-5.1.2.dist-info}/licenses/LICENSE +0 -0
  143. {pymobiledevice3-4.27.4.dist-info → pymobiledevice3-5.1.2.dist-info}/top_level.txt +0 -0
@@ -7,10 +7,10 @@ from pymobiledevice3.lockdown import LockdownClient
7
7
 
8
8
 
9
9
  class DtFetchSymbols:
10
- SERVICE_NAME = 'com.apple.dt.fetchsymbols'
10
+ SERVICE_NAME = "com.apple.dt.fetchsymbols"
11
11
  MAX_CHUNK = 1024 * 1024 * 10 # 10MB
12
- CMD_LIST_FILES_PLIST = struct.pack('>I', 0x30303030)
13
- CMD_GET_FILE = struct.pack('>I', 1)
12
+ CMD_LIST_FILES_PLIST = struct.pack(">I", 0x30303030)
13
+ CMD_GET_FILE = struct.pack(">I", 1)
14
14
 
15
15
  def __init__(self, lockdown: LockdownClient):
16
16
  self.logger = logging.getLogger(__name__)
@@ -18,16 +18,16 @@ class DtFetchSymbols:
18
18
 
19
19
  def list_files(self) -> list[str]:
20
20
  service = self._start_command(self.CMD_LIST_FILES_PLIST)
21
- files = service.recv_plist().get('files')
21
+ files = service.recv_plist().get("files")
22
22
  service.close()
23
23
  return files
24
24
 
25
25
  def get_file(self, fileno: int, stream: typing.IO):
26
26
  service = self._start_command(self.CMD_GET_FILE)
27
- service.sendall(struct.pack('>I', fileno))
27
+ service.sendall(struct.pack(">I", fileno))
28
28
 
29
- size = struct.unpack('>Q', service.recvall(8))[0]
30
- self.logger.debug(f'file size: {size}')
29
+ size = struct.unpack(">Q", service.recvall(8))[0]
30
+ self.logger.debug(f"file size: {size}")
31
31
 
32
32
  received = 0
33
33
  while received < size:
@@ -42,6 +42,6 @@ class DtFetchSymbols:
42
42
 
43
43
  # receive same command as an ack
44
44
  if cmd != service.recvall(len(cmd)):
45
- raise PyMobileDevice3Exception('bad ack')
45
+ raise PyMobileDevice3Exception("bad ack")
46
46
 
47
47
  return service
@@ -6,15 +6,15 @@ from pymobiledevice3.services.remote_server import RemoteServer
6
6
 
7
7
 
8
8
  class DvtSecureSocketProxyService(RemoteServer):
9
- SERVICE_NAME = 'com.apple.instruments.remoteserver.DVTSecureSocketProxy'
10
- OLD_SERVICE_NAME = 'com.apple.instruments.remoteserver'
11
- RSD_SERVICE_NAME = 'com.apple.instruments.dtservicehub'
9
+ SERVICE_NAME = "com.apple.instruments.remoteserver.DVTSecureSocketProxy"
10
+ OLD_SERVICE_NAME = "com.apple.instruments.remoteserver"
11
+ RSD_SERVICE_NAME = "com.apple.instruments.dtservicehub"
12
12
 
13
13
  def __init__(self, lockdown: LockdownServiceProvider):
14
14
  if isinstance(lockdown, RemoteServiceDiscoveryService):
15
15
  service_name = self.RSD_SERVICE_NAME
16
16
  remove_ssl_context = False
17
- elif Version(lockdown.product_version) >= Version('14.0'):
17
+ elif Version(lockdown.product_version) >= Version("14.0"):
18
18
  service_name = self.SERVICE_NAME
19
19
  remove_ssl_context = False
20
20
  else:
@@ -6,9 +6,9 @@ from pymobiledevice3.services.remote_server import RemoteServer
6
6
 
7
7
 
8
8
  class DvtTestmanagedProxyService(RemoteServer):
9
- SERVICE_NAME = 'com.apple.testmanagerd.lockdown.secure'
10
- OLD_SERVICE_NAME = 'com.apple.testmanagerd.lockdown'
11
- RSD_SERVICE_NAME = 'com.apple.dt.testmanagerd.remote'
9
+ SERVICE_NAME = "com.apple.testmanagerd.lockdown.secure"
10
+ OLD_SERVICE_NAME = "com.apple.testmanagerd.lockdown"
11
+ RSD_SERVICE_NAME = "com.apple.dt.testmanagerd.remote"
12
12
 
13
13
  # TODO: there is also service named 'com.apple.dt.testmanagerd.remote.automation', but not used
14
14
 
@@ -16,7 +16,7 @@ class DvtTestmanagedProxyService(RemoteServer):
16
16
  if isinstance(lockdown, RemoteServiceDiscoveryService): # only happends when >=17.0
17
17
  service_name = self.RSD_SERVICE_NAME
18
18
  remove_ssl_context = False
19
- elif Version(lockdown.product_version) >= Version('14.0'):
19
+ elif Version(lockdown.product_version) >= Version("14.0"):
20
20
  service_name = self.SERVICE_NAME
21
21
  remove_ssl_context = False
22
22
  else:
@@ -13,8 +13,8 @@ CMD_TABLE_RESET = 0x64
13
13
  CMD_COPY = 0x65
14
14
  CMD_SENTINEL = 0x68
15
15
  CMD_STRUCT = 0x69
16
- CMD_PLACEHOLDER_COUNT = 0x6a
17
- CMD_DEBUG = 0x6b
16
+ CMD_PLACEHOLDER_COUNT = 0x6A
17
+ CMD_DEBUG = 0x6B
18
18
 
19
19
 
20
20
  @dataclasses.dataclass
@@ -26,7 +26,7 @@ class Table:
26
26
 
27
27
 
28
28
  def decode_str(s: bytes):
29
- return s.split(b'\x00', 1)[0].decode()
29
+ return s.split(b"\x00", 1)[0].decode()
30
30
 
31
31
 
32
32
  def ignored_null(s: bytes) -> bytes:
@@ -39,35 +39,35 @@ def ignored_null(s: bytes) -> bytes:
39
39
 
40
40
 
41
41
  def decode_message_format(message) -> str:
42
- s = ''
42
+ s = ""
43
43
  for type_, data in message:
44
44
  if data and isinstance(data, bytes):
45
45
  data = ignored_null(data)
46
46
  type_ = decode_str(type_)
47
47
 
48
- if type_ == 'address':
49
- type_ = 'uint64-hex'
48
+ if type_ == "address":
49
+ type_ = "uint64-hex"
50
50
 
51
- if type_ in ('narrative-text', 'string'):
51
+ if type_ in ("narrative-text", "string"):
52
52
  if data is None:
53
- s += '<None>'
53
+ s += "<None>"
54
54
  else:
55
55
  s += data.decode()
56
- elif type_ == 'private':
57
- s += '<private>'
58
- elif type_.startswith('uint64'):
59
- uint64 = struct.unpack('<Q', data.ljust(8, b'\x00'))[0]
60
- if 'hex' in type_:
56
+ elif type_ == "private":
57
+ s += "<private>"
58
+ elif type_.startswith("uint64"):
59
+ uint64 = struct.unpack("<Q", data.ljust(8, b"\x00"))[0]
60
+ if "hex" in type_:
61
61
  uint64 = hex(uint64)[2:]
62
- if 'lowercase' in type_:
62
+ if "lowercase" in type_:
63
63
  uint64 = uint64.lower()
64
64
  s += str(uint64)
65
- elif 'decimal' in type_:
66
- uint64 = struct.unpack('<Q', data.ljust(8, b'\x00'))[0]
65
+ elif "decimal" in type_:
66
+ uint64 = struct.unpack("<Q", data.ljust(8, b"\x00"))[0]
67
67
  s += str(uint64)
68
- elif type_ in ('data', 'uuid'):
68
+ elif type_ in ("data", "uuid"):
69
69
  if data is not None:
70
- s += b''.join(data).hex()
70
+ s += b"".join(data).hex()
71
71
  else:
72
72
  # by default, make sure the data can be concatenated
73
73
  s += str(data)
@@ -75,7 +75,7 @@ def decode_message_format(message) -> str:
75
75
 
76
76
 
77
77
  class ActivityTraceTap(Tap):
78
- IDENTIFIER = 'com.apple.instruments.server.services.activitytracetap'
78
+ IDENTIFIER = "com.apple.instruments.server.services.activitytracetap"
79
79
 
80
80
  def __init__(self, dvt, enable_http_archive_logging=False):
81
81
  # TODO:
@@ -83,20 +83,20 @@ class ActivityTraceTap(Tap):
83
83
  # to understand each row's structure.
84
84
 
85
85
  config = {
86
- 'bm': 0, # buffer mode
87
- 'combineDataScope': 0,
88
- 'machTimebaseDenom': 3,
89
- 'machTimebaseNumer': 125,
90
- 'onlySignposts': 0,
91
- 'pidToInjectCombineDYLIB': '-1',
92
- 'predicate': '(messageType == info OR messageType == debug OR messageType == default OR '
93
- 'messageType == error OR messageType == fault)',
94
- 'signpostsAndLogs': 1,
95
- 'trackPidToExecNameMapping': True,
96
- 'enableHTTPArchiveLogging': enable_http_archive_logging,
97
- 'targetPID': -3, # all Process
98
- 'trackExpiredPIDs': 1,
99
- 'ur': 500,
86
+ "bm": 0, # buffer mode
87
+ "combineDataScope": 0,
88
+ "machTimebaseDenom": 3,
89
+ "machTimebaseNumer": 125,
90
+ "onlySignposts": 0,
91
+ "pidToInjectCombineDYLIB": "-1",
92
+ "predicate": "(messageType == info OR messageType == debug OR messageType == default OR "
93
+ "messageType == error OR messageType == fault)",
94
+ "signpostsAndLogs": 1,
95
+ "trackPidToExecNameMapping": True,
96
+ "enableHTTPArchiveLogging": enable_http_archive_logging,
97
+ "targetPID": -3, # all Process
98
+ "trackExpiredPIDs": 1,
99
+ "ur": 500,
100
100
  }
101
101
 
102
102
  super().__init__(dvt, self.IDENTIFIER, config)
@@ -107,8 +107,8 @@ class ActivityTraceTap(Tap):
107
107
  self.tables = []
108
108
 
109
109
  def _get_next_message(self):
110
- message = b''
111
- while message.startswith(b'bplist') or len(message) == 0:
110
+ message = b""
111
+ while message.startswith(b"bplist") or len(message) == 0:
112
112
  # ignore heartbeat messages
113
113
  message = self.channel.receive_message()
114
114
  self._set_current_message(message)
@@ -123,7 +123,7 @@ class ActivityTraceTap(Tap):
123
123
  buf = self._message.read(2)
124
124
  if len(buf) != 2:
125
125
  raise EOFError()
126
- word, = struct.unpack('<H', buf)
126
+ (word,) = struct.unpack("<H", buf)
127
127
  self._message.seek(-2, os.SEEK_CUR)
128
128
  return word
129
129
 
@@ -133,45 +133,45 @@ class ActivityTraceTap(Tap):
133
133
  return word
134
134
 
135
135
  def _handle_push(self, word):
136
- assert word >> 14 in (0b10, 0b11), f'invalid magic for pushed item. word: {hex(word)}'
136
+ assert word >> 14 in (0b10, 0b11), f"invalid magic for pushed item. word: {hex(word)}"
137
137
 
138
138
  count = 0
139
139
  imm = 0
140
140
  bit_count = 0
141
141
  while word >> 14 != 0b11:
142
142
  # not end word
143
- imm = (imm << 14) | (word & 0x3fff)
143
+ imm = (imm << 14) | (word & 0x3FFF)
144
144
  word = self._read_word()
145
145
  count += 1
146
146
  bit_count += 14
147
147
 
148
- imm = (imm << 14) | (word & 0x3fff)
148
+ imm = (imm << 14) | (word & 0x3FFF)
149
149
  bit_count += 14
150
150
 
151
- imm <<= (8 - bit_count % 8)
151
+ imm <<= 8 - bit_count % 8
152
152
  bit_count += 8 - bit_count % 8
153
153
 
154
- result = imm.to_bytes(math.ceil(bit_count / 8), 'big')
154
+ result = imm.to_bytes(math.ceil(bit_count / 8), "big")
155
155
  self.stack.append(result)
156
156
 
157
157
  return result
158
158
 
159
159
  def _handle_table_reset(self, word):
160
- """ start new table vector """
160
+ """start new table vector"""
161
161
  self.generation += 1
162
162
  self.background = 0
163
163
  self.stack = []
164
164
 
165
165
  def _handle_sentinel(self, word):
166
- """ push a dummy """
166
+ """push a dummy"""
167
167
  self.stack.append(None)
168
168
 
169
169
  def _handle_struct(self, word):
170
- """ replace last `distance` items with a single one which represents them as a tuple """
171
- distance = word & 0xff
170
+ """replace last `distance` items with a single one which represents them as a tuple"""
171
+ distance = word & 0xFF
172
172
 
173
- if distance == 0xff:
174
- raise NotImplementedError('long struct')
173
+ if distance == 0xFF:
174
+ raise NotImplementedError("long struct")
175
175
 
176
176
  new_item = self.stack[-distance:]
177
177
 
@@ -179,71 +179,82 @@ class ActivityTraceTap(Tap):
179
179
  self.stack.append(new_item)
180
180
 
181
181
  def _handle_define_table(self, word):
182
- """ define a table struct """
182
+ """define a table struct"""
183
183
  distance = 4
184
184
 
185
185
  table_raw = Table(*self.stack[-distance:])
186
- table = Table(name=table_raw.name.split(b'\x00', 1)[0].decode(),
187
- columns=[c.split(b'\x00', 1)[0].decode() for c in table_raw.columns],
188
- unknown0=table_raw.unknown0, unknown2=table_raw.unknown2)
186
+ table = Table(
187
+ name=table_raw.name.split(b"\x00", 1)[0].decode(),
188
+ columns=[c.split(b"\x00", 1)[0].decode() for c in table_raw.columns],
189
+ unknown0=table_raw.unknown0,
190
+ unknown2=table_raw.unknown2,
191
+ )
189
192
 
190
193
  self.stack = self.stack[:-distance]
191
194
  self.tables.append(table)
192
195
 
193
196
  def _handle_debug(self, word):
194
- """ pop last pushed item from stack """
195
- debug_id = word & 0xff
197
+ """pop last pushed item from stack"""
198
+ debug_id = word & 0xFF
196
199
  item = self.stack[-1]
197
200
 
198
- reference = int.from_bytes(item, byteorder='little')
201
+ reference = int.from_bytes(item, byteorder="little")
199
202
 
200
- assert reference == len(self.stack) - 1, \
201
- f'assert debug {debug_id} got reference: {hex(reference)} instead of: {len(self.stack) - 1} {item}'
203
+ assert reference == len(self.stack) - 1, (
204
+ f"assert debug {debug_id} got reference: {hex(reference)} instead of: {len(self.stack) - 1} {item}"
205
+ )
202
206
  self.stack = self.stack[:-1]
203
207
 
204
208
  def _handle_copy(self, word):
205
- """ copy item at distance from stack """
206
- distance = word & 0xff
207
- if distance != 0xff:
209
+ """copy item at distance from stack"""
210
+ distance = word & 0xFF
211
+ if distance != 0xFF:
208
212
  item = self.stack[-distance - 1]
209
213
  self.stack.append(item)
210
214
  else:
211
215
  # long struct - pop distance from stack
212
216
  item = self.stack[-1]
213
- reference = int.from_bytes(item, byteorder='little') - 1
217
+ reference = int.from_bytes(item, byteorder="little") - 1
214
218
  self.stack = self.stack[:-1]
215
219
  self.stack.append(self.stack[reference])
216
220
 
217
221
  def _handle_end_row(self, word):
218
- """ flush current row """
219
- generation = word & 0xff
222
+ """flush current row"""
223
+ generation = word & 0xFF
220
224
  columns = self.tables[generation].columns
221
- row = self.stack[-len(columns):]
222
- self.stack = self.stack[:-len(columns)]
225
+ row = self.stack[-len(columns) :]
226
+ self.stack = self.stack[: -len(columns)]
223
227
 
224
- Message = dataclasses.make_dataclass('message', [c.replace('-', '_') for c in columns])
228
+ Message = dataclasses.make_dataclass("message", [c.replace("-", "_") for c in columns])
225
229
  message = Message(*row)
226
- message.process = 0 if message.process is None else struct.unpack('<I', message.process[0].ljust(4, b'\x00'))[0]
227
- message.thread = struct.unpack('<I', message.thread[0].ljust(4, b'\x00'))[0]
228
-
229
- string_fields = ('message_type', 'format_string', 'subsystem', 'category', 'sender_image_path',
230
- 'event_type', 'name')
230
+ message.process = 0 if message.process is None else struct.unpack("<I", message.process[0].ljust(4, b"\x00"))[0]
231
+ message.thread = struct.unpack("<I", message.thread[0].ljust(4, b"\x00"))[0]
232
+
233
+ string_fields = (
234
+ "message_type",
235
+ "format_string",
236
+ "subsystem",
237
+ "category",
238
+ "sender_image_path",
239
+ "event_type",
240
+ "name",
241
+ )
231
242
  for f in string_fields:
232
243
  if hasattr(message, f):
233
244
  v = getattr(message, f)
234
245
  setattr(message, f, decode_str(v) if v else v)
235
246
 
236
- if hasattr(message, 'message'):
247
+ if hasattr(message, "message"):
237
248
  return message
238
249
 
239
250
  def _handle_placeholder_count(self, word):
240
- """ remove `count` last items from stack """
241
- count = word & 0xff
251
+ """remove `count` last items from stack"""
252
+ count = word & 0xFF
242
253
  if count > 0:
243
254
  self.stack = self.stack[:-count]
244
255
 
245
256
  def _handle_convert_mach_continuous(self, word):
246
- """ push an item and pop it. effectively do nothing """
257
+ """push an item and pop it. effectively do nothing"""
247
258
  pass
248
259
 
249
260
  def _parse(self):
@@ -2,7 +2,7 @@ from pymobiledevice3.services.remote_server import MessageAux
2
2
 
3
3
 
4
4
  class ApplicationListing:
5
- IDENTIFIER = 'com.apple.instruments.server.services.device.applictionListing'
5
+ IDENTIFIER = "com.apple.instruments.server.services.device.applictionListing"
6
6
 
7
7
  def __init__(self, dvt):
8
8
  self._channel = dvt.make_channel(self.IDENTIFIER)
@@ -12,8 +12,7 @@ class ApplicationListing:
12
12
  Get the applications list from the device.
13
13
  :return: List of applications and their attributes.
14
14
  """
15
- self._channel.installedApplicationsMatching_registerUpdateToken_(
16
- MessageAux().append_obj({}).append_obj(''))
15
+ self._channel.installedApplicationsMatching_registerUpdateToken_(MessageAux().append_obj({}).append_obj(""))
17
16
  result = self._channel.receive_plist()
18
17
  assert isinstance(result, list)
19
18
  return result
@@ -5,7 +5,7 @@ from pymobiledevice3.services.remote_server import MessageAux
5
5
 
6
6
 
7
7
  class ConditionInducer:
8
- IDENTIFIER = 'com.apple.instruments.server.services.ConditionInducer'
8
+ IDENTIFIER = "com.apple.instruments.server.services.ConditionInducer"
9
9
 
10
10
  def __init__(self, dvt):
11
11
  self.logger = logging.getLogger(__name__)
@@ -17,15 +17,16 @@ class ConditionInducer:
17
17
 
18
18
  def set(self, profile_identifier):
19
19
  for group in self.list():
20
- for profile in group.get('profiles'):
21
- if profile_identifier == profile.get('identifier'):
22
- self.logger.info(profile.get('description'))
20
+ for profile in group.get("profiles"):
21
+ if profile_identifier == profile.get("identifier"):
22
+ self.logger.info(profile.get("description"))
23
23
  self._channel.enableConditionWithIdentifier_profileIdentifier_(
24
- MessageAux().append_obj(group.get('identifier')).append_obj(profile.get('identifier')))
24
+ MessageAux().append_obj(group.get("identifier")).append_obj(profile.get("identifier"))
25
+ )
25
26
  # wait for response which may be a raised NSError
26
27
  self._channel.receive_plist()
27
28
  return
28
- raise PyMobileDevice3Exception('Invalid profile identifier')
29
+ raise PyMobileDevice3Exception("Invalid profile identifier")
29
30
 
30
31
  def clear(self):
31
32
  self._channel.disableActiveCondition()