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,375 @@
1
+ """``ErrorBoundary`` and ``Suspense`` handling for the reconciler.
2
+
3
+ Both boundaries are transparent wrappers whose children are swapped
4
+ for a fallback subtree when something goes wrong beneath them:
5
+
6
+ - an **error boundary** catches exceptions raised while rendering its
7
+ subtree, mounts its ``fallback`` (optionally receiving the error and
8
+ a ``reset`` callable), and rebuilds the content when ``reset`` runs;
9
+ - a **Suspense** boundary catches [`Suspend`][pythonnative.suspense.Suspend]
10
+ signals (an ``async`` body or a [`use_resource`][pythonnative.use_resource]
11
+ read that isn't ready), shows its ``fallback``, and retries the
12
+ content once the awaited work completes. Hook states of components
13
+ that had already rendered are preserved across the retry so cached
14
+ resources aren't refetched.
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ import inspect
20
+ from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Tuple
21
+
22
+ from .. import diagnostics
23
+ from ..element import Element
24
+ from ..hooks import HookState
25
+ from ..suspense import Suspend
26
+ from .vnode import VNode, normalize_children
27
+
28
+ if TYPE_CHECKING:
29
+ from ..scheduler import TransitionQueue
30
+
31
+ HydrationMap = Dict[Tuple[int, Any], List[HookState]]
32
+
33
+
34
+ class BoundaryMixin:
35
+ """Error-boundary and Suspense behavior mixed into the reconciler."""
36
+
37
+ # Attributes provided by the concrete reconciler.
38
+ _dirty_boundaries: Dict[int, VNode]
39
+ _dirty_suspense: Dict[int, VNode]
40
+ _hydration: Optional[HydrationMap]
41
+ _suspense_salvage: Optional[HydrationMap]
42
+ transitions: "TransitionQueue"
43
+
44
+ # Methods provided by the concrete reconciler.
45
+ def _create_child_list(self, elements: List[Element]) -> List[VNode]: ... # pragma: no cover
46
+
47
+ def _reconcile_child_list(self, old: List[VNode], new: List[Element]) -> List[VNode]: ... # pragma: no cover
48
+
49
+ def _destroy_tree(self, node: VNode, salvage: Optional[HydrationMap] = None) -> None: ... # pragma: no cover
50
+
51
+ def _refresh_identity(self, node: VNode) -> None: ... # pragma: no cover
52
+
53
+ def request_render(self) -> None: # pragma: no cover
54
+ """Ask for another render pass (provided by the concrete reconciler)."""
55
+ ...
56
+
57
+ # ------------------------------------------------------------------
58
+ # Error boundaries
59
+ # ------------------------------------------------------------------
60
+
61
+ def _create_error_boundary(self, element: Element) -> VNode:
62
+ node = VNode(element, [])
63
+ try:
64
+ children = self._create_child_list(normalize_children(element.children, owner="ErrorBoundary"))
65
+ except Exception as exc:
66
+ self._activate_boundary(node, exc)
67
+ return node
68
+ for child in children:
69
+ child.parent = node
70
+ node.children = children
71
+ self._refresh_identity(node)
72
+ return node
73
+
74
+ def _reconcile_error_boundary(self, old: VNode, new_el: Element) -> VNode:
75
+ old.element = new_el
76
+ if old.error is not None:
77
+ # Fallback is showing; keep showing it (rebuilt against the
78
+ # latest fallback prop) until reset() clears the error.
79
+ fallback_els = self._error_fallback_elements(old, old.error)
80
+ old.children = self._reconcile_child_list(old.children, fallback_els)
81
+ for child in old.children:
82
+ child.parent = old
83
+ self._refresh_identity(old)
84
+ return old
85
+ try:
86
+ children = self._reconcile_child_list(
87
+ old.children, normalize_children(new_el.children, owner="ErrorBoundary")
88
+ )
89
+ old.children = children
90
+ for child in children:
91
+ child.parent = old
92
+ self._refresh_identity(old)
93
+ except Exception as exc:
94
+ self._activate_boundary(old, exc)
95
+ return old
96
+
97
+ def _activate_boundary(self, node: VNode, exc: BaseException) -> None:
98
+ """Destroy a boundary's failed subtree and mount its fallback.
99
+
100
+ Calls the ``on_error`` prop (if any), records the error on the
101
+ node, and replaces the children with the rendered fallback.
102
+ Re-raises when the boundary has no fallback, letting an outer
103
+ boundary (or the screen host) take over.
104
+ """
105
+ props = node.element.props
106
+ on_error = props.get("on_error")
107
+ if callable(on_error):
108
+ try:
109
+ on_error(exc)
110
+ except Exception as cb_exc:
111
+ diagnostics.warn(f"ErrorBoundary on_error callback raised {cb_exc!r}")
112
+ if props.get("fallback") is None:
113
+ raise exc
114
+ for child in node.children:
115
+ self._destroy_tree(child)
116
+ node.children = []
117
+ node.error = exc
118
+ children = self._create_child_list(self._error_fallback_elements(node, exc))
119
+ for child in children:
120
+ child.parent = node
121
+ node.children = children
122
+ self._refresh_identity(node)
123
+
124
+ def _error_fallback_elements(self, node: VNode, exc: BaseException) -> List[Element]:
125
+ """Render a boundary's fallback prop into a normalized child list."""
126
+ fallback = node.element.props.get("fallback")
127
+ if fallback is None:
128
+ return []
129
+ result: Any = fallback
130
+ if callable(fallback) and not isinstance(fallback, Element):
131
+ arity = _positional_arity(fallback)
132
+ if arity >= 2:
133
+ result = fallback(exc, self._make_boundary_reset(node))
134
+ elif arity == 1:
135
+ result = fallback(exc)
136
+ else:
137
+ result = fallback()
138
+ return normalize_children(result, owner="ErrorBoundary.fallback")
139
+
140
+ def _make_boundary_reset(self, node: VNode) -> Callable[[], None]:
141
+ """Return the ``reset`` callable handed to a boundary's fallback."""
142
+
143
+ def reset() -> None:
144
+ if not node.mounted or node.error is None:
145
+ return
146
+ node.error = None
147
+ self._dirty_boundaries[id(node)] = node
148
+ from ..scheduler import schedule_trigger
149
+
150
+ schedule_trigger(self.request_render)
151
+
152
+ return reset
153
+
154
+ # ------------------------------------------------------------------
155
+ # Suspense boundaries
156
+ # ------------------------------------------------------------------
157
+
158
+ def _create_suspense(self, element: Element) -> VNode:
159
+ if element.props.get("fallback") is None:
160
+ return self._create_wrapper(element, "Suspense")
161
+ node = VNode(element, [])
162
+ self._attempt_suspense_content(node)
163
+ return node
164
+
165
+ def _reconcile_suspense(self, old: VNode, new_el: Element) -> VNode:
166
+ previous = old.element
167
+ old.element = new_el
168
+ if old.suspense_showing_fallback and previous.children != new_el.children:
169
+ if old.suspense_hydration:
170
+ self._dispose_hydration(old.suspense_hydration)
171
+ old.suspense_hydration = None
172
+ old.suspense_waits = None
173
+ self._attempt_suspense_content(old)
174
+ return old
175
+ if old.suspense_showing_fallback:
176
+ # Fallback showing; keep it in sync with the latest fallback
177
+ # prop. Content retries are driven by waitable completions,
178
+ # not by parent re-renders.
179
+ old.children = self._reconcile_child_list(old.children, self._suspense_fallback_elements(old))
180
+ for child in old.children:
181
+ child.parent = old
182
+ self._refresh_identity(old)
183
+ return old
184
+ try:
185
+ children = self._reconcile_child_list(old.children, normalize_children(new_el.children, owner="Suspense"))
186
+ old.children = children
187
+ for child in children:
188
+ child.parent = old
189
+ self._refresh_identity(old)
190
+ except Suspend as signal:
191
+ self._teardown_suspense_content(old)
192
+ self._suspend_boundary(old, signal)
193
+ return old
194
+
195
+ def _attempt_suspense_content(self, node: VNode) -> None:
196
+ """Build a boundary's content from scratch (initial mount or retry).
197
+
198
+ Components re-adopt hook states preserved from the previous
199
+ attempt (the hydration map), so cached resources resolve
200
+ instead of refetching. On success any still-showing fallback
201
+ is swapped out for the content; on suspension the fallback
202
+ mounts (or stays) and a retry is wired to the pending work.
203
+ """
204
+ hydration: HydrationMap = node.suspense_hydration or {}
205
+ node.suspense_hydration = None
206
+ saved_hydration = self._hydration
207
+ saved_salvage = self._suspense_salvage
208
+ self._hydration = hydration
209
+ self._suspense_salvage = None
210
+ try:
211
+ children = self._create_child_list(normalize_children(node.element.children, owner="Suspense"))
212
+ except Suspend as signal:
213
+ # Unclaimed hook states from the previous attempt stay
214
+ # preserved for the next retry; salvaged sibling states are
215
+ # folded in by _suspend_boundary.
216
+ merged = {key: states for key, states in hydration.items() if states}
217
+ node.suspense_hydration = merged or None
218
+ self._suspend_boundary(node, signal)
219
+ return
220
+ finally:
221
+ self._hydration = saved_hydration
222
+ self._suspense_salvage = saved_salvage
223
+
224
+ self._dispose_hydration(hydration)
225
+ for child in node.children:
226
+ self._destroy_tree(child)
227
+ for child in children:
228
+ child.parent = node
229
+ node.children = children
230
+ node.suspense_showing_fallback = False
231
+ node.suspense_waits = None
232
+ self._refresh_identity(node)
233
+
234
+ def _teardown_suspense_content(self, node: VNode) -> None:
235
+ """Destroy a boundary's live content, salvaging its hook states.
236
+
237
+ Used when an *update* under the boundary suspends: the content
238
+ components' hook states move into the boundary's hydration map,
239
+ so when the retry re-mounts them their state, caches, and
240
+ effect bookkeeping carry over (the fallback round-trip doesn't
241
+ reset the subtree).
242
+ """
243
+ salvage: HydrationMap = {}
244
+ for child in node.children:
245
+ self._destroy_tree(child, salvage=salvage)
246
+ node.children = []
247
+ node.suspense_showing_fallback = False
248
+ if salvage:
249
+ hydration = node.suspense_hydration
250
+ if hydration is None:
251
+ hydration = node.suspense_hydration = {}
252
+ for key, states in salvage.items():
253
+ hydration.setdefault(key, []).extend(states)
254
+
255
+ def _suspend_boundary(self, node: VNode, signal: Suspend) -> None:
256
+ """Show a boundary's fallback and schedule a retry for ``signal``.
257
+
258
+ A boundary without a fallback is transparent: the suspension
259
+ propagates to the next Suspense ancestor (mirroring how an
260
+ ErrorBoundary without a fallback re-raises).
261
+ """
262
+ if node.element.props.get("fallback") is None:
263
+ raise signal
264
+
265
+ # Fold in hook states salvaged while the Suspend unwound
266
+ # (already-rendered siblings of the suspender), plus the
267
+ # suspender's own state carried on the signal.
268
+ salvage = self._suspense_salvage
269
+ self._suspense_salvage = None
270
+ if salvage or (signal.hook_state is not None and signal.key is not None):
271
+ hydration = node.suspense_hydration
272
+ if hydration is None:
273
+ hydration = node.suspense_hydration = {}
274
+ if salvage:
275
+ for key, states in salvage.items():
276
+ hydration.setdefault(key, []).extend(states)
277
+ if signal.hook_state is not None and signal.key is not None:
278
+ bucket = hydration.setdefault(signal.key, [])
279
+ if signal.hook_state not in bucket:
280
+ bucket.append(signal.hook_state)
281
+
282
+ if not node.suspense_showing_fallback:
283
+ children = self._create_child_list(self._suspense_fallback_elements(node))
284
+ for child in children:
285
+ child.parent = node
286
+ node.children = children
287
+ node.suspense_showing_fallback = True
288
+ self._refresh_identity(node)
289
+
290
+ self._watch_waitable(node, signal.waitable)
291
+
292
+ @staticmethod
293
+ def _suspense_fallback_elements(node: VNode) -> List[Element]:
294
+ fallback = node.element.props.get("fallback")
295
+ if fallback is None:
296
+ return []
297
+ result: Any = fallback
298
+ if callable(fallback) and not isinstance(fallback, Element):
299
+ result = fallback()
300
+ return normalize_children(result, owner="Suspense.fallback")
301
+
302
+ def _watch_waitable(self, node: VNode, waitable: Any) -> None:
303
+ """Queue a content retry for ``node`` when ``waitable`` completes."""
304
+ waits = node.suspense_waits
305
+ if waits is None:
306
+ waits = node.suspense_waits = set()
307
+ marker = id(waitable)
308
+ if marker in waits:
309
+ return
310
+ waits.add(marker)
311
+
312
+ def _on_done(_w: Any = None) -> None:
313
+ live_waits = node.suspense_waits
314
+ if live_waits is not None:
315
+ live_waits.discard(marker)
316
+ if not node.mounted or not node.suspense_showing_fallback:
317
+ return
318
+ self._dirty_suspense[id(node)] = node
319
+ from ..scheduler import schedule_trigger
320
+
321
+ schedule_trigger(self.request_render)
322
+
323
+ waitable.add_done_callback(_on_done)
324
+
325
+ def _take_hydrated_hook_state(self, element: Element) -> Optional[HookState]:
326
+ """Pop a preserved hook state matching ``element`` from the hydration map."""
327
+ hydration = self._hydration
328
+ if not hydration:
329
+ return None
330
+ bucket = hydration.get((id(element.type), element.key))
331
+ if not bucket:
332
+ return None
333
+ return bucket.pop(0)
334
+
335
+ @staticmethod
336
+ def _dispose_hydration(hydration: HydrationMap) -> None:
337
+ """Clean up preserved hook states that no component reclaimed."""
338
+ for states in hydration.values():
339
+ for hook_state in states:
340
+ try:
341
+ hook_state.cleanup_all_effects()
342
+ except Exception as exc:
343
+ diagnostics.warn(f"Error disposing a suspended component's state: {exc!r}")
344
+ hydration.clear()
345
+
346
+ def _discard_salvage(self) -> None:
347
+ """Dispose hook states salvaged during a Suspend that no boundary caught."""
348
+ salvage = self._suspense_salvage
349
+ self._suspense_salvage = None
350
+ if salvage:
351
+ self._dispose_hydration(salvage)
352
+
353
+ @staticmethod
354
+ def _missing_suspense_error(signal: Suspend) -> RuntimeError:
355
+ who = signal.label or "A component"
356
+ return RuntimeError(
357
+ f"{who} suspended while rendering, but no Suspense ancestor provides a "
358
+ "fallback. Wrap the async part of the tree in pn.Suspense(..., "
359
+ "fallback=...) to declare its loading state."
360
+ )
361
+
362
+
363
+ def _positional_arity(fn: Callable[..., Any]) -> int:
364
+ """Count positional parameters ``fn`` accepts (2+ means unbounded is fine)."""
365
+ try:
366
+ sig = inspect.signature(fn)
367
+ except (TypeError, ValueError):
368
+ return 1
369
+ count = 0
370
+ for p in sig.parameters.values():
371
+ if p.kind in (inspect.Parameter.POSITIONAL_ONLY, inspect.Parameter.POSITIONAL_OR_KEYWORD):
372
+ count += 1
373
+ elif p.kind == inspect.Parameter.VAR_POSITIONAL:
374
+ return 2
375
+ return count
@@ -0,0 +1,88 @@
1
+ """Pure planning of native child-list moves.
2
+
3
+ Given the tags a native container currently holds and the tags it
4
+ should hold after a pass, [`plan_child_moves`][pythonnative.reconciler.children.plan_child_moves]
5
+ returns the minimal sequence of ``(tag, index)`` insertions (with
6
+ move-aware ``insert_child`` semantics: a child already attached is
7
+ re-positioned) that transforms one into the other.
8
+
9
+ The algorithm keeps the longest increasing subsequence of surviving
10
+ children in place and moves only the rest, processing right to left so
11
+ every moved child is inserted directly before an already-settled
12
+ neighbor. That yields ``n - len(LIS)`` operations, the optimum for a
13
+ move-aware insert primitive.
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ from bisect import bisect_left
19
+ from typing import Dict, List, Optional, Sequence, Tuple
20
+
21
+ __all__ = ["longest_increasing_subsequence", "plan_child_moves"]
22
+
23
+
24
+ def longest_increasing_subsequence(values: Sequence[int]) -> List[int]:
25
+ """Return the indices (into ``values``) of one longest strictly increasing subsequence."""
26
+ if not values:
27
+ return []
28
+ tails: List[int] = [] # values
29
+ tails_idx: List[int] = [] # index into values of each tail
30
+ prev: List[int] = [-1] * len(values)
31
+ for i, v in enumerate(values):
32
+ pos = bisect_left(tails, v)
33
+ if pos == len(tails):
34
+ tails.append(v)
35
+ tails_idx.append(i)
36
+ else:
37
+ tails[pos] = v
38
+ tails_idx[pos] = i
39
+ prev[i] = tails_idx[pos - 1] if pos > 0 else -1
40
+ out: List[int] = []
41
+ cursor = tails_idx[-1]
42
+ while cursor != -1:
43
+ out.append(cursor)
44
+ cursor = prev[cursor]
45
+ out.reverse()
46
+ return out
47
+
48
+
49
+ def plan_child_moves(before: Sequence[int], after: Sequence[int]) -> List[Tuple[int, int]]:
50
+ """Compute ``(tag, index)`` insert ops turning ``before`` into ``after``.
51
+
52
+ Args:
53
+ before: Tags currently attached to the container, in order.
54
+ Tags absent from ``after`` are assumed to be detached
55
+ already (the reconciler destroys them first) and must not
56
+ appear here.
57
+ after: Desired child tags, in order. Tags absent from
58
+ ``before`` are fresh children.
59
+
60
+ Returns:
61
+ Ordered insert operations. Applying each as "detach ``tag`` if
62
+ attached, then insert at ``index``" reproduces ``after``.
63
+ """
64
+ if list(before) == list(after):
65
+ return []
66
+ position_after: Dict[int, int] = {tag: i for i, tag in enumerate(after)}
67
+ # Surviving children in their current order, mapped to their target
68
+ # positions; the LIS of that sequence is the set we never touch.
69
+ surviving_targets = [position_after[tag] for tag in before if tag in position_after]
70
+ keep_positions = set(surviving_targets[i] for i in longest_increasing_subsequence(surviving_targets))
71
+
72
+ sim: List[int] = list(before)
73
+ ops: List[Tuple[int, int]] = []
74
+ anchor: Optional[int] = None
75
+ for i in range(len(after) - 1, -1, -1):
76
+ tag = after[i]
77
+ if i in keep_positions:
78
+ anchor = tag
79
+ continue
80
+ try:
81
+ sim.remove(tag)
82
+ except ValueError:
83
+ pass
84
+ index = sim.index(anchor) if anchor is not None else len(sim)
85
+ sim.insert(index, tag)
86
+ ops.append((tag, index))
87
+ anchor = tag
88
+ return ops