pythonnative 0.40.0__cp313-cp313-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (418) hide show
  1. pythonnative/__init__.py +411 -0
  2. pythonnative/_ios_log.py +92 -0
  3. pythonnative/_yoga.cp313-win_amd64.pyd +0 -0
  4. pythonnative/alerts.py +236 -0
  5. pythonnative/animated.py +1687 -0
  6. pythonnative/animation_graph.py +78 -0
  7. pythonnative/appearance.py +124 -0
  8. pythonnative/bootstrap.py +100 -0
  9. pythonnative/bridge/__init__.py +302 -0
  10. pythonnative/bridge/android.py +78 -0
  11. pythonnative/bridge/codec.py +170 -0
  12. pythonnative/bridge/commits.py +114 -0
  13. pythonnative/bridge/fake.py +243 -0
  14. pythonnative/bridge/ios.py +138 -0
  15. pythonnative/bridge/web.py +489 -0
  16. pythonnative/cli/__init__.py +7 -0
  17. pythonnative/cli/pn.py +1214 -0
  18. pythonnative/component.py +271 -0
  19. pythonnative/components/__init__.py +111 -0
  20. pythonnative/components/_base.py +166 -0
  21. pythonnative/components/controls.py +521 -0
  22. pythonnative/components/layout.py +518 -0
  23. pythonnative/components/lists.py +785 -0
  24. pythonnative/components/media.py +204 -0
  25. pythonnative/components/overlays.py +107 -0
  26. pythonnative/components/pressable.py +252 -0
  27. pythonnative/components/structural.py +167 -0
  28. pythonnative/components/text.py +291 -0
  29. pythonnative/devclient.py +824 -0
  30. pythonnative/devserver/__init__.py +34 -0
  31. pythonnative/devserver/server.py +718 -0
  32. pythonnative/devserver/static/animation_graph.js +82 -0
  33. pythonnative/devserver/static/bridge.js +147 -0
  34. pythonnative/devserver/static/colors.js +70 -0
  35. pythonnative/devserver/static/host.js +552 -0
  36. pythonnative/devserver/static/index.html +60 -0
  37. pythonnative/devserver/static/layout.js +85 -0
  38. pythonnative/devserver/static/preview.css +415 -0
  39. pythonnative/devserver/static/renderer.js +1994 -0
  40. pythonnative/devserver/static/shell.js +345 -0
  41. pythonnative/devserver/static/yoga/LICENSE +21 -0
  42. pythonnative/devserver/static/yoga/binaries/yoga-wasm-base64-esm.js +75 -0
  43. pythonnative/devserver/static/yoga/src/generated/YGEnums.d.ts +189 -0
  44. pythonnative/devserver/static/yoga/src/generated/YGEnums.js +211 -0
  45. pythonnative/devserver/static/yoga/src/generated/YGEnums.js.map +1 -0
  46. pythonnative/devserver/static/yoga/src/index.d.ts +12 -0
  47. pythonnative/devserver/static/yoga/src/index.js +16 -0
  48. pythonnative/devserver/static/yoga/src/index.js.map +1 -0
  49. pythonnative/devserver/static/yoga/src/load.d.ts +11 -0
  50. pythonnative/devserver/static/yoga/src/load.js +17 -0
  51. pythonnative/devserver/static/yoga/src/load.js.map +1 -0
  52. pythonnative/devserver/static/yoga/src/wrapAssembly.d.ts +155 -0
  53. pythonnative/devserver/static/yoga/src/wrapAssembly.js +125 -0
  54. pythonnative/devserver/static/yoga/src/wrapAssembly.js.map +1 -0
  55. pythonnative/devserver/watcher.py +267 -0
  56. pythonnative/devserver/ws.py +421 -0
  57. pythonnative/diagnostics.py +241 -0
  58. pythonnative/element.py +159 -0
  59. pythonnative/equality.py +19 -0
  60. pythonnative/events.py +231 -0
  61. pythonnative/gestures.py +1333 -0
  62. pythonnative/hooks.py +1621 -0
  63. pythonnative/hosts/__init__.py +63 -0
  64. pythonnative/hosts/base.py +596 -0
  65. pythonnative/hosts/native.py +302 -0
  66. pythonnative/hot_reload.py +585 -0
  67. pythonnative/layout.py +328 -0
  68. pythonnative/mutations.py +142 -0
  69. pythonnative/native/android/build.gradle +52 -0
  70. pythonnative/native/android/gradle.properties +3 -0
  71. pythonnative/native/android/settings.gradle +12 -0
  72. pythonnative/native/android/src/main/AndroidManifest.xml +11 -0
  73. pythonnative/native/android/src/main/cpp/CMakeLists.txt +9 -0
  74. pythonnative/native/android/src/main/cpp/yoga_jni.cpp +52 -0
  75. pythonnative/native/android/src/main/java/com/pythonnative/generated/NativeModules.kt +5 -0
  76. pythonnative/native/android/src/main/java/com/pythonnative/generated/NativeProps.kt +3705 -0
  77. pythonnative/native/android/src/main/java/com/pythonnative/generated/PNContracts.kt +129 -0
  78. pythonnative/native/android/src/main/java/com/pythonnative/runtime/PNBridge.kt +261 -0
  79. pythonnative/native/android/src/main/java/com/pythonnative/runtime/PythonHost.kt +20 -0
  80. pythonnative/native/android/src/main/java/com/pythonnative/runtime/animation/AnimationGraph.kt +108 -0
  81. pythonnative/native/android/src/main/java/com/pythonnative/runtime/animation/AnimationSpecs.kt +141 -0
  82. pythonnative/native/android/src/main/java/com/pythonnative/runtime/animation/PNAnimator.kt +257 -0
  83. pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/CommitState.kt +106 -0
  84. pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/JsonUtil.kt +175 -0
  85. pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/MainThread.kt +40 -0
  86. pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/PNLog.kt +33 -0
  87. pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/PNRegistry.kt +82 -0
  88. pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/PNTransaction.kt +80 -0
  89. pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/TransactionApplier.kt +117 -0
  90. pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/ViewRegistry.kt +74 -0
  91. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/BuiltinComponents.kt +37 -0
  92. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ButtonManager.kt +32 -0
  93. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ComponentManager.kt +213 -0
  94. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ContainerManagers.kt +69 -0
  95. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ControlManagers.kt +186 -0
  96. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/DatePickerManager.kt +123 -0
  97. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ImageLoader.kt +141 -0
  98. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ImageManager.kt +162 -0
  99. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ModalManager.kt +134 -0
  100. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/PNColor.kt +201 -0
  101. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/PickerManager.kt +86 -0
  102. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/PortalManager.kt +55 -0
  103. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/PressableManager.kt +122 -0
  104. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ScreenStackManager.kt +110 -0
  105. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ScrollViewManager.kt +214 -0
  106. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/SegmentedControlManager.kt +113 -0
  107. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/StatusBarManager.kt +52 -0
  108. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/TabBarManager.kt +131 -0
  109. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/TextInputManager.kt +250 -0
  110. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/TextManager.kt +233 -0
  111. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ViewStyler.kt +355 -0
  112. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/VirtualListManager.kt +159 -0
  113. pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/WebViewManager.kt +149 -0
  114. pythonnative/native/android/src/main/java/com/pythonnative/runtime/gestures/GestureArbiter.kt +233 -0
  115. pythonnative/native/android/src/main/java/com/pythonnative/runtime/gestures/GestureCoordinator.kt +127 -0
  116. pythonnative/native/android/src/main/java/com/pythonnative/runtime/gestures/GestureRecognizers.kt +527 -0
  117. pythonnative/native/android/src/main/java/com/pythonnative/runtime/layout/NativeLayout.kt +145 -0
  118. pythonnative/native/android/src/main/java/com/pythonnative/runtime/layout/YogaNode.kt +29 -0
  119. pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/BuiltinModules.kt +73 -0
  120. pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/DeviceModules.kt +316 -0
  121. pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/HostModule.kt +61 -0
  122. pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/MediaModules.kt +200 -0
  123. pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/NativeModule.kt +158 -0
  124. pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/NotificationsModule.kt +100 -0
  125. pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/PermissionsModule.kt +99 -0
  126. pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/StorageModules.kt +89 -0
  127. pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/SystemModules.kt +178 -0
  128. pythonnative/native/android/src/main/java/com/pythonnative/runtime/plugins/GeneratedPlugins.kt +16 -0
  129. pythonnative/native/android/src/main/java/com/pythonnative/runtime/screens/PNScreenFragment.kt +188 -0
  130. pythonnative/native/android/src/main/java/com/pythonnative/runtime/screens/ScreenRegistry.kt +80 -0
  131. pythonnative/native/android/src/main/java/com/pythonnative/runtime/views/PNAccessibilityDelegate.kt +48 -0
  132. pythonnative/native/android/src/main/java/com/pythonnative/runtime/views/PNBorderDrawable.kt +76 -0
  133. pythonnative/native/android/src/main/java/com/pythonnative/runtime/views/PNEditText.kt +18 -0
  134. pythonnative/native/android/src/main/java/com/pythonnative/runtime/views/PNFrameLayout.kt +49 -0
  135. pythonnative/native/android/src/test/java/com/pythonnative/runtime/AnimationSpecsTest.kt +75 -0
  136. pythonnative/native/android/src/test/java/com/pythonnative/runtime/GestureArbiterTest.kt +197 -0
  137. pythonnative/native/android/src/test/java/com/pythonnative/runtime/PNColorTest.kt +47 -0
  138. pythonnative/native/android/src/test/java/com/pythonnative/runtime/PNTransactionTest.kt +78 -0
  139. pythonnative/native/android/src/test/java/com/pythonnative/runtime/PromiseTest.kt +89 -0
  140. pythonnative/native/ios/Package.swift +23 -0
  141. pythonnative/native/ios/Sources/PythonNativeKit/Animation/PNAnimationGraph.swift +199 -0
  142. pythonnative/native/ios/Sources/PythonNativeKit/Animation/PNAnimator.swift +312 -0
  143. pythonnative/native/ios/Sources/PythonNativeKit/Bridge/PNBridge.swift +255 -0
  144. pythonnative/native/ios/Sources/PythonNativeKit/Bridge/PNCommit.swift +104 -0
  145. pythonnative/native/ios/Sources/PythonNativeKit/Bridge/PNRegistry.swift +142 -0
  146. pythonnative/native/ios/Sources/PythonNativeKit/Bridge/PNTransaction.swift +166 -0
  147. pythonnative/native/ios/Sources/PythonNativeKit/Bridge/PNViewRegistry.swift +53 -0
  148. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNButtonManagers.swift +207 -0
  149. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNColor.swift +173 -0
  150. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNComponentManager.swift +183 -0
  151. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNContainerView.swift +56 -0
  152. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNControlManagers.swift +281 -0
  153. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNImageManager.swift +222 -0
  154. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNOverlayManagers.swift +243 -0
  155. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNPressableManager.swift +114 -0
  156. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNScreenStackManager.swift +107 -0
  157. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNScrollViewManager.swift +197 -0
  158. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNTabBarManager.swift +106 -0
  159. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNTextInputManager.swift +297 -0
  160. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNTextManager.swift +230 -0
  161. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNTransform.swift +82 -0
  162. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNViewManager.swift +86 -0
  163. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNViewState.swift +87 -0
  164. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNViewStyler.swift +340 -0
  165. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNVirtualListManager.swift +155 -0
  166. pythonnative/native/ios/Sources/PythonNativeKit/Components/PNWebViewManager.swift +124 -0
  167. pythonnative/native/ios/Sources/PythonNativeKit/Generated/NativeModules.swift +1 -0
  168. pythonnative/native/ios/Sources/PythonNativeKit/Generated/NativeProps.swift +3775 -0
  169. pythonnative/native/ios/Sources/PythonNativeKit/Generated/PNContracts.swift +46 -0
  170. pythonnative/native/ios/Sources/PythonNativeKit/Gestures/PNGestureCoordinator.swift +260 -0
  171. pythonnative/native/ios/Sources/PythonNativeKit/Layout/PNLayout.swift +173 -0
  172. pythonnative/native/ios/Sources/PythonNativeKit/Modules/AlertModule.swift +92 -0
  173. pythonnative/native/ios/Sources/PythonNativeKit/Modules/HostModule.swift +80 -0
  174. pythonnative/native/ios/Sources/PythonNativeKit/Modules/LifecycleModules.swift +174 -0
  175. pythonnative/native/ios/Sources/PythonNativeKit/Modules/MediaModules.swift +177 -0
  176. pythonnative/native/ios/Sources/PythonNativeKit/Modules/PNNativeModule.swift +168 -0
  177. pythonnative/native/ios/Sources/PythonNativeKit/Modules/PermissionModules.swift +266 -0
  178. pythonnative/native/ios/Sources/PythonNativeKit/Modules/SystemModules.swift +251 -0
  179. pythonnative/native/ios/Sources/PythonNativeKit/Plugins/PNPluginRegistration.swift +8 -0
  180. pythonnative/native/ios/Sources/PythonNativeKit/Screens/PNScreenRegistry.swift +46 -0
  181. pythonnative/native/ios/Sources/PythonNativeKit/Screens/PNViewController.swift +237 -0
  182. pythonnative/native/ios/Sources/PythonNativeKit/Support/PNCompat.swift +46 -0
  183. pythonnative/native/ios/Sources/PythonNativeKit/Support/PNJSON.swift +173 -0
  184. pythonnative/native/ios/Sources/PythonNativeKit/Support/PNLog.swift +47 -0
  185. pythonnative/native/ios/Sources/PythonNativeKit/Support/PNWindow.swift +51 -0
  186. pythonnative/native/ios/Tests/PythonNativeKitTests/PNAnimationGraphTests.swift +26 -0
  187. pythonnative/native/ios/Tests/PythonNativeKitTests/PNColorTests.swift +50 -0
  188. pythonnative/native/ios/Tests/PythonNativeKitTests/PNCommitTests.swift +86 -0
  189. pythonnative/native/ios/Tests/PythonNativeKitTests/PNGestureTests.swift +101 -0
  190. pythonnative/native/ios/Tests/PythonNativeKitTests/PNManagerTests.swift +126 -0
  191. pythonnative/native/ios/Tests/PythonNativeKitTests/PNModuleTests.swift +111 -0
  192. pythonnative/native/ios/Tests/PythonNativeKitTests/PNTransactionTests.swift +91 -0
  193. pythonnative/native/yoga/LICENSE +21 -0
  194. pythonnative/native/yoga/Package.swift +9 -0
  195. pythonnative/native/yoga/VENDORED.md +2 -0
  196. pythonnative/native/yoga/include/PNStyle.h +10 -0
  197. pythonnative/native/yoga/include/module.modulemap +5 -0
  198. pythonnative/native/yoga/include/yoga/YGConfig.h +158 -0
  199. pythonnative/native/yoga/include/yoga/YGEnums.h +142 -0
  200. pythonnative/native/yoga/include/yoga/YGMacros.h +99 -0
  201. pythonnative/native/yoga/include/yoga/YGNode.h +304 -0
  202. pythonnative/native/yoga/include/yoga/YGNodeLayout.h +35 -0
  203. pythonnative/native/yoga/include/yoga/YGNodeStyle.h +130 -0
  204. pythonnative/native/yoga/include/yoga/YGPixelGrid.h +29 -0
  205. pythonnative/native/yoga/include/yoga/YGValue.h +84 -0
  206. pythonnative/native/yoga/include/yoga/Yoga.h +21 -0
  207. pythonnative/native/yoga/python.cpp +16 -0
  208. pythonnative/native/yoga/style.cpp +272 -0
  209. pythonnative/native/yoga/yoga/CMakeLists.txt +41 -0
  210. pythonnative/native/yoga/yoga/YGConfig.cpp +92 -0
  211. pythonnative/native/yoga/yoga/YGConfig.h +158 -0
  212. pythonnative/native/yoga/yoga/YGEnums.cpp +262 -0
  213. pythonnative/native/yoga/yoga/YGEnums.h +142 -0
  214. pythonnative/native/yoga/yoga/YGMacros.h +99 -0
  215. pythonnative/native/yoga/yoga/YGNode.cpp +366 -0
  216. pythonnative/native/yoga/yoga/YGNode.h +304 -0
  217. pythonnative/native/yoga/yoga/YGNodeLayout.cpp +92 -0
  218. pythonnative/native/yoga/yoga/YGNodeLayout.h +35 -0
  219. pythonnative/native/yoga/yoga/YGNodeStyle.cpp +405 -0
  220. pythonnative/native/yoga/yoga/YGNodeStyle.h +130 -0
  221. pythonnative/native/yoga/yoga/YGPixelGrid.cpp +22 -0
  222. pythonnative/native/yoga/yoga/YGPixelGrid.h +29 -0
  223. pythonnative/native/yoga/yoga/YGValue.cpp +20 -0
  224. pythonnative/native/yoga/yoga/YGValue.h +84 -0
  225. pythonnative/native/yoga/yoga/Yoga.h +21 -0
  226. pythonnative/native/yoga/yoga/algorithm/AbsoluteLayout.cpp +563 -0
  227. pythonnative/native/yoga/yoga/algorithm/AbsoluteLayout.h +41 -0
  228. pythonnative/native/yoga/yoga/algorithm/Align.h +72 -0
  229. pythonnative/native/yoga/yoga/algorithm/Baseline.cpp +78 -0
  230. pythonnative/native/yoga/yoga/algorithm/Baseline.h +21 -0
  231. pythonnative/native/yoga/yoga/algorithm/BoundAxis.h +79 -0
  232. pythonnative/native/yoga/yoga/algorithm/Cache.cpp +121 -0
  233. pythonnative/native/yoga/yoga/algorithm/Cache.h +30 -0
  234. pythonnative/native/yoga/yoga/algorithm/CalculateLayout.cpp +2428 -0
  235. pythonnative/native/yoga/yoga/algorithm/CalculateLayout.h +38 -0
  236. pythonnative/native/yoga/yoga/algorithm/FlexDirection.h +120 -0
  237. pythonnative/native/yoga/yoga/algorithm/FlexLine.cpp +124 -0
  238. pythonnative/native/yoga/yoga/algorithm/FlexLine.h +75 -0
  239. pythonnative/native/yoga/yoga/algorithm/PixelGrid.cpp +132 -0
  240. pythonnative/native/yoga/yoga/algorithm/PixelGrid.h +29 -0
  241. pythonnative/native/yoga/yoga/algorithm/SizingMode.h +73 -0
  242. pythonnative/native/yoga/yoga/algorithm/TrailingPosition.h +44 -0
  243. pythonnative/native/yoga/yoga/config/Config.cpp +135 -0
  244. pythonnative/native/yoga/yoga/config/Config.h +92 -0
  245. pythonnative/native/yoga/yoga/debug/AssertFatal.cpp +53 -0
  246. pythonnative/native/yoga/yoga/debug/AssertFatal.h +29 -0
  247. pythonnative/native/yoga/yoga/debug/Log.cpp +107 -0
  248. pythonnative/native/yoga/yoga/debug/Log.h +34 -0
  249. pythonnative/native/yoga/yoga/enums/Align.h +47 -0
  250. pythonnative/native/yoga/yoga/enums/BoxSizing.h +40 -0
  251. pythonnative/native/yoga/yoga/enums/Dimension.h +40 -0
  252. pythonnative/native/yoga/yoga/enums/Direction.h +41 -0
  253. pythonnative/native/yoga/yoga/enums/Display.h +41 -0
  254. pythonnative/native/yoga/yoga/enums/Edge.h +47 -0
  255. pythonnative/native/yoga/yoga/enums/Errata.h +41 -0
  256. pythonnative/native/yoga/yoga/enums/ExperimentalFeature.h +39 -0
  257. pythonnative/native/yoga/yoga/enums/FlexDirection.h +42 -0
  258. pythonnative/native/yoga/yoga/enums/Gutter.h +41 -0
  259. pythonnative/native/yoga/yoga/enums/Justify.h +44 -0
  260. pythonnative/native/yoga/yoga/enums/LogLevel.h +44 -0
  261. pythonnative/native/yoga/yoga/enums/MeasureMode.h +41 -0
  262. pythonnative/native/yoga/yoga/enums/NodeType.h +40 -0
  263. pythonnative/native/yoga/yoga/enums/Overflow.h +41 -0
  264. pythonnative/native/yoga/yoga/enums/PhysicalEdge.h +21 -0
  265. pythonnative/native/yoga/yoga/enums/PositionType.h +41 -0
  266. pythonnative/native/yoga/yoga/enums/Unit.h +42 -0
  267. pythonnative/native/yoga/yoga/enums/Wrap.h +41 -0
  268. pythonnative/native/yoga/yoga/enums/YogaEnums.h +85 -0
  269. pythonnative/native/yoga/yoga/event/event.cpp +87 -0
  270. pythonnative/native/yoga/yoga/event/event.h +130 -0
  271. pythonnative/native/yoga/yoga/module.modulemap +21 -0
  272. pythonnative/native/yoga/yoga/node/CachedMeasurement.h +53 -0
  273. pythonnative/native/yoga/yoga/node/LayoutResults.cpp +48 -0
  274. pythonnative/native/yoga/yoga/node/LayoutResults.h +122 -0
  275. pythonnative/native/yoga/yoga/node/LayoutableChildren.h +148 -0
  276. pythonnative/native/yoga/yoga/node/Node.cpp +443 -0
  277. pythonnative/native/yoga/yoga/node/Node.h +337 -0
  278. pythonnative/native/yoga/yoga/numeric/Comparison.h +81 -0
  279. pythonnative/native/yoga/yoga/numeric/FloatOptional.h +93 -0
  280. pythonnative/native/yoga/yoga/style/SmallValueBuffer.h +133 -0
  281. pythonnative/native/yoga/yoga/style/Style.h +757 -0
  282. pythonnative/native/yoga/yoga/style/StyleLength.h +107 -0
  283. pythonnative/native/yoga/yoga/style/StyleValueHandle.h +98 -0
  284. pythonnative/native/yoga/yoga/style/StyleValuePool.h +127 -0
  285. pythonnative/native_modules/__init__.py +124 -0
  286. pythonnative/native_modules/app_state.py +99 -0
  287. pythonnative/native_modules/battery.py +75 -0
  288. pythonnative/native_modules/biometrics.py +42 -0
  289. pythonnative/native_modules/camera.py +65 -0
  290. pythonnative/native_modules/clipboard.py +46 -0
  291. pythonnative/native_modules/fallback.py +324 -0
  292. pythonnative/native_modules/file_system.py +145 -0
  293. pythonnative/native_modules/haptics.py +75 -0
  294. pythonnative/native_modules/linking.py +123 -0
  295. pythonnative/native_modules/location.py +75 -0
  296. pythonnative/native_modules/net_info.py +112 -0
  297. pythonnative/native_modules/notifications.py +129 -0
  298. pythonnative/native_modules/permissions.py +108 -0
  299. pythonnative/native_modules/registry.py +526 -0
  300. pythonnative/native_modules/secure_store.py +52 -0
  301. pythonnative/native_modules/share.py +51 -0
  302. pythonnative/native_views/__init__.py +375 -0
  303. pythonnative/native_views/base.py +316 -0
  304. pythonnative/native_views/bridge_backend.py +277 -0
  305. pythonnative/navigation/__init__.py +103 -0
  306. pythonnative/navigation/container.py +154 -0
  307. pythonnative/navigation/handle.py +540 -0
  308. pythonnative/navigation/hooks.py +133 -0
  309. pythonnative/navigation/host.py +58 -0
  310. pythonnative/navigation/linking.py +200 -0
  311. pythonnative/navigation/navigators.py +659 -0
  312. pythonnative/navigation/screen.py +149 -0
  313. pythonnative/navigation/state.py +269 -0
  314. pythonnative/net.py +248 -0
  315. pythonnative/platform.py +166 -0
  316. pythonnative/platform_metrics.py +252 -0
  317. pythonnative/preview.py +287 -0
  318. pythonnative/profiling.py +101 -0
  319. pythonnative/project/__init__.py +68 -0
  320. pythonnative/project/android.py +557 -0
  321. pythonnative/project/builder.py +817 -0
  322. pythonnative/project/config.py +773 -0
  323. pythonnative/project/deps.py +719 -0
  324. pythonnative/project/devices.py +304 -0
  325. pythonnative/project/doctor.py +283 -0
  326. pythonnative/project/fingerprint.py +171 -0
  327. pythonnative/project/icons.py +247 -0
  328. pythonnative/project/ios.py +325 -0
  329. pythonnative/project/lockfile.py +100 -0
  330. pythonnative/project/permissions.py +361 -0
  331. pythonnative/project/plugins.py +519 -0
  332. pythonnative/project/runtime_assets.py +183 -0
  333. pythonnative/py.typed +0 -0
  334. pythonnative/query.py +153 -0
  335. pythonnative/reconciler/__init__.py +29 -0
  336. pythonnative/reconciler/boundaries.py +375 -0
  337. pythonnative/reconciler/children.py +88 -0
  338. pythonnative/reconciler/core.py +1165 -0
  339. pythonnative/reconciler/layout_pass.py +393 -0
  340. pythonnative/reconciler/vnode.py +266 -0
  341. pythonnative/refresh.py +55 -0
  342. pythonnative/runtime.py +306 -0
  343. pythonnative/scheduler.py +159 -0
  344. pythonnative/sdk/__init__.py +153 -0
  345. pythonnative/sdk/_components.py +427 -0
  346. pythonnative/sdk/builtins.py +91 -0
  347. pythonnative/sdk/codegen.py +149 -0
  348. pythonnative/sdk/module_codegen.py +184 -0
  349. pythonnative/sdk/schema.py +224 -0
  350. pythonnative/sdk/templates/contracts.kt +46 -0
  351. pythonnative/sdk/templates/contracts.swift +46 -0
  352. pythonnative/storage.py +184 -0
  353. pythonnative/style.py +841 -0
  354. pythonnative/suspense.py +183 -0
  355. pythonnative/templates/android_template/app/build.gradle +75 -0
  356. pythonnative/templates/android_template/app/proguard-rules.pro +21 -0
  357. pythonnative/templates/android_template/app/src/androidTest/java/com/pythonnative/android_template/ExampleInstrumentedTest.kt +24 -0
  358. pythonnative/templates/android_template/app/src/debug/AndroidManifest.xml +7 -0
  359. pythonnative/templates/android_template/app/src/main/AndroidManifest.xml +32 -0
  360. pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/MainActivity.kt +130 -0
  361. pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/ScreenFragment.kt +13 -0
  362. pythonnative/templates/android_template/app/src/main/res/drawable/ic_launcher_background.xml +170 -0
  363. pythonnative/templates/android_template/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +30 -0
  364. pythonnative/templates/android_template/app/src/main/res/layout/activity_main.xml +10 -0
  365. pythonnative/templates/android_template/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +6 -0
  366. pythonnative/templates/android_template/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +6 -0
  367. pythonnative/templates/android_template/app/src/main/res/mipmap-hdpi/ic_launcher.webp +0 -0
  368. pythonnative/templates/android_template/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp +0 -0
  369. pythonnative/templates/android_template/app/src/main/res/mipmap-mdpi/ic_launcher.webp +0 -0
  370. pythonnative/templates/android_template/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp +0 -0
  371. pythonnative/templates/android_template/app/src/main/res/mipmap-xhdpi/ic_launcher.webp +0 -0
  372. pythonnative/templates/android_template/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp +0 -0
  373. pythonnative/templates/android_template/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp +0 -0
  374. pythonnative/templates/android_template/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp +0 -0
  375. pythonnative/templates/android_template/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp +0 -0
  376. pythonnative/templates/android_template/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp +0 -0
  377. pythonnative/templates/android_template/app/src/main/res/navigation/nav_graph.xml +22 -0
  378. pythonnative/templates/android_template/app/src/main/res/values/colors.xml +5 -0
  379. pythonnative/templates/android_template/app/src/main/res/values/strings.xml +5 -0
  380. pythonnative/templates/android_template/app/src/main/res/values/themes.xml +9 -0
  381. pythonnative/templates/android_template/app/src/main/res/values-night/themes.xml +7 -0
  382. pythonnative/templates/android_template/app/src/main/res/xml/backup_rules.xml +13 -0
  383. pythonnative/templates/android_template/app/src/main/res/xml/data_extraction_rules.xml +19 -0
  384. pythonnative/templates/android_template/app/src/test/java/com/pythonnative/android_template/ExampleUnitTest.kt +17 -0
  385. pythonnative/templates/android_template/build.gradle +10 -0
  386. pythonnative/templates/android_template/gradle/wrapper/gradle-wrapper.jar +0 -0
  387. pythonnative/templates/android_template/gradle/wrapper/gradle-wrapper.properties +6 -0
  388. pythonnative/templates/android_template/gradle.properties +23 -0
  389. pythonnative/templates/android_template/gradlew +185 -0
  390. pythonnative/templates/android_template/gradlew.bat +89 -0
  391. pythonnative/templates/android_template/settings.gradle +17 -0
  392. pythonnative/templates/ios_template/ios_template/AppDelegate.swift +51 -0
  393. pythonnative/templates/ios_template/ios_template/Assets.xcassets/AccentColor.colorset/Contents.json +11 -0
  394. pythonnative/templates/ios_template/ios_template/Assets.xcassets/AppIcon.appiconset/Contents.json +13 -0
  395. pythonnative/templates/ios_template/ios_template/Assets.xcassets/Contents.json +6 -0
  396. pythonnative/templates/ios_template/ios_template/Base.lproj/LaunchScreen.storyboard +25 -0
  397. pythonnative/templates/ios_template/ios_template/BridgingHeader.h +14 -0
  398. pythonnative/templates/ios_template/ios_template/Info.plist +28 -0
  399. pythonnative/templates/ios_template/ios_template/PythonRuntime.swift +390 -0
  400. pythonnative/templates/ios_template/ios_template/SceneDelegate.swift +61 -0
  401. pythonnative/templates/ios_template/ios_template/ViewController.swift +23 -0
  402. pythonnative/templates/ios_template/ios_template.xcodeproj/project.pbxproj +745 -0
  403. pythonnative/templates/ios_template/ios_template.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  404. pythonnative/templates/ios_template/ios_templateTests/ios_templateTests.swift +36 -0
  405. pythonnative/templates/ios_template/ios_templateUITests/ios_templateUITests.swift +41 -0
  406. pythonnative/templates/ios_template/ios_templateUITests/ios_templateUITestsLaunchTests.swift +32 -0
  407. pythonnative/testing/__init__.py +53 -0
  408. pythonnative/testing/backend.py +276 -0
  409. pythonnative/testing/harness.py +369 -0
  410. pythonnative/utils.py +145 -0
  411. pythonnative-0.40.0.dist-info/DELVEWHEEL +2 -0
  412. pythonnative-0.40.0.dist-info/METADATA +150 -0
  413. pythonnative-0.40.0.dist-info/RECORD +418 -0
  414. pythonnative-0.40.0.dist-info/WHEEL +5 -0
  415. pythonnative-0.40.0.dist-info/entry_points.txt +2 -0
  416. pythonnative-0.40.0.dist-info/licenses/LICENSE +21 -0
  417. pythonnative-0.40.0.dist-info/top_level.txt +1 -0
  418. pythonnative.libs/msvcp140-a4c2229bdc2a2a630acdc095b4d86008.dll +0 -0
