pythonnative 0.49.0__tar.gz → 0.51.0__tar.gz

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 (635) hide show
  1. {pythonnative-0.49.0 → pythonnative-0.51.0}/.github/workflows/release.yml +80 -0
  2. {pythonnative-0.49.0/src/pythonnative.egg-info → pythonnative-0.51.0}/PKG-INFO +7 -5
  3. {pythonnative-0.49.0 → pythonnative-0.51.0}/README.md +5 -4
  4. {pythonnative-0.49.0 → pythonnative-0.51.0}/pyproject.toml +6 -2
  5. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/__init__.py +1 -1
  6. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/bootstrap.py +5 -0
  7. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/bridge/commits.py +1 -1
  8. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/bridge/web.py +1 -0
  9. pythonnative-0.51.0/src/pythonnative/cli/keys.py +178 -0
  10. pythonnative-0.51.0/src/pythonnative/cli/launch.py +261 -0
  11. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/cli/pn.py +292 -130
  12. pythonnative-0.51.0/src/pythonnative/devclient.py +1452 -0
  13. pythonnative-0.51.0/src/pythonnative/devserver/compat.py +176 -0
  14. pythonnative-0.51.0/src/pythonnative/devserver/editor.py +95 -0
  15. pythonnative-0.51.0/src/pythonnative/devserver/hub.py +464 -0
  16. pythonnative-0.51.0/src/pythonnative/devserver/packages.py +226 -0
  17. pythonnative-0.51.0/src/pythonnative/devserver/qr.py +526 -0
  18. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/server.py +399 -30
  19. pythonnative-0.51.0/src/pythonnative/devserver/static/devsupport.js +358 -0
  20. pythonnative-0.51.0/src/pythonnative/devserver/static/devtools/connection.js +136 -0
  21. pythonnative-0.51.0/src/pythonnative/devserver/static/devtools/devtools.css +753 -0
  22. pythonnative-0.51.0/src/pythonnative/devserver/static/devtools/devtools.js +379 -0
  23. pythonnative-0.51.0/src/pythonnative/devserver/static/devtools/index.html +49 -0
  24. pythonnative-0.51.0/src/pythonnative/devserver/static/devtools/panels/components.js +610 -0
  25. pythonnative-0.51.0/src/pythonnative/devserver/static/devtools/panels/connect.js +166 -0
  26. pythonnative-0.51.0/src/pythonnative/devserver/static/devtools/panels/console.js +343 -0
  27. pythonnative-0.51.0/src/pythonnative/devserver/static/devtools/panels/network.js +306 -0
  28. pythonnative-0.51.0/src/pythonnative/devserver/static/devtools/panels/panel.js +50 -0
  29. pythonnative-0.51.0/src/pythonnative/devserver/static/devtools/panels/performance.js +435 -0
  30. pythonnative-0.51.0/src/pythonnative/devserver/static/devtools/panels/problems.js +175 -0
  31. pythonnative-0.51.0/src/pythonnative/devserver/static/devtools/report.js +134 -0
  32. pythonnative-0.51.0/src/pythonnative/devserver/static/devtools/tree.js +143 -0
  33. pythonnative-0.51.0/src/pythonnative/devserver/static/devtools/util.js +184 -0
  34. pythonnative-0.51.0/src/pythonnative/devserver/static/devtools/values.js +79 -0
  35. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/static/host.js +111 -21
  36. pythonnative-0.51.0/src/pythonnative/devserver/static/index.html +108 -0
  37. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/static/layout.js +29 -1
  38. pythonnative-0.51.0/src/pythonnative/devserver/static/preview.css +880 -0
  39. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/static/renderer.js +314 -45
  40. pythonnative-0.51.0/src/pythonnative/devserver/static/shell.js +590 -0
  41. pythonnative-0.51.0/src/pythonnative/devtools/__init__.py +16 -0
  42. pythonnative-0.51.0/src/pythonnative/devtools/agent.py +524 -0
  43. pythonnative-0.51.0/src/pythonnative/devtools/console.py +134 -0
  44. pythonnative-0.51.0/src/pythonnative/devtools/debugger.py +164 -0
  45. pythonnative-0.51.0/src/pythonnative/devtools/inspector.py +381 -0
  46. pythonnative-0.51.0/src/pythonnative/devtools/perf.py +194 -0
  47. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/diagnostics.py +67 -0
  48. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/element.py +4 -2
  49. pythonnative-0.51.0/src/pythonnative/errors.py +422 -0
  50. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/gestures.py +17 -17
  51. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/hooks.py +7 -3
  52. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/hosts/base.py +8 -5
  53. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/hosts/native.py +14 -0
  54. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/hot_reload.py +18 -9
  55. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/generated/NativeProps.kt +502 -502
  56. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/generated/NativeValues.kt +22 -0
  57. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/generated/PNContracts.kt +3 -3
  58. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/TransactionApplier.kt +18 -1
  59. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/BuiltinModules.kt +13 -2
  60. pythonnative-0.51.0/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/DevSupportModule.kt +429 -0
  61. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/DeviceModules.kt +14 -3
  62. pythonnative-0.51.0/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/ErrorOverlay.kt +220 -0
  63. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/HostModule.kt +1 -1
  64. pythonnative-0.51.0/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/DevSupportRobolectricTest.kt +196 -0
  65. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Bridge/PNRegistry.swift +1 -0
  66. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Bridge/PNTransaction.swift +26 -1
  67. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Generated/NativeProps.swift +502 -502
  68. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Generated/NativeValues.swift +40 -1
  69. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Generated/PNContracts.swift +3 -3
  70. pythonnative-0.51.0/src/pythonnative/native/ios/Sources/PythonNativeKit/Modules/DevSupportModule.swift +381 -0
  71. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Modules/HostModule.swift +1 -1
  72. pythonnative-0.51.0/src/pythonnative/native/ios/Sources/PythonNativeKit/Modules/PNErrorOverlay.swift +269 -0
  73. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Support/PNWindow.swift +28 -2
  74. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNCommitTests.swift +30 -0
  75. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNModuleTests.swift +105 -0
  76. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native_modules/linking.py +20 -0
  77. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/net.py +99 -2
  78. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/preview.py +134 -18
  79. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/project/android.py +11 -4
  80. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/project/builder.py +27 -6
  81. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/project/bundle.py +3 -1
  82. pythonnative-0.51.0/src/pythonnative/project/go.py +383 -0
  83. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/project/ios.py +9 -2
  84. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/reconciler/core.py +44 -3
  85. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/sdk/_builtin_contracts.json +1 -1
  86. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/sdk/codegen.py +2 -2
  87. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/sdk/templates/contracts.kt +1 -1
  88. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/sdk/templates/contracts.swift +1 -1
  89. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/sdk/templates/values.kt +22 -0
  90. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/sdk/templates/values.swift +40 -1
  91. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/MainActivity.kt +13 -10
  92. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/ios_template/ios_template/SceneDelegate.swift +3 -1
  93. {pythonnative-0.49.0 → pythonnative-0.51.0/src/pythonnative.egg-info}/PKG-INFO +7 -5
  94. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative.egg-info/SOURCES.txt +40 -0
  95. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative.egg-info/requires.txt +1 -0
  96. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_cli.py +44 -38
  97. pythonnative-0.51.0/tests/test_cli_keys.py +153 -0
  98. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_devclient.py +75 -34
  99. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_devserver.py +20 -4
  100. pythonnative-0.51.0/tests/test_devserver_session.py +496 -0
  101. pythonnative-0.51.0/tests/test_devtools.py +300 -0
  102. pythonnative-0.51.0/tests/test_devtools_page.py +224 -0
  103. pythonnative-0.51.0/tests/test_errors.py +173 -0
  104. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_hosts.py +1 -1
  105. pythonnative-0.51.0/tests/test_qr.py +279 -0
  106. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_release_packaging.py +3 -0
  107. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_runtime_correctness.py +1 -1
  108. pythonnative-0.49.0/src/pythonnative/devclient.py +0 -869
  109. pythonnative-0.49.0/src/pythonnative/devserver/static/index.html +0 -60
  110. pythonnative-0.49.0/src/pythonnative/devserver/static/preview.css +0 -482
  111. pythonnative-0.49.0/src/pythonnative/devserver/static/shell.js +0 -374
  112. pythonnative-0.49.0/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/ErrorOverlay.kt +0 -42
  113. pythonnative-0.49.0/src/pythonnative/native/ios/Sources/PythonNativeKit/Modules/PNErrorOverlay.swift +0 -47
  114. {pythonnative-0.49.0 → pythonnative-0.51.0}/LICENSE +0 -0
  115. {pythonnative-0.49.0 → pythonnative-0.51.0}/MANIFEST.in +0 -0
  116. {pythonnative-0.49.0 → pythonnative-0.51.0}/scripts/check-distributions.py +0 -0
  117. {pythonnative-0.49.0 → pythonnative-0.51.0}/scripts/cibuildwheel.toml +0 -0
  118. {pythonnative-0.49.0 → pythonnative-0.51.0}/scripts/release-assets.py +0 -0
  119. {pythonnative-0.49.0 → pythonnative-0.51.0}/setup.cfg +0 -0
  120. {pythonnative-0.49.0 → pythonnative-0.51.0}/setup.py +0 -0
  121. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/_ios_log.py +0 -0
  122. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/alerts.py +0 -0
  123. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/animated.py +0 -0
  124. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/animation_graph.py +0 -0
  125. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/appearance.py +0 -0
  126. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/assets/__init__.py +0 -0
  127. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/assets/fonts.py +0 -0
  128. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/bridge/__init__.py +0 -0
  129. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/bridge/android.py +0 -0
  130. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/bridge/codec.py +0 -0
  131. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/bridge/fake.py +0 -0
  132. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/bridge/ios.py +0 -0
  133. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/bridge/list_store.py +0 -0
  134. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/cli/__init__.py +0 -0
  135. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/component.py +0 -0
  136. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/components/__init__.py +0 -0
  137. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/components/_base.py +0 -0
  138. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/components/controls.py +0 -0
  139. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/components/events.py +0 -0
  140. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/components/graphics.py +0 -0
  141. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/components/layout.py +0 -0
  142. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/components/lists.py +0 -0
  143. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/components/media.py +0 -0
  144. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/components/overlays.py +0 -0
  145. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/components/pressable.py +0 -0
  146. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/components/props.py +0 -0
  147. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/components/structural.py +0 -0
  148. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/components/text.py +0 -0
  149. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/__init__.py +0 -0
  150. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/auth.py +0 -0
  151. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/static/animation_graph.js +0 -0
  152. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/static/assets.js +0 -0
  153. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/static/bridge.js +0 -0
  154. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/static/colors.js +0 -0
  155. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/static/contracts.js +0 -0
  156. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/static/list-store.js +0 -0
  157. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/static/yoga/LICENSE +0 -0
  158. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/static/yoga/binaries/yoga-wasm-base64-esm.js +0 -0
  159. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/static/yoga/src/generated/YGEnums.d.ts +0 -0
  160. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/static/yoga/src/generated/YGEnums.js +0 -0
  161. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/static/yoga/src/generated/YGEnums.js.map +0 -0
  162. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/static/yoga/src/index.d.ts +0 -0
  163. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/static/yoga/src/index.js +0 -0
  164. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/static/yoga/src/index.js.map +0 -0
  165. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/static/yoga/src/load.d.ts +0 -0
  166. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/static/yoga/src/load.js +0 -0
  167. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/static/yoga/src/load.js.map +0 -0
  168. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/static/yoga/src/wrapAssembly.d.ts +0 -0
  169. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/static/yoga/src/wrapAssembly.js +0 -0
  170. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/static/yoga/src/wrapAssembly.js.map +0 -0
  171. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/watcher.py +0 -0
  172. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/devserver/ws.py +0 -0
  173. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/equality.py +0 -0
  174. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/events.py +0 -0
  175. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/handles.py +0 -0
  176. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/hosts/__init__.py +0 -0
  177. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/icons/LICENSE-lucide.txt +0 -0
  178. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/icons/__init__.py +0 -0
  179. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/icons/_lucide.json +0 -0
  180. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/icons/_names.py +0 -0
  181. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/journal.py +0 -0
  182. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/layout.py +0 -0
  183. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/lint.py +0 -0
  184. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/list_data.py +0 -0
  185. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/mutations.py +0 -0
  186. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/build.gradle +0 -0
  187. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/gradle.properties +0 -0
  188. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/settings.gradle +0 -0
  189. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/AndroidManifest.xml +0 -0
  190. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/cpp/CMakeLists.txt +0 -0
  191. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/cpp/yoga_jni.cpp +0 -0
  192. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/generated/NativeModules.kt +0 -0
  193. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/PNBridge.kt +0 -0
  194. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/PythonHost.kt +0 -0
  195. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/animation/AnimationGraph.kt +0 -0
  196. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/animation/AnimationSpecs.kt +0 -0
  197. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/animation/PNAnimator.kt +0 -0
  198. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/assets/PNAssets.kt +0 -0
  199. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/CommitState.kt +0 -0
  200. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/JsonUtil.kt +0 -0
  201. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/MainThread.kt +0 -0
  202. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/PNLog.kt +0 -0
  203. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/PNRegistry.kt +0 -0
  204. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/PNTransaction.kt +0 -0
  205. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/ViewRegistry.kt +0 -0
  206. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/BuiltinComponents.kt +0 -0
  207. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ButtonManager.kt +0 -0
  208. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ComponentManager.kt +0 -0
  209. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ContainerManagers.kt +0 -0
  210. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ControlManagers.kt +0 -0
  211. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/DatePickerManager.kt +0 -0
  212. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/EffectManagers.kt +0 -0
  213. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ImageLoader.kt +0 -0
  214. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ImageManager.kt +0 -0
  215. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ListStore.kt +0 -0
  216. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ModalManager.kt +0 -0
  217. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/PNColor.kt +0 -0
  218. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/PNTheme.kt +0 -0
  219. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/PickerManager.kt +0 -0
  220. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/PortalManager.kt +0 -0
  221. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/PressableManager.kt +0 -0
  222. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ScreenStackManager.kt +0 -0
  223. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ScreenTransitions.kt +0 -0
  224. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ScrollViewManager.kt +0 -0
  225. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/SegmentedControlManager.kt +0 -0
  226. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/StatusBarManager.kt +0 -0
  227. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/SvgManager.kt +0 -0
  228. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/TabBarManager.kt +0 -0
  229. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/TextInputManager.kt +0 -0
  230. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/TextManager.kt +0 -0
  231. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ViewStyler.kt +0 -0
  232. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/VirtualListManager.kt +0 -0
  233. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/WebViewManager.kt +0 -0
  234. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/gestures/GestureArbiter.kt +0 -0
  235. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/gestures/GestureCoordinator.kt +0 -0
  236. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/gestures/GestureRecognizers.kt +0 -0
  237. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/graphics/SvgPath.kt +0 -0
  238. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/layout/NativeLayout.kt +0 -0
  239. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/layout/YogaNode.kt +0 -0
  240. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/AssetModules.kt +0 -0
  241. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/MediaModules.kt +0 -0
  242. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/NativeModule.kt +0 -0
  243. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/NotificationsModule.kt +0 -0
  244. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/PermissionsModule.kt +0 -0
  245. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/PlatformModules.kt +0 -0
  246. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/StorageModules.kt +0 -0
  247. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/SystemModules.kt +0 -0
  248. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/plugins/GeneratedPlugins.kt +0 -0
  249. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/screens/PNKeyboard.kt +0 -0
  250. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/screens/PNScreenFragment.kt +0 -0
  251. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/screens/ScreenRegistry.kt +0 -0
  252. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/views/PNAccessibilityDelegate.kt +0 -0
  253. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/views/PNBorderDrawable.kt +0 -0
  254. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/views/PNEditText.kt +0 -0
  255. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/views/PNFrameLayout.kt +0 -0
  256. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/views/PNScrollViews.kt +0 -0
  257. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/res/anim/pn_fade_in.xml +0 -0
  258. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/res/anim/pn_fade_out.xml +0 -0
  259. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/res/anim/pn_hold.xml +0 -0
  260. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/res/anim/pn_slide_in_bottom.xml +0 -0
  261. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/res/anim/pn_slide_in_left.xml +0 -0
  262. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/res/anim/pn_slide_in_right.xml +0 -0
  263. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/res/anim/pn_slide_out_bottom.xml +0 -0
  264. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/res/anim/pn_slide_out_left.xml +0 -0
  265. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/res/anim/pn_slide_out_right.xml +0 -0
  266. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/res/drawable/pn_ic_arrow_back.xml +0 -0
  267. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/res/values/pn_ids.xml +0 -0
  268. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/main/res/xml/pn_file_paths.xml +0 -0
  269. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/generated/PNRecordFixtures.kt +0 -0
  270. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/AnimationSpecsTest.kt +0 -0
  271. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/AssetsAndSvgTest.kt +0 -0
  272. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/ContractFixtureTest.kt +0 -0
  273. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/GestureArbiterTest.kt +0 -0
  274. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/NativeLifecycleTest.kt +0 -0
  275. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/PNColorTest.kt +0 -0
  276. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/PNTransactionTest.kt +0 -0
  277. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/PromiseTest.kt +0 -0
  278. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/RoundOneRobolectricTest.kt +0 -0
  279. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/RoundTwoLogicTest.kt +0 -0
  280. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/RoundTwoRobolectricTest.kt +0 -0
  281. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/ScreenTransitionsTest.kt +0 -0
  282. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/StyleAccessibilityDeviceTest.kt +0 -0
  283. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Package.swift +0 -0
  284. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Animation/PNAnimationGraph.swift +0 -0
  285. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Animation/PNAnimator.swift +0 -0
  286. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Bridge/PNBridge.swift +0 -0
  287. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Bridge/PNCommit.swift +0 -0
  288. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Bridge/PNViewRegistry.swift +0 -0
  289. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNButtonManagers.swift +0 -0
  290. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNColor.swift +0 -0
  291. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNComponentManager.swift +0 -0
  292. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNContainerView.swift +0 -0
  293. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNControlManagers.swift +0 -0
  294. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNEffectManagers.swift +0 -0
  295. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNImageManager.swift +0 -0
  296. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNListStore.swift +0 -0
  297. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNOverlayManagers.swift +0 -0
  298. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNPressableManager.swift +0 -0
  299. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNScreenStackManager.swift +0 -0
  300. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNScrollViewManager.swift +0 -0
  301. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNSvgManager.swift +0 -0
  302. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNTabBarManager.swift +0 -0
  303. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNTextInputManager.swift +0 -0
  304. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNTextManager.swift +0 -0
  305. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNTransform.swift +0 -0
  306. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNViewManager.swift +0 -0
  307. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNViewState.swift +0 -0
  308. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNViewStyler.swift +0 -0
  309. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNVirtualListManager.swift +0 -0
  310. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNWebViewManager.swift +0 -0
  311. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Generated/NativeModules.swift +0 -0
  312. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Gestures/PNGestureCoordinator.swift +0 -0
  313. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Layout/PNLayout.swift +0 -0
  314. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Modules/AlertModule.swift +0 -0
  315. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Modules/EnvironmentModules.swift +0 -0
  316. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Modules/ImagesModule.swift +0 -0
  317. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Modules/LifecycleModules.swift +0 -0
  318. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Modules/MediaModules.swift +0 -0
  319. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Modules/PNNativeModule.swift +0 -0
  320. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Modules/PermissionModules.swift +0 -0
  321. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Modules/SystemModules.swift +0 -0
  322. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Plugins/PNPluginRegistration.swift +0 -0
  323. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Resources/PrivacyInfo.xcprivacy +0 -0
  324. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Screens/PNScreenRegistry.swift +0 -0
  325. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Screens/PNViewController.swift +0 -0
  326. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Support/PNAssets.swift +0 -0
  327. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Support/PNCompat.swift +0 -0
  328. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Support/PNJSON.swift +0 -0
  329. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Support/PNLog.swift +0 -0
  330. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Tests/NativeTests.xcodeproj/project.pbxproj +0 -0
  331. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Tests/NativeTests.xcodeproj/xcshareddata/xcschemes/NativeTests.xcscheme +0 -0
  332. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/Fixtures/validation.json +0 -0
  333. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNAnimationGraphTests.swift +0 -0
  334. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNAssetTests.swift +0 -0
  335. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNColorTests.swift +0 -0
  336. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNContractFixtureTests.swift +0 -0
  337. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNContractParityTests.swift +0 -0
  338. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNGestureTests.swift +0 -0
  339. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNLifecycleTests.swift +0 -0
  340. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNManagerTests.swift +0 -0
  341. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNParityTests.swift +0 -0
  342. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNRecordFixtures.swift +0 -0
  343. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNTransactionTests.swift +0 -0
  344. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/ios/Tests/TestHost/main.swift +0 -0
  345. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/LICENSE +0 -0
  346. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/Package.swift +0 -0
  347. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/VENDORED.md +0 -0
  348. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/include/PNStyle.h +0 -0
  349. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/include/module.modulemap +0 -0
  350. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/include/yoga/YGConfig.h +0 -0
  351. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/include/yoga/YGEnums.h +0 -0
  352. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/include/yoga/YGMacros.h +0 -0
  353. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/include/yoga/YGNode.h +0 -0
  354. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/include/yoga/YGNodeLayout.h +0 -0
  355. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/include/yoga/YGNodeStyle.h +0 -0
  356. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/include/yoga/YGPixelGrid.h +0 -0
  357. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/include/yoga/YGValue.h +0 -0
  358. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/include/yoga/Yoga.h +0 -0
  359. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/python.cpp +0 -0
  360. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/style.cpp +0 -0
  361. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/CMakeLists.txt +0 -0
  362. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/YGConfig.cpp +0 -0
  363. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/YGConfig.h +0 -0
  364. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/YGEnums.cpp +0 -0
  365. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/YGEnums.h +0 -0
  366. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/YGMacros.h +0 -0
  367. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/YGNode.cpp +0 -0
  368. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/YGNode.h +0 -0
  369. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/YGNodeLayout.cpp +0 -0
  370. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/YGNodeLayout.h +0 -0
  371. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/YGNodeStyle.cpp +0 -0
  372. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/YGNodeStyle.h +0 -0
  373. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/YGPixelGrid.cpp +0 -0
  374. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/YGPixelGrid.h +0 -0
  375. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/YGValue.cpp +0 -0
  376. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/YGValue.h +0 -0
  377. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/Yoga.h +0 -0
  378. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/algorithm/AbsoluteLayout.cpp +0 -0
  379. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/algorithm/AbsoluteLayout.h +0 -0
  380. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/algorithm/Align.h +0 -0
  381. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/algorithm/Baseline.cpp +0 -0
  382. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/algorithm/Baseline.h +0 -0
  383. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/algorithm/BoundAxis.h +0 -0
  384. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/algorithm/Cache.cpp +0 -0
  385. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/algorithm/Cache.h +0 -0
  386. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/algorithm/CalculateLayout.cpp +0 -0
  387. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/algorithm/CalculateLayout.h +0 -0
  388. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/algorithm/FlexDirection.h +0 -0
  389. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/algorithm/FlexLine.cpp +0 -0
  390. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/algorithm/FlexLine.h +0 -0
  391. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/algorithm/PixelGrid.cpp +0 -0
  392. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/algorithm/PixelGrid.h +0 -0
  393. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/algorithm/SizingMode.h +0 -0
  394. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/algorithm/TrailingPosition.h +0 -0
  395. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/config/Config.cpp +0 -0
  396. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/config/Config.h +0 -0
  397. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/debug/AssertFatal.cpp +0 -0
  398. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/debug/AssertFatal.h +0 -0
  399. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/debug/Log.cpp +0 -0
  400. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/debug/Log.h +0 -0
  401. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/enums/Align.h +0 -0
  402. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/enums/BoxSizing.h +0 -0
  403. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/enums/Dimension.h +0 -0
  404. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/enums/Direction.h +0 -0
  405. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/enums/Display.h +0 -0
  406. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/enums/Edge.h +0 -0
  407. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/enums/Errata.h +0 -0
  408. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/enums/ExperimentalFeature.h +0 -0
  409. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/enums/FlexDirection.h +0 -0
  410. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/enums/Gutter.h +0 -0
  411. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/enums/Justify.h +0 -0
  412. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/enums/LogLevel.h +0 -0
  413. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/enums/MeasureMode.h +0 -0
  414. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/enums/NodeType.h +0 -0
  415. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/enums/Overflow.h +0 -0
  416. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/enums/PhysicalEdge.h +0 -0
  417. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/enums/PositionType.h +0 -0
  418. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/enums/Unit.h +0 -0
  419. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/enums/Wrap.h +0 -0
  420. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/enums/YogaEnums.h +0 -0
  421. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/event/event.cpp +0 -0
  422. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/event/event.h +0 -0
  423. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/module.modulemap +0 -0
  424. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/node/CachedMeasurement.h +0 -0
  425. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/node/LayoutResults.cpp +0 -0
  426. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/node/LayoutResults.h +0 -0
  427. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/node/LayoutableChildren.h +0 -0
  428. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/node/Node.cpp +0 -0
  429. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/node/Node.h +0 -0
  430. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/numeric/Comparison.h +0 -0
  431. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/numeric/FloatOptional.h +0 -0
  432. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/style/SmallValueBuffer.h +0 -0
  433. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/style/Style.h +0 -0
  434. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/style/StyleLength.h +0 -0
  435. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/style/StyleValueHandle.h +0 -0
  436. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native/yoga/yoga/style/StyleValuePool.h +0 -0
  437. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native_modules/__init__.py +0 -0
  438. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native_modules/accessibility_info.py +0 -0
  439. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native_modules/app_state.py +0 -0
  440. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native_modules/battery.py +0 -0
  441. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native_modules/biometrics.py +0 -0
  442. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native_modules/camera.py +0 -0
  443. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native_modules/clipboard.py +0 -0
  444. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native_modules/device.py +0 -0
  445. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native_modules/dimensions.py +0 -0
  446. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native_modules/fallback.py +0 -0
  447. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native_modules/file_system.py +0 -0
  448. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native_modules/haptics.py +0 -0
  449. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native_modules/images.py +0 -0
  450. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native_modules/keyboard.py +0 -0
  451. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native_modules/localization.py +0 -0
  452. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native_modules/location.py +0 -0
  453. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native_modules/net_info.py +0 -0
  454. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native_modules/notifications.py +0 -0
  455. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native_modules/permissions.py +0 -0
  456. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native_modules/registry.py +0 -0
  457. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native_modules/secure_store.py +0 -0
  458. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native_modules/share.py +0 -0
  459. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native_views/__init__.py +0 -0
  460. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/native_views/bridge_backend.py +0 -0
  461. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/navigation/__init__.py +0 -0
  462. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/navigation/container.py +0 -0
  463. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/navigation/handle.py +0 -0
  464. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/navigation/hooks.py +0 -0
  465. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/navigation/host.py +0 -0
  466. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/navigation/linking.py +0 -0
  467. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/navigation/navigators.py +0 -0
  468. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/navigation/ref.py +0 -0
  469. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/navigation/screen.py +0 -0
  470. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/navigation/state.py +0 -0
  471. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/platform.py +0 -0
  472. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/platform_metrics.py +0 -0
  473. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/profiling.py +0 -0
  474. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/project/__init__.py +0 -0
  475. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/project/artifacts.py +0 -0
  476. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/project/bytecode.py +0 -0
  477. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/project/config.py +0 -0
  478. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/project/deps.py +0 -0
  479. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/project/devices.py +0 -0
  480. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/project/doctor.py +0 -0
  481. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/project/fingerprint.py +0 -0
  482. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/project/icons.py +0 -0
  483. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/project/lockfile.py +0 -0
  484. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/project/permissions.py +0 -0
  485. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/project/plugins.py +0 -0
  486. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/project/runtime_assets.py +0 -0
  487. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/prop_checks.py +0 -0
  488. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/py.typed +0 -0
  489. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/query.py +0 -0
  490. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/reconciler/__init__.py +0 -0
  491. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/reconciler/boundaries.py +0 -0
  492. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/reconciler/children.py +0 -0
  493. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/reconciler/layout_pass.py +0 -0
  494. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/reconciler/vnode.py +0 -0
  495. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/refresh.py +0 -0
  496. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/runtime.py +0 -0
  497. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/scheduler.py +0 -0
  498. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/sdk/__init__.py +0 -0
  499. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/sdk/_components.py +0 -0
  500. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/sdk/builtins.py +0 -0
  501. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/sdk/commands.py +0 -0
  502. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/sdk/contract_codegen.py +0 -0
  503. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/sdk/module_codegen.py +0 -0
  504. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/sdk/native_types.py +0 -0
  505. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/sdk/schema.py +0 -0
  506. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/sdk/services.py +0 -0
  507. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/sdk/types.py +0 -0
  508. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/storage.py +0 -0
  509. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/store.py +0 -0
  510. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/style.py +0 -0
  511. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/suspense.py +0 -0
  512. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/svg.py +0 -0
  513. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/build.gradle +0 -0
  514. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/proguard-rules.pro +0 -0
  515. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/debug/AndroidManifest.xml +0 -0
  516. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/main/AndroidManifest.xml +0 -0
  517. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/ScreenFragment.kt +0 -0
  518. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/main/res/drawable/ic_launcher_background.xml +0 -0
  519. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +0 -0
  520. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/main/res/layout/activity_main.xml +0 -0
  521. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +0 -0
  522. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +0 -0
  523. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-hdpi/ic_launcher.webp +0 -0
  524. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp +0 -0
  525. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-mdpi/ic_launcher.webp +0 -0
  526. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp +0 -0
  527. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xhdpi/ic_launcher.webp +0 -0
  528. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp +0 -0
  529. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp +0 -0
  530. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp +0 -0
  531. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp +0 -0
  532. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp +0 -0
  533. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/main/res/navigation/nav_graph.xml +0 -0
  534. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/main/res/values/colors.xml +0 -0
  535. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/main/res/values/strings.xml +0 -0
  536. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/main/res/values/themes.xml +0 -0
  537. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/main/res/values-night/themes.xml +0 -0
  538. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/main/res/xml/backup_rules.xml +0 -0
  539. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/app/src/main/res/xml/data_extraction_rules.xml +0 -0
  540. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/build.gradle +0 -0
  541. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/gradle/wrapper/gradle-wrapper.jar +0 -0
  542. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/gradle/wrapper/gradle-wrapper.properties +0 -0
  543. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/gradle.properties +0 -0
  544. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/gradlew +0 -0
  545. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/gradlew.bat +0 -0
  546. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/android_template/settings.gradle +0 -0
  547. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/ios_template/PNFinalizePython.sh +0 -0
  548. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/ios_template/ios_template/AppDelegate.swift +0 -0
  549. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/ios_template/ios_template/Assets.xcassets/AccentColor.colorset/Contents.json +0 -0
  550. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/ios_template/ios_template/Assets.xcassets/AppIcon.appiconset/Contents.json +0 -0
  551. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/ios_template/ios_template/Assets.xcassets/Contents.json +0 -0
  552. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/ios_template/ios_template/Base.lproj/LaunchScreen.storyboard +0 -0
  553. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/ios_template/ios_template/BridgingHeader.h +0 -0
  554. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/ios_template/ios_template/Info.plist +0 -0
  555. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/ios_template/ios_template/PrivacyInfo.xcprivacy +0 -0
  556. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/ios_template/ios_template/PythonRuntime.swift +0 -0
  557. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/ios_template/ios_template/ViewController.swift +0 -0
  558. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/ios_template/ios_template.xcodeproj/project.pbxproj +0 -0
  559. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/templates/ios_template/ios_template.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -0
  560. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/testing/__init__.py +0 -0
  561. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/testing/backend.py +0 -0
  562. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/testing/clock.py +0 -0
  563. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/testing/harness.py +0 -0
  564. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/testing/pytest_plugin.py +0 -0
  565. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/testing/queries.py +0 -0
  566. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/theme.py +0 -0
  567. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative/utils.py +0 -0
  568. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative.egg-info/dependency_links.txt +0 -0
  569. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative.egg-info/entry_points.txt +0 -0
  570. {pythonnative-0.49.0 → pythonnative-0.51.0}/src/pythonnative.egg-info/top_level.txt +0 -0
  571. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_alert.py +0 -0
  572. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_animated.py +0 -0
  573. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_animated_easing.py +0 -0
  574. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_animated_graph.py +0 -0
  575. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_appearance.py +0 -0
  576. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_assets.py +0 -0
  577. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_async_hooks.py +0 -0
  578. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_authoring.py +0 -0
  579. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_bridge.py +0 -0
  580. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_codegen.py +0 -0
  581. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_components.py +0 -0
  582. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_contract_fixtures.py +0 -0
  583. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_core_semantics.py +0 -0
  584. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_device_modules.py +0 -0
  585. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_devserver_ws.py +0 -0
  586. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_e2e_suite_renders.py +0 -0
  587. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_element.py +0 -0
  588. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_events.py +0 -0
  589. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_extended_components.py +0 -0
  590. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_gesture_activation.py +0 -0
  591. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_gesture_composition.py +0 -0
  592. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_gestures.py +0 -0
  593. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_handles.py +0 -0
  594. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_hooks.py +0 -0
  595. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_hot_reload.py +0 -0
  596. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_identity_bailout.py +0 -0
  597. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_inbox.py +0 -0
  598. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_incremental_pipeline.py +0 -0
  599. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_incremental_render.py +0 -0
  600. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_interaction_props.py +0 -0
  601. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_ios_log.py +0 -0
  602. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_layout.py +0 -0
  603. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_lint.py +0 -0
  604. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_list_features.py +0 -0
  605. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_metric_hooks.py +0 -0
  606. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_mutations.py +0 -0
  607. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_native_lists.py +0 -0
  608. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_native_modules.py +0 -0
  609. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_native_values.py +0 -0
  610. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_native_views.py +0 -0
  611. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_navigation.py +0 -0
  612. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_net.py +0 -0
  613. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_new_components.py +0 -0
  614. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_performance_budgets.py +0 -0
  615. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_platform.py +0 -0
  616. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_platform_metrics.py +0 -0
  617. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_reconciler.py +0 -0
  618. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_ref.py +0 -0
  619. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_release_workflow.py +0 -0
  620. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_runtime.py +0 -0
  621. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_runtime_contracts.py +0 -0
  622. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_runtime_overhaul.py +0 -0
  623. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_sdk.py +0 -0
  624. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_smoke.py +0 -0
  625. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_storage.py +0 -0
  626. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_store.py +0 -0
  627. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_style.py +0 -0
  628. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_suspense.py +0 -0
  629. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_testing_library.py +0 -0
  630. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_theme.py +0 -0
  631. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_transitions.py +0 -0
  632. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_typed_events.py +0 -0
  633. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_typing_conformance.py +0 -0
  634. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_utils.py +0 -0
  635. {pythonnative-0.49.0 → pythonnative-0.51.0}/tests/test_web_transport.py +0 -0
