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,55 @@
1
+ """Conservative component compatibility for Fast Refresh."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import ast
6
+ import inspect
7
+ import textwrap
8
+ from typing import Any, Callable
9
+
10
+
11
+ def hook_signature(function: Callable[..., Any], _seen: frozenset[int] = frozenset()) -> tuple[str, ...] | None:
12
+ """Record hook order and binding names before the source file changes.
13
+
14
+ Binding names distinguish inserting or moving hooks of the same kind.
15
+ Uninspectable functions remount instead of risking slot corruption.
16
+ """
17
+ if id(function) in _seen:
18
+ return None
19
+ _seen = _seen | {id(function)}
20
+ try:
21
+ tree = ast.parse(textwrap.dedent(inspect.getsource(function)))
22
+ except (OSError, TypeError, SyntaxError):
23
+ return None
24
+ result = []
25
+ parents = {id(child): node for node in ast.walk(tree) for child in ast.iter_child_nodes(node)}
26
+ for node in ast.walk(tree):
27
+ if not isinstance(node, ast.Call):
28
+ continue
29
+ name = (
30
+ node.func.id
31
+ if isinstance(node.func, ast.Name)
32
+ else node.func.attr if isinstance(node.func, ast.Attribute) else ""
33
+ )
34
+ if not name.startswith("use_"):
35
+ continue
36
+ owner = parents.get(id(node))
37
+ binding = (
38
+ ast.dump(owner.targets[0])
39
+ if isinstance(owner, ast.Assign)
40
+ else ast.dump(owner.target) if isinstance(owner, ast.AnnAssign) else ""
41
+ )
42
+ signature = name + ":" + binding
43
+ target = None
44
+ if isinstance(node.func, ast.Name):
45
+ target = function.__globals__.get(node.func.id)
46
+ elif isinstance(node.func, ast.Attribute) and isinstance(node.func.value, ast.Name):
47
+ owner = function.__globals__.get(node.func.value.id)
48
+ target = getattr(owner, node.func.attr, None)
49
+ if inspect.isfunction(target) and not target.__module__.startswith("pythonnative."):
50
+ nested = hook_signature(target, _seen)
51
+ if nested is None:
52
+ return None
53
+ signature += repr(nested)
54
+ result.append((node.lineno, node.col_offset, signature))
55
+ return tuple(value for _, _, value in sorted(result))
@@ -0,0 +1,306 @@
1
+ """Application execution on a standard asyncio event loop.
2
+
3
+ Mobile hosts start one application thread with :func:`start`. All Python
4
+ rendering, callbacks, and tasks run there. Native hosts own their UI threads
5
+ and marshal view operations themselves. Headless programs can instead drive
6
+ an ordinary local loop with :func:`run_blocking` and :func:`drain`.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import asyncio
12
+ import contextvars
13
+ import inspect
14
+ import threading
15
+ from typing import Any, Awaitable, Callable, Coroutine, TypeVar
16
+
17
+ T = TypeVar("T")
18
+ Awaitlike = Coroutine[Any, Any, T] | Awaitable[T]
19
+ _loop: asyncio.AbstractEventLoop | None = None
20
+ _thread: threading.Thread | None = None
21
+ _owner: threading.Thread | None = None
22
+ _lock = threading.RLock()
23
+ _scope: contextvars.ContextVar[TaskScope | None] = contextvars.ContextVar("pn_task_scope", default=None)
24
+
25
+
26
+ class TaskScope:
27
+ """Own tasks until an application or component is disposed.
28
+
29
+ Closing a scope cancels its tasks and rejects new work. A task removes
30
+ itself when it finishes, including when it fails or is cancelled.
31
+ """
32
+
33
+ def __init__(self, name: str = "application") -> None:
34
+ self.name = name
35
+ self.closed = False
36
+ self._tasks: set[Any] = set()
37
+
38
+ @property
39
+ def pending(self) -> int:
40
+ """Number of unfinished tasks owned by this scope."""
41
+ return sum(not task.done() for task in self._tasks)
42
+
43
+ def create_task(self, awaitable: Awaitlike[T], *, report_errors: bool = False) -> Any:
44
+ """Schedule work with this scope's lifetime and context."""
45
+ if self.closed:
46
+ if inspect.iscoroutine(awaitable):
47
+ awaitable.close()
48
+ raise RuntimeError(f"Task scope {self.name!r} is closed")
49
+ token = _scope.set(self)
50
+ try:
51
+ task = _schedule(awaitable)
52
+ finally:
53
+ _scope.reset(token)
54
+ self._tasks.add(task)
55
+
56
+ def finished(done: Any) -> None:
57
+ self._tasks.discard(done)
58
+ if report_errors and not done.cancelled():
59
+ error = done.exception()
60
+ if error is not None:
61
+ from .diagnostics import report_error
62
+
63
+ if not report_error(error, phase=f"task in {self.name}"):
64
+ get_loop().call_exception_handler(
65
+ {"message": f"Task in {self.name} failed", "exception": error}
66
+ )
67
+
68
+ task.add_done_callback(finished)
69
+ return task
70
+
71
+ def close(self) -> None:
72
+ """Cancel owned work; calling this more than once is harmless."""
73
+ self.closed = True
74
+ for task in tuple(self._tasks):
75
+ if (
76
+ isinstance(task, asyncio.Future)
77
+ and task.get_loop().is_running()
78
+ and not _on_loop_thread(task.get_loop())
79
+ ):
80
+ task.get_loop().call_soon_threadsafe(task.cancel)
81
+ else:
82
+ task.cancel()
83
+ self._tasks.clear()
84
+
85
+
86
+ _application_scope = TaskScope()
87
+
88
+
89
+ def start() -> asyncio.AbstractEventLoop:
90
+ """Start the application thread once and return its event loop."""
91
+ global _loop, _thread, _owner
92
+ with _lock:
93
+ if _thread is not None and _thread.is_alive():
94
+ assert _loop is not None
95
+ return _loop
96
+ if _loop is not None and not _loop.is_closed():
97
+ raise RuntimeError("Start the application runtime before creating headless tasks")
98
+ ready = threading.Event()
99
+ loop = asyncio.new_event_loop()
100
+ _loop = loop
101
+
102
+ def serve() -> None:
103
+ asyncio.set_event_loop(loop)
104
+ ready.set()
105
+ try:
106
+ loop.run_forever()
107
+ finally:
108
+ loop.run_until_complete(_cancel_tasks(loop))
109
+ loop.run_until_complete(loop.shutdown_asyncgens())
110
+ loop.run_until_complete(loop.shutdown_default_executor())
111
+ loop.close()
112
+
113
+ _thread = threading.Thread(target=serve, name="PythonNative", daemon=True)
114
+ _owner = _thread
115
+ _thread.start()
116
+ ready.wait()
117
+ return loop
118
+
119
+
120
+ def get_loop() -> asyncio.AbstractEventLoop:
121
+ """Return the application loop, or the caller's loop in headless mode."""
122
+ global _loop, _owner
123
+ if _thread is not None and _thread.is_alive():
124
+ assert _loop is not None
125
+ return _loop
126
+ try:
127
+ return asyncio.get_running_loop()
128
+ except RuntimeError:
129
+ with _lock:
130
+ if _loop is None or _loop.is_closed():
131
+ _loop = asyncio.new_event_loop()
132
+ _owner = threading.current_thread()
133
+ return _loop
134
+
135
+
136
+ def _on_loop_thread(loop: asyncio.AbstractEventLoop) -> bool:
137
+ try:
138
+ return asyncio.get_running_loop() is loop
139
+ except RuntimeError:
140
+ return loop is _loop and threading.current_thread() is _owner
141
+
142
+
143
+ async def _ensure_coro(awaitable: Awaitlike[T]) -> T:
144
+ return await awaitable
145
+
146
+
147
+ def _schedule(awaitable: Awaitlike[T]) -> Any:
148
+ loop = get_loop()
149
+ if _on_loop_thread(loop):
150
+ return asyncio.ensure_future(awaitable, loop=loop)
151
+ return asyncio.run_coroutine_threadsafe(_ensure_coro(awaitable), loop)
152
+
153
+
154
+ def run_async(awaitable: Awaitlike[T]) -> Any:
155
+ """Schedule work in the current component scope or the application scope.
156
+
157
+ Returns an asyncio task on the application thread and a concurrent
158
+ future on other threads. Both handles support cancellation.
159
+ """
160
+ return (_scope.get() or _application_scope).create_task(awaitable)
161
+
162
+
163
+ def run_application_task(awaitable: Awaitlike[T]) -> Any:
164
+ """Start work that should survive the component that requested it."""
165
+ return _application_scope.create_task(awaitable)
166
+
167
+
168
+ def invoke(callback: Callable[..., Any], *args: Any, scope: TaskScope | None = None) -> Any:
169
+ """Invoke a callback and schedule an awaitable result in its owner's scope."""
170
+ owner = scope or _scope.get() or _application_scope
171
+ if owner.closed:
172
+ return None
173
+ token = _scope.set(owner)
174
+ try:
175
+ result = callback(*args)
176
+ if inspect.isawaitable(result):
177
+ return owner.create_task(result, report_errors=True)
178
+ return result
179
+ finally:
180
+ _scope.reset(token)
181
+
182
+
183
+ def run_blocking(awaitable: Awaitlike[T], timeout: float | None = None) -> T:
184
+ """Wait for work from synchronous code; never block the application loop."""
185
+ loop = get_loop()
186
+ if loop.is_running() and _on_loop_thread(loop):
187
+ if inspect.iscoroutine(awaitable):
188
+ awaitable.close()
189
+ raise RuntimeError("run_blocking() cannot run inside the event loop; await the result")
190
+
191
+ async def bounded() -> T:
192
+ async with asyncio.timeout(timeout):
193
+ return await awaitable
194
+
195
+ if loop.is_running():
196
+ return asyncio.run_coroutine_threadsafe(bounded(), loop).result()
197
+ return loop.run_until_complete(bounded())
198
+
199
+
200
+ def drain(timeout: float = 1.0, *, until: Callable[[], bool] | None = None) -> bool:
201
+ """Settle headless work or wait for application tasks from a test thread.
202
+
203
+ Long-lived application tasks require an explicit ``until`` predicate.
204
+ This uses public asyncio APIs and never inspects selector internals.
205
+ """
206
+
207
+ async def settle() -> bool:
208
+ loop = asyncio.get_running_loop()
209
+ deadline = loop.time() + timeout
210
+ idle_turns = 0
211
+ while loop.time() < deadline:
212
+ await asyncio.sleep(0)
213
+ if until is not None and until():
214
+ return True
215
+ pending = [task for task in asyncio.all_tasks() if task is not asyncio.current_task() and not task.done()]
216
+ if until is None and not pending:
217
+ idle_turns += 1
218
+ if idle_turns >= 3:
219
+ return True
220
+ else:
221
+ idle_turns = 0
222
+ await asyncio.sleep(0.001)
223
+ return False
224
+
225
+ return run_blocking(settle())
226
+
227
+
228
+ def call_threadsafe(callback: Callable[..., Any], *args: Any) -> None:
229
+ """Enqueue a callback on the application event loop from any thread."""
230
+ get_loop().call_soon_threadsafe(callback, *args)
231
+
232
+
233
+ def call_on_application_thread(fn: Callable[[], None]) -> None:
234
+ """Execute Python work on its owner thread, inline when already there."""
235
+ loop = get_loop()
236
+ if _on_loop_thread(loop):
237
+ fn()
238
+ else:
239
+ loop.call_soon_threadsafe(fn)
240
+
241
+
242
+ def resolve_future(future: asyncio.Future[T], value: T) -> None:
243
+ """Complete a future from any thread unless it was cancelled."""
244
+
245
+ def complete() -> None:
246
+ if not future.done():
247
+ future.set_result(value)
248
+
249
+ future.get_loop().call_soon_threadsafe(complete)
250
+
251
+
252
+ def reject_future(future: asyncio.Future[Any], error: BaseException) -> None:
253
+ """Fail a future from any thread unless it was cancelled."""
254
+
255
+ def complete() -> None:
256
+ if not future.done():
257
+ future.set_exception(error)
258
+
259
+ future.get_loop().call_soon_threadsafe(complete)
260
+
261
+
262
+ def create_future() -> asyncio.Future[Any]:
263
+ """Create a future for completion by a native request."""
264
+ return get_loop().create_future()
265
+
266
+
267
+ async def _cancel_tasks(loop: asyncio.AbstractEventLoop) -> None:
268
+ tasks = [task for task in asyncio.all_tasks(loop) if task is not asyncio.current_task()]
269
+ for task in tasks:
270
+ task.cancel()
271
+ await asyncio.gather(*tasks, return_exceptions=True)
272
+
273
+
274
+ def _shutdown_for_tests() -> None:
275
+ global _loop, _thread, _owner, _application_scope
276
+ with _lock:
277
+ loop, thread = _loop, _thread
278
+ _application_scope.close()
279
+ if loop is not None and not loop.is_closed():
280
+ if thread is not None:
281
+ loop.call_soon_threadsafe(loop.stop)
282
+ thread.join(timeout=5)
283
+ if thread.is_alive():
284
+ raise RuntimeError("Application thread did not stop")
285
+ elif not loop.is_running():
286
+ loop.run_until_complete(_cancel_tasks(loop))
287
+ loop.run_until_complete(loop.shutdown_asyncgens())
288
+ loop.close()
289
+ _loop = _thread = _owner = None
290
+ _application_scope = TaskScope()
291
+
292
+
293
+ __all__ = [
294
+ "TaskScope",
295
+ "call_on_application_thread",
296
+ "call_threadsafe",
297
+ "create_future",
298
+ "drain",
299
+ "get_loop",
300
+ "reject_future",
301
+ "resolve_future",
302
+ "run_application_task",
303
+ "run_async",
304
+ "run_blocking",
305
+ "start",
306
+ ]
@@ -0,0 +1,159 @@
1
+ """Update scheduling primitives shared by hooks and the reconciler.
2
+
3
+ Two pieces live here:
4
+
5
+ - [`batch_updates`][pythonnative.scheduler.batch_updates], a context manager that
6
+ coalesces the render triggers fired by several state setters into
7
+ one, tracked per execution context (so it composes with ``async``
8
+ code).
9
+ - [`TransitionQueue`][pythonnative.scheduler.TransitionQueue], the
10
+ per-reconciler queue behind
11
+ [`use_transition`][pythonnative.use_transition]: renders marked as
12
+ transitions are deferred to a later turn of the framework loop so
13
+ urgent updates (typing, presses) stay responsive.
14
+
15
+ Nothing here is global mutable state beyond context variables, so
16
+ several reconcilers (screens, list rows, tests) never interfere.
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ from contextlib import contextmanager
22
+ from contextvars import ContextVar
23
+ from typing import Callable, Generator, List, Optional
24
+
25
+ from . import diagnostics
26
+
27
+ __all__ = ["TransitionQueue", "batch_updates", "in_transition", "run_in_transition", "schedule_trigger"]
28
+
29
+ # Depth of nested ``batch_updates`` blocks plus the triggers deferred by
30
+ # the outermost block, per execution context.
31
+ _batch_depth: ContextVar[int] = ContextVar("pn_batch_depth", default=0)
32
+ _batch_pending: ContextVar[Optional[List[Callable[[], None]]]] = ContextVar("pn_batch_pending", default=None)
33
+
34
+ # Whether state updates in the current execution context are marked as
35
+ # transitions (see ``use_transition``).
36
+ _transition_var: ContextVar[bool] = ContextVar("pn_transition", default=False)
37
+
38
+
39
+ def schedule_trigger(trigger: Callable[[], None]) -> None:
40
+ """Run ``trigger`` now, or defer it to the end of the enclosing ``batch_updates`` block."""
41
+ pending = _batch_pending.get()
42
+ if _batch_depth.get() > 0 and pending is not None:
43
+ if trigger not in pending:
44
+ pending.append(trigger)
45
+ else:
46
+ trigger()
47
+
48
+
49
+ @contextmanager
50
+ def batch_updates() -> Generator[None, None, None]:
51
+ """Coalesce multiple state updates into a single re-render.
52
+
53
+ State setters called inside the ``with`` block defer their
54
+ re-render trigger until the block exits, so any number of
55
+ ``set_*`` calls produce at most one render pass.
56
+
57
+ Example:
58
+ ```python
59
+ import pythonnative as pn
60
+
61
+ with pn.batch_updates():
62
+ set_count(1)
63
+ set_name("hello")
64
+ ```
65
+ """
66
+ depth = _batch_depth.get()
67
+ depth_token = _batch_depth.set(depth + 1)
68
+ pending_token = None
69
+ if depth == 0:
70
+ pending_token = _batch_pending.set([])
71
+ try:
72
+ yield
73
+ finally:
74
+ _batch_depth.reset(depth_token)
75
+ if pending_token is not None:
76
+ triggers = _batch_pending.get() or []
77
+ _batch_pending.reset(pending_token)
78
+ for trigger in triggers:
79
+ trigger()
80
+
81
+
82
+ def in_transition() -> bool:
83
+ """Whether state updates in the current context are transitions."""
84
+ return _transition_var.get()
85
+
86
+
87
+ def run_in_transition(fn: Callable[[], None]) -> None:
88
+ """Run ``fn`` with its state updates marked as transitions."""
89
+ token = _transition_var.set(True)
90
+ try:
91
+ fn()
92
+ finally:
93
+ _transition_var.reset(token)
94
+
95
+
96
+ class TransitionQueue:
97
+ """Deferred render triggers and completion callbacks for one reconciler.
98
+
99
+ Triggers added via [`defer`][pythonnative.scheduler.TransitionQueue.defer]
100
+ run together on a later loop turn; callbacks added via
101
+ [`on_complete`][pythonnative.scheduler.TransitionQueue.on_complete]
102
+ run right after them (this is how ``use_transition`` flips its
103
+ ``is_pending`` flag back off once the deferred render committed).
104
+ """
105
+
106
+ __slots__ = ("_triggers", "_callbacks", "_scheduled")
107
+
108
+ def __init__(self) -> None:
109
+ self._triggers: List[Callable[[], None]] = []
110
+ self._callbacks: List[Callable[[], None]] = []
111
+ self._scheduled = False
112
+
113
+ def defer(self, trigger: Callable[[], None]) -> None:
114
+ """Queue ``trigger`` for the next flush."""
115
+ if trigger not in self._triggers:
116
+ self._triggers.append(trigger)
117
+ self._ensure_scheduled()
118
+
119
+ def on_complete(self, callback: Callable[[], None]) -> None:
120
+ """Queue ``callback`` to run after the next flush's triggers."""
121
+ self._callbacks.append(callback)
122
+ self._ensure_scheduled()
123
+
124
+ @property
125
+ def pending(self) -> bool:
126
+ """Whether a flush is scheduled or work is queued."""
127
+ return self._scheduled or bool(self._triggers) or bool(self._callbacks)
128
+
129
+ def flush(self) -> None:
130
+ """Run every deferred trigger, then the completion callbacks."""
131
+ self._scheduled = False
132
+ triggers = self._triggers
133
+ callbacks = self._callbacks
134
+ self._triggers = []
135
+ self._callbacks = []
136
+ for fn in triggers + callbacks:
137
+ try:
138
+ fn()
139
+ except Exception as exc:
140
+ if not diagnostics.report_error(exc, phase="transition"):
141
+ raise
142
+
143
+ def clear(self) -> None:
144
+ """Drop queued work (used on unmount)."""
145
+ self._triggers = []
146
+ self._callbacks = []
147
+ self._scheduled = False
148
+
149
+ def _ensure_scheduled(self) -> None:
150
+ if self._scheduled:
151
+ return
152
+ self._scheduled = True
153
+ from .runtime import get_loop
154
+
155
+ get_loop().call_soon(self._flush_if_scheduled)
156
+
157
+ def _flush_if_scheduled(self) -> None:
158
+ if self._scheduled:
159
+ self.flush()
@@ -0,0 +1,153 @@
1
+ """Public extension surface for PythonNative.
2
+
3
+ The ``pythonnative.sdk`` package collects the *stable* extension
4
+ contract that third-party packages rely on: the
5
+ [`Style`][pythonnative.sdk.Style] type, the
6
+ [`@native_component`][pythonnative.sdk.native_component] /
7
+ [`register_component`][pythonnative.sdk.register_component]
8
+ registration helpers, the
9
+ [`element_factory`][pythonnative.sdk.element_factory] helper for
10
+ producing strongly-typed element constructors, the
11
+ [`ViewHandler`][pythonnative.sdk.ViewHandler] protocol for off-device
12
+ stand-ins, and the native module registry
13
+ ([`native_module`][pythonnative.sdk.native_module],
14
+ [`register_python_module`][pythonnative.sdk.register_python_module]).
15
+
16
+ A custom native component is three things:
17
+
18
+ 1. A typed, frozen [`Props`][pythonnative.sdk.Props] dataclass listing
19
+ the public properties the component accepts.
20
+ 2. A Swift ``PNComponentManager`` and a Kotlin ``ComponentManager``
21
+ registered under the component's name by the package's native
22
+ plugin (``pn_plugin.json`` next to ``ios/`` and ``android/`` source
23
+ folders; see ``docs/guides/custom-components.md``).
24
+ 3. A registration call in Python
25
+ ([`register_component`][pythonnative.sdk.register_component], or the
26
+ [`@native_component`][pythonnative.sdk.native_component] decorator
27
+ when you also supply a test
28
+ [`ViewHandler`][pythonnative.sdk.ViewHandler] for the Python backend)
29
+ that declares the element name and binds its props type.
30
+
31
+ Once registered, the component appears alongside the built-ins: the
32
+ reconciler, layout engine, and Fast Refresh treat it identically.
33
+
34
+ A native module (device API without a view) follows the same split: a
35
+ Swift / Kotlin class registered by name in the plugin, a Python facade
36
+ that calls ``native_module(name).call(...)``, and optionally a Python
37
+ implementation registered with ``register_python_module`` for the
38
+ browser preview and tests.
39
+
40
+ PyPI packages can ship both without users importing them explicitly
41
+ by declaring entry points in the ``pythonnative.handlers`` (Python
42
+ side) and ``pythonnative.plugins`` (native source) groups; ``pn build``
43
+ compiles the native sources into the app.
44
+
45
+ Example:
46
+ ```python
47
+ from dataclasses import dataclass
48
+ import pythonnative as pn
49
+ from pythonnative.sdk import Props, element_factory, register_component
50
+
51
+
52
+ @dataclass(frozen=True)
53
+ class BadgeProps(Props):
54
+ text: str = ""
55
+ color: str = "#FF3B30"
56
+ style: pn.StyleProp = None
57
+
58
+
59
+ register_component(name="Badge", props=BadgeProps)
60
+ Badge = element_factory("Badge")
61
+
62
+
63
+ @pn.component
64
+ def App():
65
+ return pn.Column(
66
+ Badge(text="3", color="#0A84FF"),
67
+ pn.Text("Inbox"),
68
+ )
69
+ ```
70
+ """
71
+
72
+ from ..element import Element
73
+ from ..native_modules.registry import (
74
+ NativeModule,
75
+ NativeModuleError,
76
+ PythonModule,
77
+ emit,
78
+ native_module,
79
+ register_python_module,
80
+ )
81
+ from ..native_views.base import ViewHandler, parse_color_int
82
+ from ..style import (
83
+ Color,
84
+ Dimension,
85
+ EdgeInsets,
86
+ EdgeValue,
87
+ FlexDirection,
88
+ JustifyContent,
89
+ Overflow,
90
+ Position,
91
+ Style,
92
+ StyleProp,
93
+ TransformSpec,
94
+ style,
95
+ )
96
+ from ._components import (
97
+ ENTRY_POINT_GROUP,
98
+ Props,
99
+ element_factory,
100
+ get_props_type,
101
+ get_test_handler,
102
+ install_into_registry,
103
+ list_components,
104
+ native_component,
105
+ register_component,
106
+ unregister_component,
107
+ )
108
+ from .codegen import generate
109
+ from .schema import ComponentSchema, ModuleSchema, NativeField, register_schema
110
+
111
+ __all__ = [
112
+ "ComponentSchema",
113
+ "ModuleSchema",
114
+ "NativeField",
115
+ "register_schema",
116
+ "generate",
117
+ # Core types
118
+ "Element",
119
+ "ViewHandler",
120
+ # Style types
121
+ "Color",
122
+ "Dimension",
123
+ "EdgeInsets",
124
+ "EdgeValue",
125
+ "FlexDirection",
126
+ "JustifyContent",
127
+ "Overflow",
128
+ "Position",
129
+ "Style",
130
+ "StyleProp",
131
+ "TransformSpec",
132
+ "style",
133
+ # SDK helpers (re-exported so users only import from one place)
134
+ "parse_color_int",
135
+ # Native-component SDK
136
+ "ENTRY_POINT_GROUP",
137
+ "Props",
138
+ "element_factory",
139
+ "get_test_handler",
140
+ "get_props_type",
141
+ "install_into_registry",
142
+ "list_components",
143
+ "native_component",
144
+ "register_component",
145
+ "unregister_component",
146
+ # Native-module SDK
147
+ "NativeModule",
148
+ "NativeModuleError",
149
+ "PythonModule",
150
+ "emit",
151
+ "native_module",
152
+ "register_python_module",
153
+ ]