@@ -0,0 +1,14 @@
1
+ //
2
+ // BridgingHeader.h
3
+ // ios_template
4
+ //
5
+ // Exposes the embedded CPython C API to Swift. The header resolves
6
+ // through the linked Python.xcframework's framework search path.
7
+ //
8
+
9
+ #ifndef ios_template_BridgingHeader_h
10
+ #define ios_template_BridgingHeader_h
11
+
12
+ #include <Python/Python.h>
13
+
14
+ #endif /* ios_template_BridgingHeader_h */
@@ -0,0 +1,28 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <!-- PythonNative's StatusBar element is applied through PNViewController's
6
+ preferredStatusBarStyle / prefersStatusBarHidden overrides, so the
7
+ modern view-controller-based appearance must stay enabled. -->
8
+ <key>UIViewControllerBasedStatusBarAppearance</key>
9
+ <true/>
10
+ <key>UIApplicationSceneManifest</key>
11
+ <dict>
12
+ <key>UIApplicationSupportsMultipleScenes</key>
13
+ <false/>
14
+ <key>UISceneConfigurations</key>
15
+ <dict>
16
+ <key>UIWindowSceneSessionRoleApplication</key>
17
+ <array>
18
+ <dict>
19
+ <key>UISceneConfigurationName</key>
20
+ <string>Default Configuration</string>
21
+ <key>UISceneDelegateClassName</key>
22
+ <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
23
+ </dict>
24
+ </array>
25
+ </dict>
26
+ </dict>
27
+ </dict>
28
+ </plist>
@@ -0,0 +1,390 @@
1
+ //
2
+ // PythonRuntime.swift
3
+ // ios_template
4
+ //
5
+ // Embeds CPython directly through the C API (no PythonKit). The
6
+ // Python.xcframework is linked at build time, so a missing runtime is
7
+ // a build error, never a silent runtime fallback.
8
+ //
9
+ // After the interpreter starts, `pythonnative.bootstrap.start()` binds
10
+ // the PythonNativeKit C exports, registers the Python callback, and
11
+ // verifies the protocol version. Everything else (screens, modules,
12
+ // deep links) flows over that bridge; nothing else here calls Python
13
+ // functions by name.
14
+ //
15
+
16
+ import Foundation
17
+ import PythonNativeKit
18
+
19
+ enum PythonRuntimeError: Error, CustomStringConvertible {
20
+ case startup(String)
21
+ case call(String)
22
+
23
+ var description: String {
24
+ switch self {
25
+ case .startup(let message): return message
26
+ case .call(let message): return message
27
+ }
28
+ }
29
+ }
30
+
31
+ /// An owned reference to a Python object. Reference counting is handled
32
+ /// automatically; the wrapped pointer is released on deinit.
33
+ final class PyRef {
34
+ fileprivate let pointer: UnsafeMutablePointer<PyObject>
35
+
36
+ fileprivate init(owned pointer: UnsafeMutablePointer<PyObject>) {
37
+ self.pointer = pointer
38
+ }
39
+
40
+ deinit {
41
+ let gil = PyGILState_Ensure()
42
+ Py_DecRef(pointer)
43
+ PyGILState_Release(gil)
44
+ }
45
+
46
+ /// Call a method on this object with string/number/bool arguments.
47
+ @discardableResult
48
+ func call(_ method: String, _ args: Any...) throws -> PyRef {
49
+ let gil = PyGILState_Ensure()
50
+ defer { PyGILState_Release(gil) }
51
+ guard let bound = PyObject_GetAttrString(pointer, method) else {
52
+ throw PythonRuntimeError.call("Python object has no method '\(method)': \(PythonRuntime.consumeError())")
53
+ }
54
+ defer { Py_DecRef(bound) }
55
+ return try PythonRuntime.invoke(bound, args: args, context: method)
56
+ }
57
+
58
+ /// Truthiness of the wrapped object (`PyObject_IsTrue`).
59
+ var isTruthy: Bool {
60
+ let gil = PyGILState_Ensure()
61
+ defer { PyGILState_Release(gil) }
62
+ return PyObject_IsTrue(pointer) == 1
63
+ }
64
+ }
65
+
66
+ /// Owns the embedded CPython interpreter for the whole process.
67
+ final class PythonRuntime {
68
+ static let shared = PythonRuntime()
69
+
70
+ private(set) var started = false
71
+ private(set) var startupError: String? = nil
72
+
73
+ private init() {}
74
+
75
+ // MARK: - Startup
76
+
77
+ /// Initialize the embedded interpreter once and complete the bridge
78
+ /// handshake. Throws with a full description when the bundle is not
79
+ /// packaged correctly or the protocol versions disagree; there is
80
+ /// deliberately no fallback mode.
81
+ func ensureStarted() throws {
82
+ if let error = startupError { throw PythonRuntimeError.startup(error) }
83
+ if started { return }
84
+ do {
85
+ try start()
86
+ // The interpreter is live from here on; a failed handshake is
87
+ // recorded as a startup error but Python is never re-initialized.
88
+ started = true
89
+ try connectBridge()
90
+ } catch let error as PythonRuntimeError {
91
+ startupError = error.description
92
+ throw error
93
+ }
94
+ }
95
+
96
+ /// Run `pythonnative.bootstrap.start(dev, strict=True)`: it binds the
97
+ /// `pn_bridge_*` symbols, registers the native -> Python callback,
98
+ /// verifies the protocol version against `pn_bridge_protocol_version()`,
99
+ /// routes `print()` to the console, and warms the asyncio runtime.
100
+ private func connectBridge() throws {
101
+ #if DEBUG
102
+ let dev = true
103
+ #else
104
+ let dev = false
105
+ #endif
106
+ do {
107
+ try callList(module: "pythonnative.bootstrap", function: "start", [dev, true])
108
+ } catch let error as PythonRuntimeError {
109
+ throw PythonRuntimeError.startup(
110
+ "Bridge bootstrap failed (native protocol v\(pn_bridge_protocol_version())):\n\(error.description)"
111
+ )
112
+ }
113
+ guard PNBridge.shared.hasCallback else {
114
+ throw PythonRuntimeError.startup(
115
+ "pythonnative.bridge.handshake() returned without registering the native callback."
116
+ )
117
+ }
118
+ }
119
+
120
+ private func start() throws {
121
+ guard let resourcePath = Bundle.main.resourcePath else {
122
+ throw PythonRuntimeError.startup("The app bundle has no resource path; the build is corrupt.")
123
+ }
124
+ let pythonHome = "\(resourcePath)/python"
125
+ let appPath = "\(resourcePath)/app"
126
+ let packagesPath = "\(resourcePath)/app_packages"
127
+ for (path, hint) in [
128
+ (pythonHome, "the embedded Python runtime"),
129
+ (appPath, "the app's Python sources"),
130
+ (packagesPath, "the bundled Python packages"),
131
+ ] where !FileManager.default.fileExists(atPath: path) {
132
+ throw PythonRuntimeError.startup(
133
+ "Missing \(hint) at \(path). Build the app with 'pn run ios' or 'pn build ios' "
134
+ + "so the PythonNative CLI stages the Python runtime; the raw Xcode template "
135
+ + "cannot run on its own."
136
+ )
137
+ }
138
+
139
+ // The embedded CPython (3.13+) reports sys.platform == "ios" on its
140
+ // own; this explicit override is belt-and-braces for
141
+ // pythonnative.utils.IS_IOS and costs nothing.
142
+ setenv("PN_PLATFORM", "ios", 1)
143
+
144
+ var preconfig = PyPreConfig()
145
+ PyPreConfig_InitIsolatedConfig(&preconfig)
146
+ preconfig.utf8_mode = 1
147
+ var status = Py_PreInitialize(&preconfig)
148
+ if PyStatus_Exception(status) != 0 {
149
+ throw PythonRuntimeError.startup("Unable to pre-initialize Python: \(Self.statusMessage(status))")
150
+ }
151
+
152
+ var config = PyConfig()
153
+ PyConfig_InitIsolatedConfig(&config)
154
+ defer { PyConfig_Clear(&config) }
155
+ // Unbuffered stdio so print() reaches the device log immediately.
156
+ config.buffered_stdio = 0
157
+ // The signed bundle is immutable; never try to write bytecode.
158
+ config.write_bytecode = 0
159
+
160
+ guard let homeW = Py_DecodeLocale(pythonHome, nil) else {
161
+ throw PythonRuntimeError.startup("Could not decode the Python home path.")
162
+ }
163
+ status = withUnsafeMutablePointer(to: &config) { cfg in
164
+ PyConfig_SetString(cfg, &cfg.pointee.home, homeW)
165
+ }
166
+ PyMem_RawFree(homeW)
167
+ if PyStatus_Exception(status) != 0 {
168
+ throw PythonRuntimeError.startup("Unable to set the Python home: \(Self.statusMessage(status))")
169
+ }
170
+
171
+ status = PyConfig_Read(&config)
172
+ if PyStatus_Exception(status) != 0 {
173
+ throw PythonRuntimeError.startup("Unable to read the Python config: \(Self.statusMessage(status))")
174
+ }
175
+
176
+ status = Py_InitializeFromConfig(&config)
177
+ if PyStatus_Exception(status) != 0 {
178
+ throw PythonRuntimeError.startup("Unable to initialize Python: \(Self.statusMessage(status))")
179
+ }
180
+
181
+ // The interpreter is live and this thread holds the GIL. Finish
182
+ // path setup, then release the GIL; every later entry point
183
+ // re-acquires it via PyGILState_Ensure.
184
+ do {
185
+ try bootstrapPaths(appPath: appPath, packagesPath: packagesPath)
186
+ } catch {
187
+ PyEval_SaveThread()
188
+ throw error
189
+ }
190
+ PyEval_SaveThread()
191
+ NSLog("[PN] Embedded Python initialized (home: \(pythonHome))")
192
+ }
193
+
194
+ private func bootstrapPaths(appPath: String, packagesPath: String) throws {
195
+ // site.addsitedir(app_packages): adds to sys.path and honors .pth files.
196
+ guard let site = PyImport_ImportModule("site"),
197
+ let addsitedir = PyObject_GetAttrString(site, "addsitedir")
198
+ else {
199
+ throw PythonRuntimeError.startup("Could not import the site module: \(Self.consumeError())")
200
+ }
201
+ defer { Py_DecRef(site) }
202
+ defer { Py_DecRef(addsitedir) }
203
+ guard let packagesObj = PyUnicode_FromString(packagesPath),
204
+ let argsTuple = PyTuple_New(1)
205
+ else {
206
+ throw PythonRuntimeError.startup("Could not build site.addsitedir arguments.")
207
+ }
208
+ PyTuple_SetItem(argsTuple, 0, packagesObj) // steals packagesObj
209
+ defer { Py_DecRef(argsTuple) }
210
+ guard let addResult = PyObject_CallObject(addsitedir, argsTuple) else {
211
+ throw PythonRuntimeError.startup("site.addsitedir failed: \(Self.consumeError())")
212
+ }
213
+ Py_DecRef(addResult)
214
+
215
+ // sys.path.insert(0, app) so `import app.main` resolves.
216
+ guard let sys = PyImport_ImportModule("sys"),
217
+ let sysPath = PyObject_GetAttrString(sys, "path"),
218
+ let appObj = PyUnicode_FromString(appPath)
219
+ else {
220
+ throw PythonRuntimeError.startup("Could not access sys.path: \(Self.consumeError())")
221
+ }
222
+ defer { Py_DecRef(sys) }
223
+ defer { Py_DecRef(sysPath) }
224
+ defer { Py_DecRef(appObj) }
225
+ // The bundle root itself is also importable ("app" package form).
226
+ if let resourceObj = PyUnicode_FromString(Bundle.main.resourcePath ?? appPath) {
227
+ PyList_Insert(sysPath, 0, resourceObj)
228
+ Py_DecRef(resourceObj)
229
+ }
230
+ if PyList_Insert(sysPath, 0, appObj) != 0 {
231
+ throw PythonRuntimeError.startup("Could not add the app directory to sys.path.")
232
+ }
233
+
234
+ #if DEBUG
235
+ // Dev-only: prioritize the writable hot-reload overlay. Release
236
+ // builds never look outside the signed bundle.
237
+ let documents = NSHomeDirectory() + "/Documents"
238
+ guard let hotReload = PyImport_ImportModule("pythonnative.hot_reload"),
239
+ let configure = PyObject_GetAttrString(hotReload, "configure_dev_environment"),
240
+ let docsObj = PyUnicode_FromString(documents),
241
+ let devArgs = PyTuple_New(1)
242
+ else {
243
+ throw PythonRuntimeError.startup(
244
+ "Could not import pythonnative: \(Self.consumeError())\n"
245
+ + "The pythonnative package must be staged into app_packages by the pn CLI."
246
+ )
247
+ }
248
+ defer { Py_DecRef(hotReload) }
249
+ defer { Py_DecRef(configure) }
250
+ PyTuple_SetItem(devArgs, 0, docsObj) // steals docsObj
251
+ defer { Py_DecRef(devArgs) }
252
+ if let devResult = PyObject_CallObject(configure, devArgs) {
253
+ Py_DecRef(devResult)
254
+ } else {
255
+ throw PythonRuntimeError.startup("Hot-reload setup failed: \(Self.consumeError())")
256
+ }
257
+ #endif
258
+ }
259
+
260
+ // MARK: - Calling into Python
261
+
262
+ /// Import `module` and call its `function` with the given arguments.
263
+ /// Supported argument types: String, Int, UInt, Bool, Double.
264
+ @discardableResult
265
+ func call(module: String, function: String, _ args: Any...) throws -> PyRef {
266
+ try callList(module: module, function: function, args)
267
+ }
268
+
269
+ @discardableResult
270
+ func callList(module: String, function: String, _ args: [Any]) throws -> PyRef {
271
+ guard started else {
272
+ throw PythonRuntimeError.call("Python is not running (startup failed or never happened).")
273
+ }
274
+ let gil = PyGILState_Ensure()
275
+ defer { PyGILState_Release(gil) }
276
+ guard let moduleObj = PyImport_ImportModule(module) else {
277
+ throw PythonRuntimeError.call("Could not import \(module): \(Self.consumeError())")
278
+ }
279
+ defer { Py_DecRef(moduleObj) }
280
+ guard let fnObj = PyObject_GetAttrString(moduleObj, function) else {
281
+ throw PythonRuntimeError.call("\(module) has no attribute '\(function)': \(Self.consumeError())")
282
+ }
283
+ defer { Py_DecRef(fnObj) }
284
+ return try Self.invoke(fnObj, args: args, context: "\(module).\(function)")
285
+ }
286
+
287
+ /// Shared invocation helper. The caller must hold the GIL.
288
+ fileprivate static func invoke(
289
+ _ callable: UnsafeMutablePointer<PyObject>,
290
+ args: [Any],
291
+ context: String
292
+ ) throws -> PyRef {
293
+ guard let tuple = PyTuple_New(args.count) else {
294
+ throw PythonRuntimeError.call("Could not allocate arguments for \(context).")
295
+ }
296
+ for (index, arg) in args.enumerated() {
297
+ guard let converted = convert(arg) else {
298
+ Py_DecRef(tuple)
299
+ throw PythonRuntimeError.call("Unsupported argument type \(type(of: arg)) for \(context).")
300
+ }
301
+ PyTuple_SetItem(tuple, index, converted) // steals converted
302
+ }
303
+ defer { Py_DecRef(tuple) }
304
+ guard let result = PyObject_CallObject(callable, tuple) else {
305
+ throw PythonRuntimeError.call("\(context) raised: \(consumeError())")
306
+ }
307
+ return PyRef(owned: result)
308
+ }
309
+
310
+ private static func convert(_ value: Any) -> UnsafeMutablePointer<PyObject>? {
311
+ switch value {
312
+ case let string as String:
313
+ return PyUnicode_FromString(string)
314
+ case let flag as Bool:
315
+ return PyBool_FromLong(flag ? 1 : 0)
316
+ case let unsigned as UInt:
317
+ return PyLong_FromUnsignedLongLong(UInt64(unsigned))
318
+ case let integer as Int:
319
+ return PyLong_FromLongLong(Int64(integer))
320
+ case let double as Double:
321
+ return PyFloat_FromDouble(double)
322
+ default:
323
+ return nil
324
+ }
325
+ }
326
+
327
+ // MARK: - Error formatting
328
+
329
+ /// Format and clear the pending Python exception (caller holds the GIL).
330
+ fileprivate static func consumeError() -> String {
331
+ var ptype: UnsafeMutablePointer<PyObject>? = nil
332
+ var pvalue: UnsafeMutablePointer<PyObject>? = nil
333
+ var ptrace: UnsafeMutablePointer<PyObject>? = nil
334
+ PyErr_Fetch(&ptype, &pvalue, &ptrace)
335
+ PyErr_NormalizeException(&ptype, &pvalue, &ptrace)
336
+ defer {
337
+ Py_DecRef(ptype)
338
+ Py_DecRef(pvalue)
339
+ Py_DecRef(ptrace)
340
+ }
341
+ guard ptype != nil else { return "unknown Python error" }
342
+
343
+ if let traceback = PyImport_ImportModule("traceback") {
344
+ defer { Py_DecRef(traceback) }
345
+ let fnName = ptrace != nil ? "format_exception" : "format_exception_only"
346
+ if let formatFn = PyObject_GetAttrString(traceback, fnName) {
347
+ defer { Py_DecRef(formatFn) }
348
+ let count = ptrace != nil ? 3 : 2
349
+ if let tuple = PyTuple_New(count) {
350
+ Py_IncRef(ptype)
351
+ PyTuple_SetItem(tuple, 0, ptype)
352
+ Py_IncRef(pvalue)
353
+ PyTuple_SetItem(tuple, 1, pvalue)
354
+ if count == 3 {
355
+ Py_IncRef(ptrace)
356
+ PyTuple_SetItem(tuple, 2, ptrace)
357
+ }
358
+ defer { Py_DecRef(tuple) }
359
+ if let lines = PyObject_CallObject(formatFn, tuple) {
360
+ defer { Py_DecRef(lines) }
361
+ if let empty = PyUnicode_FromString(""),
362
+ let joined = PyUnicode_Join(empty, lines)
363
+ {
364
+ Py_DecRef(empty)
365
+ defer { Py_DecRef(joined) }
366
+ if let utf8 = PyUnicode_AsUTF8(joined) {
367
+ return String(cString: utf8)
368
+ }
369
+ }
370
+ }
371
+ }
372
+ }
373
+ }
374
+ // Fallback: str(value).
375
+ if let value = pvalue, let str = PyObject_Str(value) {
376
+ defer { Py_DecRef(str) }
377
+ if let utf8 = PyUnicode_AsUTF8(str) {
378
+ return String(cString: utf8)
379
+ }
380
+ }
381
+ return "unknown Python error"
382
+ }
383
+
384
+ private static func statusMessage(_ status: PyStatus) -> String {
385
+ if let errMsg = status.err_msg {
386
+ return String(cString: errMsg)
387
+ }
388
+ return "unknown error"
389
+ }
390
+ }
@@ -0,0 +1,61 @@
1
+ //
2
+ // SceneDelegate.swift
3
+ // ios_template
4
+ //
5
+ // Creates the window programmatically and forwards scene-level events
6
+ // (deep links, foreground/background transitions) to the Swift native
7
+ // modules, which relay them to Python over the bridge.
8
+ //
9
+
10
+ import PythonNativeKit
11
+ import UIKit
12
+
13
+ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
14
+ var window: UIWindow?
15
+
16
+ func scene(
17
+ _ scene: UIScene,
18
+ willConnectTo session: UISceneSession,
19
+ options connectionOptions: UIScene.ConnectionOptions
20
+ ) {
21
+ guard let windowScene = (scene as? UIWindowScene) else { return }
22
+ // A cold start from a deep link delivers the URL here, before
23
+ // Python is running; LinkingModule buffers it until the bridge
24
+ // callback is registered so Linking.get_initial_url() sees it.
25
+ for context in connectionOptions.urlContexts {
26
+ LinkingModule.deliver(url: context.url.absoluteString)
27
+ }
28
+ let window = UIWindow(windowScene: windowScene)
29
+ let root = ViewController()
30
+ let nav = UINavigationController(rootViewController: root)
31
+ window.rootViewController = nav
32
+ self.window = window
33
+ window.makeKeyAndVisible()
34
+ }
35
+
36
+ func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
37
+ for context in URLContexts {
38
+ LinkingModule.deliver(url: context.url.absoluteString)
39
+ }
40
+ }
41
+
42
+ // MARK: - AppState forwarding
43
+
44
+ func sceneDidBecomeActive(_ scene: UIScene) {
45
+ AppStateModule.dispatch("active")
46
+ }
47
+
48
+ func sceneWillResignActive(_ scene: UIScene) {
49
+ AppStateModule.dispatch("inactive")
50
+ }
51
+
52
+ func sceneWillEnterForeground(_ scene: UIScene) {
53
+ AppStateModule.dispatch("inactive")
54
+ }
55
+
56
+ func sceneDidEnterBackground(_ scene: UIScene) {
57
+ AppStateModule.dispatch("background")
58
+ }
59
+
60
+ func sceneDidDisconnect(_ scene: UIScene) {}
61
+ }
@@ -0,0 +1,23 @@
1
+ //
2
+ // ViewController.swift
3
+ // ios_template
4
+ //
5
+ // Hosts one PythonNative screen. All screen plumbing lives in
6
+ // PythonNativeKit's PNViewController; this subclass only starts the
7
+ // embedded interpreter (showing a bootstrap error on failure).
8
+ //
9
+
10
+ import PythonNativeKit
11
+ import UIKit
12
+
13
+ final class ViewController: PNViewController {
14
+ override func prepareRuntime() -> Bool {
15
+ do {
16
+ try PythonRuntime.shared.ensureStarted()
17
+ } catch {
18
+ showBootstrapError("Python failed to start.\n\n\(error)")
19
+ return false
20
+ }
21
+ return true
22
+ }
23
+ }