@@ -113,3 +113,83 @@ jobs:
113
113
  uses: pypa/gh-action-pypi-publish@release/v1
114
114
  with:
115
115
  skip-existing: true
116
+
117
+ # PythonNative Go, the prebuilt dev client, ships as release assets that
118
+ # `pn go` downloads for the matching version (RFC 0006). Its builds run
119
+ # after PyPI publishing so a toolchain hiccup never blocks the package.
120
+ go:
121
+ name: Build PythonNative Go (${{ matrix.name }})
122
+ needs: [release, publish]
123
+ if: needs.release.outputs.tag != '' && needs.release.outputs.commit != ''
124
+ strategy:
125
+ fail-fast: false
126
+ matrix:
127
+ # The simulator app's Python runtime is staged for one architecture,
128
+ # so each Mac architecture gets its own asset, built on a runner of
129
+ # that architecture (`pn go` downloads the one matching the Mac).
130
+ include:
131
+ - name: ios-arm64
132
+ platform: ios
133
+ runner: macos-15
134
+ - name: ios-x86_64
135
+ platform: ios
136
+ runner: macos-15-intel
137
+ - name: android
138
+ platform: android
139
+ runner: ubuntu-24.04
140
+ runs-on: ${{ matrix.runner }}
141
+ env:
142
+ DEVELOPER_DIR: /Applications/Xcode_26.3.app/Contents/Developer
143
+ timeout-minutes: 45
144
+ steps:
145
+ - uses: actions/checkout@v4
146
+ with:
147
+ ref: ${{ needs.release.outputs.commit }}
148
+ - uses: astral-sh/setup-uv@v10.0.1
149
+ with:
150
+ enable-cache: true
151
+ python-version: '3.13'
152
+ - name: Set up Java 17
153
+ if: matrix.platform == 'android'
154
+ uses: actions/setup-java@v4
155
+ with:
156
+ distribution: 'temurin'
157
+ java-version: '17'
158
+ - name: Set up Gradle
159
+ if: matrix.platform == 'android'
160
+ uses: gradle/actions/setup-gradle@v4
161
+ - name: Install PythonNative
162
+ run: uv sync --locked
163
+ - name: Build and package
164
+ run: uv run python scripts/build-go.py --platform ${{ matrix.platform }} --out go-dist
165
+ - uses: actions/upload-artifact@v4
166
+ with:
167
+ name: go-${{ matrix.name }}
168
+ path: go-dist/
169
+ if-no-files-found: error
170
+
171
+ go-assets:
172
+ name: Attach PythonNative Go to the release
173
+ needs: [release, go]
174
+ runs-on: ubuntu-24.04
175
+ permissions:
176
+ contents: write
177
+ steps:
178
+ - uses: actions/checkout@v4
179
+ with:
180
+ ref: ${{ needs.release.outputs.commit }}
181
+ - uses: actions/download-artifact@v4
182
+ with:
183
+ pattern: go-*
184
+ path: go-dist
185
+ merge-multiple: true
186
+ - uses: astral-sh/setup-uv@v10.0.1
187
+ with:
188
+ python-version: '3.13'
189
+ - name: Write checksums
190
+ run: uv run python scripts/build-go.py --checksums go-dist
191
+ - name: Upload
192
+ env:
193
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
194
+ RELEASE_TAG: ${{ needs.release.outputs.tag }}
195
+ run: gh release upload "$RELEASE_TAG" go-dist/* --clobber
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pythonnative
3
- Version: 0.49.0
3
+ Version: 0.51.0
4
4
  Summary: Cross-platform native UI toolkit for Android and iOS
5
5
  Author: Owen Carey
6
6
  License: MIT License
@@ -40,6 +40,7 @@ Classifier: Topic :: Software Development :: User Interfaces
40
40
  Requires-Python: >=3.13
41
41
  Description-Content-Type: text/markdown
42
42
  License-File: LICENSE
43
+ Requires-Dist: debugpy>=1.8
43
44
  Provides-Extra: build
44
45
  Requires-Dist: Pillow>=10.0; extra == "build"
45
46
  Dynamic: license-file
@@ -88,7 +89,9 @@ PythonNative is a cross-platform toolkit for building native Android and iOS app
88
89
  - **Device APIs:** Python facades expose camera, location, notifications, storage, permissions, keyboard, dimensions and pixel ratio, device info, localization, accessibility settings, and other native services, with a Python fallback for headless tests. Test permissions and platform behavior on your deployment targets.
89
90
  - **Native extension SDK:** Python dataclasses and protocols define contracts; `define_component` returns a typed element factory and `pn codegen` generates props and module adapters for Swift and Kotlin. Plugins package native sources and resources, and builds verify matching contracts at startup.
90
91
  - **Testing library:** `pythonnative.testing` renders components headlessly with Testing Library-style queries (`get_by_role`, `get_by_placeholder_text`, `within`, `find_by_*`), a virtual clock for timers, and a pytest plugin that resets the runtime between tests.
91
- - **Development tools:** `pn start` serves the browser preview and connected mobile dev clients. Fast Refresh preserves compatible component state, while diagnostics report errors and invalid hook usage. Changes to native inputs trigger a rebuild.
92
+ - **PythonNative Go:** a prebuilt dev client, published with each release, runs any project without native code, so the project itself is never compiled. `i` / `a` in `pn start` open it on the iOS Simulator (which still needs Xcode installed) or an Android emulator, and a phone with Go installed opens the project by scanning the QR code `pn start` prints. Go isn't in the app stores: Android phones install the APK, and iPhones need Go built and signed with your Apple team. Projects that add native code run in their own debug build, which `pn run` rebuilds only when something native changes.
93
+ - **DevTools and debugging:** `pn start` serves DevTools, with a component tree showing props and hooks (and editable state), a console with a REPL inside the running app, problems with component stacks and source excerpts, network requests, and live performance with trace capture. VS Code attaches `debugpy` breakpoints to Python on the preview, a simulator, or a phone. On device, a dev menu (shake or Cmd+D) offers reload, an element inspector, and a performance monitor, and errors show a screen with the component stack and your source.
94
+ - **Development tools:** Fast Refresh preserves compatible component state, `pn lint` checks the rules of hooks, and `pn init` scaffolds tests, type checking, debugger settings, and CI.
92
95
  - **Browser preview:** `pn preview` runs your Python application against a browser renderer with DOM widgets, Yoga WebAssembly layout, and JavaScript animation graphs. It supports iteration on application logic and UI; fonts, platform controls, and device APIs require mobile testing.
93
96
  - **App packaging and dependency locks:** `pn run` and `pn build` stage bundled app templates, native libraries, and Python sources. Target-specific wheel locks record dependency versions and hashes for mobile builds. Binary dependencies need compatible mobile wheels; `pn deps` reports target resolution.
94
97
 
@@ -125,9 +128,8 @@ def App() -> pn.Node:
125
128
 
126
129
  ```bash
127
130
  pn init my-app && cd my-app
128
- pn preview # dev server + browser preview with Fast Refresh
129
- pn run ios # in another terminal: debug build that connects to the same server
130
- pn run android
131
+ pn start # dev server: scan the QR code, or press i (iOS), a (Android), w (browser), j (DevTools)
132
+ pn run ios # the project's own debug build, for projects that add native code
131
133
  pn build ios # standalone release artifacts
132
134
  ```
133
135
 
@@ -42,7 +42,9 @@ PythonNative is a cross-platform toolkit for building native Android and iOS app
42
42
  - **Device APIs:** Python facades expose camera, location, notifications, storage, permissions, keyboard, dimensions and pixel ratio, device info, localization, accessibility settings, and other native services, with a Python fallback for headless tests. Test permissions and platform behavior on your deployment targets.
43
43
  - **Native extension SDK:** Python dataclasses and protocols define contracts; `define_component` returns a typed element factory and `pn codegen` generates props and module adapters for Swift and Kotlin. Plugins package native sources and resources, and builds verify matching contracts at startup.
44
44
  - **Testing library:** `pythonnative.testing` renders components headlessly with Testing Library-style queries (`get_by_role`, `get_by_placeholder_text`, `within`, `find_by_*`), a virtual clock for timers, and a pytest plugin that resets the runtime between tests.
45
- - **Development tools:** `pn start` serves the browser preview and connected mobile dev clients. Fast Refresh preserves compatible component state, while diagnostics report errors and invalid hook usage. Changes to native inputs trigger a rebuild.
45
+ - **PythonNative Go:** a prebuilt dev client, published with each release, runs any project without native code, so the project itself is never compiled. `i` / `a` in `pn start` open it on the iOS Simulator (which still needs Xcode installed) or an Android emulator, and a phone with Go installed opens the project by scanning the QR code `pn start` prints. Go isn't in the app stores: Android phones install the APK, and iPhones need Go built and signed with your Apple team. Projects that add native code run in their own debug build, which `pn run` rebuilds only when something native changes.
46
+ - **DevTools and debugging:** `pn start` serves DevTools, with a component tree showing props and hooks (and editable state), a console with a REPL inside the running app, problems with component stacks and source excerpts, network requests, and live performance with trace capture. VS Code attaches `debugpy` breakpoints to Python on the preview, a simulator, or a phone. On device, a dev menu (shake or Cmd+D) offers reload, an element inspector, and a performance monitor, and errors show a screen with the component stack and your source.
47
+ - **Development tools:** Fast Refresh preserves compatible component state, `pn lint` checks the rules of hooks, and `pn init` scaffolds tests, type checking, debugger settings, and CI.
46
48
  - **Browser preview:** `pn preview` runs your Python application against a browser renderer with DOM widgets, Yoga WebAssembly layout, and JavaScript animation graphs. It supports iteration on application logic and UI; fonts, platform controls, and device APIs require mobile testing.
47
49
  - **App packaging and dependency locks:** `pn run` and `pn build` stage bundled app templates, native libraries, and Python sources. Target-specific wheel locks record dependency versions and hashes for mobile builds. Binary dependencies need compatible mobile wheels; `pn deps` reports target resolution.
48
50
 
@@ -79,9 +81,8 @@ def App() -> pn.Node:
79
81
 
80
82
  ```bash
81
83
  pn init my-app && cd my-app
82
- pn preview # dev server + browser preview with Fast Refresh
83
- pn run ios # in another terminal: debug build that connects to the same server
84
- pn run android
84
+ pn start # dev server: scan the QR code, or press i (iOS), a (Android), w (browser), j (DevTools)
85
+ pn run ios # the project's own debug build, for projects that add native code
85
86
  pn build ios # standalone release artifacts
86
87
  ```
87
88
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pythonnative"
7
- version = "0.49.0"
7
+ version = "0.51.0"
8
8
  description = "Cross-platform native UI toolkit for Android and iOS"
9
9
  authors = [
10
10
  { name = "Owen Carey" }
@@ -26,7 +26,11 @@ classifiers = [
26
26
  "Programming Language :: Python :: 3.14",
27
27
  "Topic :: Software Development :: User Interfaces",
28
28
  ]
29
- dependencies = []
29
+ # debugpy is development tooling: `pn start` syncs its sources to dev
30
+ # clients for breakpoint debugging (RFC 0006). App bundles never include it.
31
+ dependencies = [
32
+ "debugpy>=1.8",
33
+ ]
30
34
 
31
35
  [project.optional-dependencies]
32
36
  build = [
@@ -66,7 +66,7 @@ Example:
66
66
  ```
67
67
  """
68
68
 
69
- __version__ = "0.49.0"
69
+ __version__ = "0.51.0"
70
70
 
71
71
  import importlib
72
72
  from typing import TYPE_CHECKING, Any
@@ -88,6 +88,11 @@ def start(dev: bool = False, strict: bool = False, entry: Optional[str] = None)
88
88
 
89
89
  client = devclient.start_if_configured()
90
90
  status_["dev_server"] = client.server_label if client is not None else None
91
+ if client is None:
92
+ # No server yet: the dev menu, inspector, and performance
93
+ # monitor still work locally; a connection replaces this
94
+ # agent with one that reports to DevTools.
95
+ devclient.install_local_agent()
91
96
  # An overlay from the last session may already hold assets the
92
97
  # bundle doesn't; point the native resolver at it right away.
93
98
  from .assets import configure_native
@@ -21,7 +21,7 @@ from typing import Any, Callable
21
21
  from ..profiling import count, profiled
22
22
  from .list_store import ListStore
23
23
 
24
- PROTOCOL_VERSION = 5
24
+ PROTOCOL_VERSION = 6
25
25
  """The bridge protocol every runtime speaks; generated native contracts carry it."""
26
26
 
27
27
 
@@ -24,6 +24,7 @@ __all__ = ["BROWSER_MODULES", "WebTransport"]
24
24
 
25
25
  BROWSER_MODULES = frozenset(
26
26
  {
27
+ "DevSupport",
27
28
  "Host",
28
29
  "Layout",
29
30
  "Alert",
@@ -0,0 +1,178 @@
1
+ """Single-key commands for ``pn start``, like Metro's terminal UI.
2
+
3
+ When stdin is a terminal, ``pn start`` reads keys without waiting for
4
+ Enter. [`KeyCommands.handle`][pythonnative.cli.keys.KeyCommands.handle]
5
+ maps each key to an action; it's separate from the terminal handling so it
6
+ can be tested without one.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import os
12
+ import subprocess
13
+ import sys
14
+ import threading
15
+ import webbrowser
16
+ from typing import Any, Callable, Dict, List, Optional, Tuple
17
+
18
+ __all__ = ["HELP", "KeyCommands", "read_keys"]
19
+
20
+ Logger = Callable[[str], None]
21
+
22
+ HELP: List[Tuple[str, str]] = [
23
+ ("i", "open on the iOS Simulator (in PythonNative Go when the project can run there)"),
24
+ ("a", "open on an Android emulator or device (in PythonNative Go when possible)"),
25
+ ("I / A", "build and run the project's own development app"),
26
+ ("w", "open the browser preview"),
27
+ ("j", "open DevTools"),
28
+ ("r", "reload every connected app"),
29
+ ("m", "open the dev menu on every connected device"),
30
+ ("d", "show how to attach a debugger"),
31
+ ("c", "clear the terminal"),
32
+ ("?", "show these commands"),
33
+ ("q", "quit"),
34
+ ]
35
+
36
+ LAUNCH_CONFIG = """{
37
+ "name": "PythonNative: Attach",
38
+ "type": "debugpy",
39
+ "request": "attach",
40
+ "connect": {"host": "127.0.0.1", "port": %d},
41
+ "justMyCode": true
42
+ }"""
43
+
44
+
45
+ class KeyCommands:
46
+ """Turn keys into dev-server actions.
47
+
48
+ Args:
49
+ session: The running ``PreviewSession``.
50
+ port: The dev server's port (passed to ``pn go`` and ``pn run``).
51
+ log: Terminal logger.
52
+ stop: Called by ``q``.
53
+ spawn: Runs a ``pn`` subcommand in the background (tests replace it).
54
+ """
55
+
56
+ def __init__(
57
+ self,
58
+ session: Any,
59
+ port: int,
60
+ log: Logger,
61
+ stop: Callable[[], None],
62
+ spawn: Optional[Callable[[List[str]], None]] = None,
63
+ ) -> None:
64
+ self.session = session
65
+ self.port = port
66
+ self.log = log
67
+ self.stop = stop
68
+ self.spawn = spawn or self._spawn
69
+ self._running: Dict[str, subprocess.Popen[bytes]] = {}
70
+
71
+ def help_lines(self) -> List[str]:
72
+ """The command list, aligned."""
73
+ return [f" {key:<6} {text}" for key, text in HELP]
74
+
75
+ def handle(self, key: str) -> bool:
76
+ """Run the action for ``key``; returns ``False`` once the server should stop."""
77
+ server = self.session.server
78
+ if key in ("i", "a", "I", "A"):
79
+ platform = "ios" if key.lower() == "i" else "android"
80
+ use_go = key.islower() and self._go_compatible()
81
+ command = ["go" if use_go else "run", platform, "--port", str(self.port)]
82
+ if not use_go:
83
+ command.append("--no-logs")
84
+ what = "PythonNative Go" if use_go else "the project's development app"
85
+ self.log(f"[pn] opening {what} on {'iOS' if platform == 'ios' else 'Android'}...")
86
+ self.spawn(command)
87
+ elif key == "w":
88
+ webbrowser.open(server.info.preview_url("localhost"))
89
+ elif key == "j":
90
+ webbrowser.open(server.info.devtools_url("localhost"))
91
+ elif key == "r":
92
+ self.log("[pn] reloading every connected app")
93
+ server.broadcast_command("reload")
94
+ elif key == "m":
95
+ self.log("[pn] opening the dev menu on connected devices")
96
+ server.broadcast_command("menu")
97
+ elif key == "d":
98
+ self._debug_help()
99
+ elif key == "c":
100
+ sys.stdout.write("\033[2J\033[H")
101
+ sys.stdout.flush()
102
+ elif key in ("?", "h"):
103
+ for line in ["", " Commands:", *self.help_lines(), ""]:
104
+ self.log(line)
105
+ elif key in ("q", "\x03", "\x04"):
106
+ self.stop()
107
+ return False
108
+ return True
109
+
110
+ def _go_compatible(self) -> bool:
111
+ try:
112
+ runtime = self.session.server.project_runtime
113
+ except Exception:
114
+ return True
115
+ if not runtime.go_compatible:
116
+ reasons = runtime.plugins + runtime.native_packages
117
+ self.log(
118
+ f"[pn] this project needs native code PythonNative Go doesn't have ({', '.join(reasons)}); "
119
+ "building its development app instead"
120
+ )
121
+ return False
122
+ return True
123
+
124
+ def _debug_help(self) -> None:
125
+ server = self.session.server
126
+ if not server.debug_port:
127
+ self.log("[pn] the debugger proxy is off (start with --debug-port 5678)")
128
+ return
129
+ target = server.hub.default_target()
130
+ where = target.label() if target is not None else "the next app that connects"
131
+ self.log(f"[pn] debugger: attach a Debug Adapter Protocol client to 127.0.0.1:{server.debug_port}")
132
+ self.log(f"[pn] it debugs {where}; pick another in DevTools or with the device's dev menu")
133
+ self.log("[pn] VS Code launch configuration (pn init writes it to .vscode/launch.json):")
134
+ for line in (LAUNCH_CONFIG % server.debug_port).split("\n"):
135
+ self.log(" " + line)
136
+
137
+ def _spawn(self, args: List[str]) -> None:
138
+ """Run ``pn <args>`` in the background, outside the preview's web environment."""
139
+ name = " ".join(args[:2])
140
+ previous = self._running.get(name)
141
+ if previous is not None and previous.poll() is None:
142
+ self.log(f"[pn] `pn {name}` is still running")
143
+ return
144
+ env = {key: value for key, value in os.environ.items() if key != "PN_PLATFORM"}
145
+ process = subprocess.Popen(
146
+ [sys.executable, "-m", "pythonnative.cli.pn", *args], env=env, stdin=subprocess.DEVNULL
147
+ )
148
+ self._running[name] = process
149
+
150
+
151
+ def read_keys(handle: Callable[[str], bool], stopped: threading.Event) -> None:
152
+ """Read single keys from the terminal until ``handle`` returns ``False`` or ``stopped`` is set.
153
+
154
+ The terminal is put in cbreak mode (keys arrive without Enter, and
155
+ Ctrl+C still interrupts) and restored on exit.
156
+ """
157
+ try:
158
+ import select
159
+ import termios
160
+ import tty
161
+ except ImportError: # Windows: no key commands.
162
+ return
163
+ fd = sys.stdin.fileno()
164
+ try:
165
+ saved = termios.tcgetattr(fd)
166
+ except termios.error:
167
+ return
168
+ try:
169
+ tty.setcbreak(fd)
170
+ while not stopped.is_set():
171
+ ready, _, _ = select.select([fd], [], [], 0.25)
172
+ if not ready:
173
+ continue
174
+ key = os.read(fd, 1).decode("utf-8", errors="ignore")
175
+ if key and not handle(key):
176
+ break
177
+ finally:
178
+ termios.tcsetattr(fd, termios.TCSADRAIN, saved)
@@ -0,0 +1,261 @@
1
+ """Device-facing steps shared by ``pn run``, ``pn go``, and ``pn start``'s keys.
2
+
3
+ These shell out to ``xcrun simctl``, ``xcrun devicectl``, ``adb``, and the
4
+ Android emulator, so they're exercised on real toolchains rather than in
5
+ unit tests (which cover the pure helpers: links and URLs).
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import json
11
+ import shlex
12
+ import subprocess
13
+ import time
14
+ from pathlib import Path
15
+ from typing import Any, Callable, Dict, List, Optional
16
+
17
+ from ..project import devices as devices_mod
18
+
19
+ Logger = Callable[[str], None]
20
+
21
+ __all__ = [
22
+ "boot_android_emulator",
23
+ "booted_ios_udid",
24
+ "ensure_android_device",
25
+ "install_android",
26
+ "install_ios_simulator",
27
+ "open_link_android",
28
+ "launch_ios_device",
29
+ "launch_ios_simulator",
30
+ "select_ios_simulator",
31
+ "server_connect_url",
32
+ ]
33
+
34
+
35
+ # ======================================================================
36
+ # URLs
37
+ # ======================================================================
38
+
39
+
40
+ def server_connect_url(platform: str, device: Optional[devices_mod.Device], port: int, token: str) -> str:
41
+ """The server URL a launched dev client should use to reach ``pn start``.
42
+
43
+ Simulators share the host's loopback. Android emulators and USB
44
+ devices reach it through ``adb reverse`` (set up by the caller), so
45
+ ``localhost`` works for every Android target. A physical iOS device is
46
+ on the LAN, so it gets the first LAN address. The URL carries the dev
47
+ ``token`` the server requires.
48
+ """
49
+ from ..devserver.auth import with_token
50
+
51
+ host = "localhost"
52
+ if platform == "ios" and device is not None and device.kind == "device":
53
+ from ..devserver import lan_addresses
54
+
55
+ host = next(iter(lan_addresses()), host)
56
+ return with_token(f"http://{host}:{port}/", token)
57
+
58
+
59
+ # ======================================================================
60
+ # iOS
61
+ # ======================================================================
62
+
63
+
64
+ def booted_ios_udid() -> Optional[str]:
65
+ """A booted iOS Simulator's UDID, or ``None``."""
66
+ try:
67
+ result = subprocess.run(
68
+ ["xcrun", "simctl", "list", "devices", "booted", "--json"], check=False, capture_output=True, text=True
69
+ )
70
+ except FileNotFoundError:
71
+ return None
72
+ try:
73
+ data = json.loads(result.stdout or "{}")
74
+ except json.JSONDecodeError:
75
+ return None
76
+ for devices in (data.get("devices") or {}).values():
77
+ for device in devices or []:
78
+ if device.get("state") == "Booted" and device.get("udid"):
79
+ return str(device["udid"])
80
+ return None
81
+
82
+
83
+ def select_ios_simulator() -> Optional[str]:
84
+ """A simulator UDID to target: the booted one, else an iPhone 15, else the first available iPhone.
85
+
86
+ The fallback order is deliberate: a full-size iPhone keeps layouts (and
87
+ the E2E suite's taps) the same from run to run, where picking by name
88
+ could land on a compact model such as the iPhone SE.
89
+ """
90
+ booted = booted_ios_udid()
91
+ if booted:
92
+ return booted
93
+ try:
94
+ result = subprocess.run(
95
+ ["xcrun", "simctl", "list", "devices", "available", "--json"], check=False, capture_output=True, text=True
96
+ )
97
+ except FileNotFoundError:
98
+ return None
99
+ try:
100
+ data = json.loads(result.stdout or "{}")
101
+ except json.JSONDecodeError:
102
+ return None
103
+ devices: List[Dict[str, Any]] = [d for entries in (data.get("devices") or {}).values() for d in (entries or [])]
104
+ for device in devices:
105
+ if "iphone 15" in str(device.get("name") or "").lower() and device.get("isAvailable"):
106
+ return str(device.get("udid"))
107
+ for device in devices:
108
+ if device.get("isAvailable") and str(device.get("name") or "").lower().startswith("iphone"):
109
+ return str(device.get("udid"))
110
+ return None
111
+
112
+
113
+ def boot_ios_simulator(udid: str) -> None:
114
+ """Boot ``udid`` (a no-op when it's booted) and bring Simulator.app forward."""
115
+ subprocess.run(["xcrun", "simctl", "boot", udid], check=False, capture_output=True)
116
+ subprocess.run(["open", "-a", "Simulator"], check=False, capture_output=True)
117
+ subprocess.run(["xcrun", "simctl", "bootstatus", udid, "-b"], check=False, capture_output=True)
118
+
119
+
120
+ def install_ios_simulator(udid: str, app: Path) -> bool:
121
+ """Install an ``.app`` on a simulator."""
122
+ return subprocess.run(["xcrun", "simctl", "install", udid, str(app)], check=False).returncode == 0
123
+
124
+
125
+ def launch_ios_simulator(
126
+ udid: str, bundle_id: str, link: Optional[str], *, console: bool = False
127
+ ) -> "subprocess.Popen[bytes]":
128
+ """Relaunch an app on a simulator, handing it a connect link.
129
+
130
+ The link travels in the launch environment (``PN_CONNECT_LINK``)
131
+ rather than through ``simctl openurl``, which makes iOS ask the user to
132
+ confirm opening the app. With ``console``, the app's stdout and stderr
133
+ stream to this terminal and the returned process runs until the app
134
+ exits.
135
+ """
136
+ import os
137
+
138
+ from ..devclient import LINK_ENV
139
+
140
+ env = {**os.environ, "SIMCTL_CHILD_PYTHONUNBUFFERED": "1"}
141
+ if link:
142
+ env["SIMCTL_CHILD_" + LINK_ENV] = link
143
+ command = ["xcrun", "simctl", "launch", "--terminate-running-process"]
144
+ if console:
145
+ command.append("--console-pty")
146
+ return subprocess.Popen([*command, udid, bundle_id], env=env)
147
+
148
+
149
+ def launch_ios_device(identifier: str, bundle_id: str, link: Optional[str]) -> bool:
150
+ """Relaunch an app on a physical device, handing it a connect link."""
151
+ from ..devclient import LINK_ENV
152
+
153
+ command = ["xcrun", "devicectl", "device", "process", "launch", "--terminate-existing"]
154
+ if link:
155
+ command += ["--environment-variables", json.dumps({LINK_ENV: link})]
156
+ command += ["--device", identifier, bundle_id]
157
+ return subprocess.run(command, check=False).returncode == 0
158
+
159
+
160
+ # ======================================================================
161
+ # Android
162
+ # ======================================================================
163
+
164
+
165
+ def _emulator_binary() -> Optional[Path]:
166
+ from ..project.android import sdk_dir
167
+
168
+ candidate = sdk_dir() / "emulator" / "emulator"
169
+ return candidate if candidate.exists() else None
170
+
171
+
172
+ def list_avds() -> List[str]:
173
+ """The Android Virtual Devices this machine has."""
174
+ emulator = _emulator_binary()
175
+ if emulator is None:
176
+ return []
177
+ result = subprocess.run([str(emulator), "-list-avds"], check=False, capture_output=True, text=True)
178
+ return [line.strip() for line in (result.stdout or "").splitlines() if line.strip() and " " not in line.strip()]
179
+
180
+
181
+ def boot_android_emulator(log: Logger, avd: Optional[str] = None, timeout: float = 240.0) -> Optional[str]:
182
+ """Boot an emulator and wait until Android finished booting; returns its serial."""
183
+ emulator = _emulator_binary()
184
+ avds = list_avds()
185
+ name = avd or (avds[0] if avds else None)
186
+ if emulator is None or name is None:
187
+ log("No Android emulator to boot: create one in Android Studio's Device Manager.")
188
+ return None
189
+ log(f"Booting the Android emulator {name}...")
190
+ subprocess.Popen(
191
+ [str(emulator), "-avd", name, "-netdelay", "none", "-netspeed", "full"],
192
+ stdout=subprocess.DEVNULL,
193
+ stderr=subprocess.DEVNULL,
194
+ start_new_session=True,
195
+ )
196
+ deadline = time.monotonic() + timeout
197
+ while time.monotonic() < deadline:
198
+ for device in devices_mod.list_android_devices():
199
+ if device.kind == "emulator" and device.is_ready:
200
+ booted = subprocess.run(
201
+ ["adb", "-s", device.identifier, "shell", "getprop", "sys.boot_completed"],
202
+ check=False,
203
+ capture_output=True,
204
+ text=True,
205
+ )
206
+ if booted.stdout.strip() == "1":
207
+ return device.identifier
208
+ time.sleep(2.0)
209
+ log("The emulator didn't finish booting in time.")
210
+ return None
211
+
212
+
213
+ def ensure_android_device(device: Optional[devices_mod.Device], log: Logger) -> Optional[str]:
214
+ """A ready Android serial: ``device``'s, the first connected one, or a freshly booted emulator."""
215
+ if device is not None:
216
+ return device.identifier
217
+ ready = [d for d in devices_mod.list_android_devices() if d.is_ready]
218
+ if ready:
219
+ return ready[0].identifier
220
+ return boot_android_emulator(log)
221
+
222
+
223
+ def _adb(serial: Optional[str], *args: str, capture: bool = False) -> subprocess.CompletedProcess[str]:
224
+ command = ["adb", *(["-s", serial] if serial else []), *args]
225
+ return subprocess.run(command, check=False, capture_output=capture, text=True)
226
+
227
+
228
+ def install_android(serial: Optional[str], apk: Path, package: str, log: Logger) -> bool:
229
+ """Install an APK, replacing an installed copy signed with a different key."""
230
+ result = _adb(serial, "install", "-r", str(apk), capture=True)
231
+ if result.returncode == 0:
232
+ return True
233
+ output = (result.stdout or "") + (result.stderr or "")
234
+ if "INSTALL_FAILED_UPDATE_INCOMPATIBLE" in output or "signatures do not match" in output:
235
+ log(f"Replacing the installed {package}, which was signed with a different key.")
236
+ _adb(serial, "uninstall", package, capture=True)
237
+ return _adb(serial, "install", str(apk)).returncode == 0
238
+ log(output.strip())
239
+ return False
240
+
241
+
242
+ def reverse_port(serial: Optional[str], port: int) -> None:
243
+ """Let the device reach ``localhost:port`` on this machine (``adb reverse``)."""
244
+ _adb(serial, "reverse", f"tcp:{port}", f"tcp:{port}", capture=True)
245
+
246
+
247
+ def open_link_android(serial: Optional[str], link: str, package: str) -> bool:
248
+ """Open a deep link in ``package`` (launching it when needed)."""
249
+ # `adb shell` runs its arguments through the device's shell.
250
+ command = f"am start -a android.intent.action.VIEW -d {shlex.quote(link)} {shlex.quote(package)}"
251
+ return _adb(serial, "shell", command).returncode == 0
252
+
253
+
254
+ def stop_android_app(serial: Optional[str], package: str) -> None:
255
+ """Force-stop ``package`` so the next link cold-starts it."""
256
+ _adb(serial, "shell", "am", "force-stop", package, capture=True)
257
+
258
+
259
+ def describe(device: Optional[devices_mod.Device]) -> Dict[str, Any]:
260
+ """A loggable description of a target device."""
261
+ return device.to_dict() if device is not None else {}