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,65 @@
1
+ """Cross-platform camera and gallery access.
2
+
3
+ Both entry points are coroutines: ``await Camera.take_photo()`` returns
4
+ the saved image path (a ``str``) or ``None`` if the user cancels. The
5
+ native ``Camera`` module presents ``UIImagePickerController`` (iOS) or
6
+ launches ``MediaStore.ACTION_IMAGE_CAPTURE`` / ``ACTION_PICK``
7
+ (Android) and resolves the call when the picker finishes; Python only
8
+ awaits the promise.
9
+
10
+ Example:
11
+ ```python
12
+ import pythonnative as pn
13
+
14
+ async def add_photo():
15
+ path = await pn.Camera.take_photo()
16
+ if path is None:
17
+ return # user cancelled
18
+ await save_to_album(path)
19
+ ```
20
+ """
21
+
22
+ from __future__ import annotations
23
+
24
+ from typing import Any, Optional
25
+
26
+ from .registry import native_module
27
+
28
+
29
+ class Camera:
30
+ """Camera and image-picker interface (static coroutines)."""
31
+
32
+ @staticmethod
33
+ async def take_photo(**options: Any) -> Optional[str]:
34
+ """Launch the device camera to capture a photo.
35
+
36
+ Args:
37
+ **options: Forwarded to the native module (``quality``,
38
+ ``allow_editing``, ...). Unknown keys are ignored.
39
+
40
+ Returns:
41
+ The saved image path, or ``None`` if the user cancelled (or
42
+ there is no camera to present, as in the browser preview).
43
+
44
+ Raises:
45
+ NativeModuleError: If the picker can't be presented, for
46
+ example because another picker is already open.
47
+ """
48
+ return await _launch("take_photo", options)
49
+
50
+ @staticmethod
51
+ async def pick_from_gallery(**options: Any) -> Optional[str]:
52
+ """Open the system gallery picker.
53
+
54
+ Returns:
55
+ The selected image path, or ``None`` if the user cancelled.
56
+
57
+ Raises:
58
+ NativeModuleError: If the picker can't be presented.
59
+ """
60
+ return await _launch("pick_from_gallery", options)
61
+
62
+
63
+ async def _launch(method: str, options: Any) -> Optional[str]:
64
+ result = await native_module("Camera").call_async(method, **options)
65
+ return str(result) if result else None
@@ -0,0 +1,46 @@
1
+ """Cross-platform clipboard access.
2
+
3
+ [`Clipboard`][pythonnative.Clipboard] reads and writes the system
4
+ pasteboard through the native ``Clipboard`` module (``UIPasteboard``
5
+ on iOS, ``ClipboardManager`` on Android). The pasteboard lives in
6
+ process memory on both platforms, so every method is synchronous.
7
+
8
+ Off device the module is a process-local string buffer, which keeps it
9
+ usable in ``pn preview`` and unit tests.
10
+
11
+ Example:
12
+ ```python
13
+ import pythonnative as pn
14
+
15
+ pn.Clipboard.set_string("hello")
16
+ assert pn.Clipboard.get_string() == "hello"
17
+ ```
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ from .registry import native_module
23
+
24
+
25
+ class Clipboard:
26
+ """System clipboard interface (synchronous).
27
+
28
+ Raises:
29
+ NativeModuleError: If the native module reports a failure.
30
+ """
31
+
32
+ @staticmethod
33
+ def set_string(text: str) -> None:
34
+ """Copy ``text`` onto the system clipboard."""
35
+ native_module("Clipboard").call("set_string", text="" if text is None else str(text))
36
+
37
+ @staticmethod
38
+ def get_string() -> str:
39
+ """Return the current clipboard string (``""`` when empty)."""
40
+ value = native_module("Clipboard").call("get_string")
41
+ return "" if value is None else str(value)
42
+
43
+ @staticmethod
44
+ def has_string() -> bool:
45
+ """Return ``True`` when the clipboard holds non-empty text."""
46
+ return bool(Clipboard.get_string())
@@ -0,0 +1,324 @@
1
+ """Pure-Python fallbacks for the built-in native modules.
2
+
3
+ On iOS and Android every module in this package is implemented in
4
+ Swift and Kotlin (``PythonNativeKit`` and the ``pythonnative`` Gradle
5
+ module). Off device the same module names resolve to the plain Python
6
+ classes below, which keep the API usable without a device: in-memory
7
+ buffers, ``"unknown"`` states, and no-op feedback. Unit tests use them
8
+ directly; the browser preview implements a handful of modules in the
9
+ page (``Alert``, ``Clipboard``, ``Device``, ...) and routes the rest
10
+ here.
11
+
12
+ Each class has the same method names and argument shapes as its native
13
+ counterpart, so a facade in this package never branches on platform.
14
+ Apps and tests may swap any of these with
15
+ [`register_python_module`][pythonnative.native_modules.registry.register_python_module].
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ import json
21
+ import os
22
+ import platform as _platform
23
+ import sys
24
+ import threading
25
+ from typing import Any, Callable, Dict, List, Optional
26
+
27
+ __all__ = ["default_implementation"]
28
+
29
+
30
+ # ======================================================================
31
+ # Device / host information
32
+ # ======================================================================
33
+
34
+
35
+ class FallbackDevice:
36
+ """Static device information for the host machine."""
37
+
38
+ def info(self) -> Dict[str, Any]:
39
+ home = os.path.expanduser("~")
40
+ app_dir = os.path.join(home, ".pythonnative_data")
41
+ return {
42
+ "platform": "test",
43
+ "os": sys.platform,
44
+ "os_version": _platform.release(),
45
+ "model": _platform.machine(),
46
+ "app_dir": app_dir,
47
+ "cache_dir": os.path.join(app_dir, "cache"),
48
+ "temp_dir": os.path.join(app_dir, "tmp"),
49
+ "locale": os.environ.get("LANG", "en_US").split(".")[0],
50
+ "app_version": "0.0.0",
51
+ "build_number": "0",
52
+ "bundle_id": "com.pythonnative.preview",
53
+ "python_version": _platform.python_version(),
54
+ }
55
+
56
+
57
+ class FallbackAppState:
58
+ def current_state(self) -> str:
59
+ return "active"
60
+
61
+
62
+ # ======================================================================
63
+ # Storage
64
+ # ======================================================================
65
+
66
+
67
+ class FallbackStorage:
68
+ """Dict-backed ``AsyncStorage`` with optional JSON persistence.
69
+
70
+ Set ``PN_STORAGE_DIR`` to persist between runs (``pn preview`` does
71
+ this); leave it unset in tests for a purely in-memory store.
72
+ """
73
+
74
+ def __init__(self) -> None:
75
+ self._lock = threading.Lock()
76
+ self._store: Dict[str, str] = {}
77
+ self._loaded = False
78
+
79
+ def _path(self) -> Optional[str]:
80
+ base = os.environ.get("PN_STORAGE_DIR")
81
+ if not base:
82
+ return None
83
+ try:
84
+ os.makedirs(base, exist_ok=True)
85
+ except OSError:
86
+ return None
87
+ return os.path.join(base, "pn_async_storage.json")
88
+
89
+ def _load(self) -> None:
90
+ if self._loaded:
91
+ return
92
+ self._loaded = True
93
+ path = self._path()
94
+ if path is None or not os.path.exists(path):
95
+ return
96
+ try:
97
+ with open(path, encoding="utf-8") as f:
98
+ data = json.load(f)
99
+ except (OSError, json.JSONDecodeError):
100
+ return
101
+ if isinstance(data, dict):
102
+ self._store.update({str(k): str(v) for k, v in data.items()})
103
+
104
+ def _persist(self) -> None:
105
+ path = self._path()
106
+ if path is None:
107
+ return
108
+ try:
109
+ with open(path, "w", encoding="utf-8") as f:
110
+ json.dump(self._store, f)
111
+ except OSError:
112
+ pass
113
+
114
+ def get(self, key: str) -> Optional[str]:
115
+ with self._lock:
116
+ self._load()
117
+ return self._store.get(key)
118
+
119
+ def set(self, key: str, value: str) -> None:
120
+ with self._lock:
121
+ self._load()
122
+ self._store[key] = value
123
+ self._persist()
124
+
125
+ def delete(self, key: str) -> None:
126
+ with self._lock:
127
+ self._load()
128
+ self._store.pop(key, None)
129
+ self._persist()
130
+
131
+ def all_keys(self) -> List[str]:
132
+ with self._lock:
133
+ self._load()
134
+ return list(self._store.keys())
135
+
136
+ def clear(self) -> None:
137
+ with self._lock:
138
+ self._store.clear()
139
+ self._persist()
140
+
141
+ def _reset(self) -> None:
142
+ """Forget everything, including the on-disk snapshot (tests)."""
143
+ with self._lock:
144
+ self._store.clear()
145
+ self._loaded = False
146
+
147
+
148
+ class FallbackSecureStore:
149
+ def __init__(self) -> None:
150
+ self._store: Dict[str, str] = {}
151
+
152
+ def set_item(self, key: str, value: str) -> bool:
153
+ self._store[key] = value
154
+ return True
155
+
156
+ def get_item(self, key: str) -> Optional[str]:
157
+ return self._store.get(key)
158
+
159
+ def delete_item(self, key: str) -> bool:
160
+ return self._store.pop(key, None) is not None
161
+
162
+ def clear(self) -> None:
163
+ self._store.clear()
164
+
165
+
166
+ class FallbackClipboard:
167
+ def __init__(self) -> None:
168
+ self._buffer = ""
169
+
170
+ def set_string(self, text: str) -> None:
171
+ self._buffer = "" if text is None else str(text)
172
+
173
+ def get_string(self) -> str:
174
+ return self._buffer
175
+
176
+
177
+ # ======================================================================
178
+ # System integration
179
+ # ======================================================================
180
+
181
+
182
+ class FallbackAlert:
183
+ """Records alerts and answers with scripted responses.
184
+
185
+ The log and response queue live on
186
+ [`Alert`][pythonnative.alerts.Alert] (``Alert._test_log`` and
187
+ ``Alert.set_test_response``) so tests have one place to look.
188
+ """
189
+
190
+ @staticmethod
191
+ def _record(title: str, message: Optional[str], buttons: List[Dict[str, Any]], style: str) -> Any:
192
+ from ..alerts import Alert
193
+
194
+ Alert._test_log.append({"title": title, "message": message, "buttons": list(buttons), "style": style})
195
+ return Alert
196
+
197
+ def show(self, title: str, message: Optional[str], buttons: List[Dict[str, Any]], style: str) -> None:
198
+ self._record(title, message, buttons, style)
199
+
200
+ def present(self, title: str, message: Optional[str], buttons: List[Dict[str, Any]], style: str) -> int:
201
+ return int(self._record(title, message, buttons, style)._next_test_response())
202
+
203
+
204
+ class FallbackShare:
205
+ def share(self, message: Optional[str] = None, url: Optional[str] = None, title: Optional[str] = None) -> bool:
206
+ del message, url, title
207
+ return False
208
+
209
+
210
+ class FallbackLinking:
211
+ def open_url(self, url: str) -> bool:
212
+ del url
213
+ return False
214
+
215
+ def can_open_url(self, url: str) -> bool:
216
+ del url
217
+ return False
218
+
219
+ def open_settings(self) -> bool:
220
+ return False
221
+
222
+
223
+ class FallbackHaptics:
224
+ def impact(self, style: str = "medium") -> None:
225
+ del style
226
+
227
+ def notification(self, type: str = "success") -> None: # noqa: A002 - wire name
228
+ del type
229
+
230
+ def selection(self) -> None:
231
+ pass
232
+
233
+ def vibrate(self, duration_ms: int = 400) -> None:
234
+ del duration_ms
235
+
236
+ def cancel(self) -> None:
237
+ pass
238
+
239
+
240
+ class FallbackBattery:
241
+ def get_level(self) -> float:
242
+ return -1.0
243
+
244
+ def get_state(self) -> str:
245
+ return "unknown"
246
+
247
+
248
+ class FallbackNetInfo:
249
+ def fetch(self) -> Optional[Dict[str, Any]]:
250
+ # ``None`` means "no fresh reading"; the facade keeps whatever
251
+ # snapshot was last dispatched (tests push those directly).
252
+ return None
253
+
254
+
255
+ class FallbackPermissions:
256
+ def check(self, permission: str) -> str:
257
+ del permission
258
+ return "undetermined"
259
+
260
+ def request(self, permission: str) -> str:
261
+ del permission
262
+ return "undetermined"
263
+
264
+
265
+ class FallbackNotifications:
266
+ def request_permission(self) -> bool:
267
+ return False
268
+
269
+ def schedule(self, title: str, body: str = "", delay_seconds: float = 0, identifier: str = "default") -> bool:
270
+ del title, body, delay_seconds, identifier
271
+ return False
272
+
273
+ def cancel(self, identifier: str = "default") -> None:
274
+ del identifier
275
+
276
+ def get_device_token(self) -> Optional[str]:
277
+ return None
278
+
279
+
280
+ class FallbackCamera:
281
+ def take_photo(self) -> Optional[str]:
282
+ return None
283
+
284
+ def pick_from_gallery(self) -> Optional[str]:
285
+ return None
286
+
287
+
288
+ class FallbackLocation:
289
+ def get_current(self) -> Optional[Dict[str, float]]:
290
+ return None
291
+
292
+
293
+ class FallbackBiometrics:
294
+ def is_available(self) -> bool:
295
+ return False
296
+
297
+ def authenticate(self, reason: str = "Authenticate") -> bool:
298
+ del reason
299
+ return False
300
+
301
+
302
+ _DEFAULTS: Dict[str, Callable[[], Any]] = {
303
+ "Device": FallbackDevice,
304
+ "AppState": FallbackAppState,
305
+ "Storage": FallbackStorage,
306
+ "SecureStore": FallbackSecureStore,
307
+ "Clipboard": FallbackClipboard,
308
+ "Alert": FallbackAlert,
309
+ "Share": FallbackShare,
310
+ "Linking": FallbackLinking,
311
+ "Haptics": FallbackHaptics,
312
+ "Battery": FallbackBattery,
313
+ "NetInfo": FallbackNetInfo,
314
+ "Permissions": FallbackPermissions,
315
+ "Notifications": FallbackNotifications,
316
+ "Camera": FallbackCamera,
317
+ "Location": FallbackLocation,
318
+ "Biometrics": FallbackBiometrics,
319
+ }
320
+
321
+
322
+ def default_implementation(name: str) -> Optional[Callable[[], Any]]:
323
+ """Return the factory for the built-in Python fallback implementation of ``name``."""
324
+ return _DEFAULTS.get(name)
@@ -0,0 +1,145 @@
1
+ """App-scoped file I/O.
2
+
3
+ [`FileSystem`][pythonnative.FileSystem] answers one question the
4
+ standard library can't, "where may this app write?", and then gets out
5
+ of the way: [`app_dir`][pythonnative.native_modules.file_system.FileSystem.app_dir]
6
+ comes from the native ``Device`` module, and
7
+ [`path`][pythonnative.native_modules.file_system.FileSystem.path] turns
8
+ an app-relative name into a ``pathlib.Path`` you use like any other.
9
+ The read/write helpers are thin conveniences over that path; they
10
+ raise the same ``OSError`` subclasses ``open`` and ``os`` do
11
+ (``FileNotFoundError``, ``PermissionError``, ...) rather than hiding
12
+ them behind ``None`` and ``False``.
13
+
14
+ Relative paths are resolved against ``app_dir``; absolute paths are used
15
+ as-is. Everything here is synchronous: it is local disk I/O on the
16
+ calling thread, exactly like the standard library.
17
+
18
+ Example:
19
+ ```python
20
+ from pythonnative import FileSystem
21
+
22
+ FileSystem.write_text("notes/today.txt", "Hello, file system!")
23
+ print(FileSystem.read_text("notes/today.txt"))
24
+
25
+ # Or work with the Path directly:
26
+ notes = FileSystem.path("notes")
27
+ for entry in sorted(notes.iterdir()):
28
+ print(entry.name)
29
+ ```
30
+ """
31
+
32
+ from __future__ import annotations
33
+
34
+ import os
35
+ from pathlib import Path
36
+ from typing import Any, List, Optional, Union
37
+
38
+ from .registry import native_module
39
+
40
+ PathLike = Union[str, "os.PathLike[str]"]
41
+
42
+ _app_dir_cache: Optional[str] = None
43
+
44
+
45
+ class FileSystem:
46
+ """App-scoped file I/O.
47
+
48
+ Every helper accepts an absolute path or a path relative to
49
+ [`app_dir`][pythonnative.native_modules.file_system.FileSystem.app_dir],
50
+ and raises ``OSError`` (or a subclass) when the operation fails,
51
+ like the standard library it wraps.
52
+ """
53
+
54
+ @staticmethod
55
+ def app_dir() -> str:
56
+ """Return the app's writable data directory.
57
+
58
+ On Android the result is ``Context.getFilesDir()``. On iOS it is
59
+ the app's Documents directory. Off device, without
60
+ either runtime, a ``.pythonnative_data`` directory under the
61
+ user's home folder is used. The value comes from the native
62
+ ``Device`` module's ``info()`` and is cached after the first
63
+ call.
64
+
65
+ Returns:
66
+ Absolute path to the app's data directory.
67
+ """
68
+ global _app_dir_cache
69
+ if _app_dir_cache is None:
70
+ info = native_module("Device").call("info")
71
+ path = info.get("app_dir") if isinstance(info, dict) else None
72
+ _app_dir_cache = str(path) if path else os.path.join(os.path.expanduser("~"), ".pythonnative_data")
73
+ return _app_dir_cache
74
+
75
+ @staticmethod
76
+ def path(path: PathLike = "") -> Path:
77
+ """Resolve ``path`` against ``app_dir`` and return it as a ``pathlib.Path``.
78
+
79
+ Absolute paths are returned unchanged. With no argument, returns
80
+ ``app_dir`` itself.
81
+ """
82
+ candidate = Path(path)
83
+ return candidate if candidate.is_absolute() else Path(FileSystem.app_dir()) / candidate
84
+
85
+ @staticmethod
86
+ def read_text(path: PathLike, encoding: str = "utf-8") -> str:
87
+ """Read a text file; raises ``FileNotFoundError`` and friends like ``open`` does."""
88
+ return FileSystem.path(path).read_text(encoding=encoding)
89
+
90
+ @staticmethod
91
+ def write_text(path: PathLike, content: str, encoding: str = "utf-8") -> None:
92
+ """Write a text file, creating parent directories as needed."""
93
+ target = FileSystem.path(path)
94
+ target.parent.mkdir(parents=True, exist_ok=True)
95
+ target.write_text(content, encoding=encoding)
96
+
97
+ @staticmethod
98
+ def read_bytes(path: PathLike) -> bytes:
99
+ """Read a binary file."""
100
+ return FileSystem.path(path).read_bytes()
101
+
102
+ @staticmethod
103
+ def write_bytes(path: PathLike, data: bytes) -> None:
104
+ """Write a binary file, creating parent directories as needed."""
105
+ target = FileSystem.path(path)
106
+ target.parent.mkdir(parents=True, exist_ok=True)
107
+ target.write_bytes(data)
108
+
109
+ @staticmethod
110
+ def exists(path: PathLike) -> bool:
111
+ """Return whether a file or directory exists."""
112
+ return FileSystem.path(path).exists()
113
+
114
+ @staticmethod
115
+ def delete(path: PathLike, *, missing_ok: bool = False) -> None:
116
+ """Delete a single file.
117
+
118
+ Args:
119
+ path: Absolute or ``app_dir``-relative path.
120
+ missing_ok: Ignore a missing file instead of raising
121
+ ``FileNotFoundError`` (same as ``Path.unlink``).
122
+ """
123
+ FileSystem.path(path).unlink(missing_ok=missing_ok)
124
+
125
+ @staticmethod
126
+ def list_dir(path: PathLike = "") -> List[str]:
127
+ """Return the entry names in a directory (``app_dir`` by default), sorted."""
128
+ return sorted(entry.name for entry in FileSystem.path(path).iterdir())
129
+
130
+ @staticmethod
131
+ def get_size(path: PathLike) -> int:
132
+ """Return a file's size in bytes."""
133
+ return FileSystem.path(path).stat().st_size
134
+
135
+ @staticmethod
136
+ def ensure_dir(path: PathLike) -> Path:
137
+ """Create a directory (and any missing parents) if needed; returns its ``Path``."""
138
+ target = FileSystem.path(path)
139
+ target.mkdir(parents=True, exist_ok=True)
140
+ return target
141
+
142
+ @staticmethod
143
+ def join(*parts: Any) -> str:
144
+ """Join path components with the OS separator (``os.path.join`` over ``str(part)``)."""
145
+ return os.path.join(*[str(p) for p in parts])
@@ -0,0 +1,75 @@
1
+ """Haptic feedback and raw vibration.
2
+
3
+ Two interfaces live here, both backed by the native ``Haptics`` module:
4
+
5
+ - [`Haptics`][pythonnative.Haptics]: semantic, iOS-style feedback
6
+ (impact / notification / selection) backed by
7
+ ``UIFeedbackGenerator`` on iOS and ``VibrationEffect`` patterns on
8
+ Android.
9
+ - [`Vibration`][pythonnative.Vibration]: a blunt "buzz for N
10
+ milliseconds" interface for cases where you want an explicit
11
+ duration.
12
+
13
+ Every method is synchronous (the OS queues the effect and returns).
14
+ Missing hardware is not an error: on a device without a Taptic Engine
15
+ or vibrator, and off device the native module simply does nothing.
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ from typing import Any
21
+
22
+ from .registry import native_module
23
+
24
+ ImpactStyle = str # "light" | "medium" | "heavy" | "soft" | "rigid"
25
+ NotificationType = str # "success" | "warning" | "error"
26
+
27
+
28
+ def _call(method: str, **args: Any) -> None:
29
+ native_module("Haptics").call(method, **args)
30
+
31
+
32
+ class Haptics:
33
+ """Semantic haptic feedback (synchronous).
34
+
35
+ Raises:
36
+ NativeModuleError: If the native module fails.
37
+ """
38
+
39
+ @staticmethod
40
+ def impact(style: ImpactStyle = "medium") -> None:
41
+ """Play a physical "impact" tap of the given ``style``."""
42
+ _call("impact", style=style)
43
+
44
+ @staticmethod
45
+ def notification(type_: NotificationType = "success") -> None:
46
+ """Play a success / warning / error notification pattern."""
47
+ _call("notification", type=type_)
48
+
49
+ @staticmethod
50
+ def selection() -> None:
51
+ """Play the light "selection changed" tick."""
52
+ _call("selection")
53
+
54
+
55
+ class Vibration:
56
+ """Raw vibration control (synchronous).
57
+
58
+ Raises:
59
+ NativeModuleError: If the native module fails.
60
+ """
61
+
62
+ @staticmethod
63
+ def vibrate(duration_ms: int = 400) -> None:
64
+ """Vibrate for ``duration_ms`` milliseconds.
65
+
66
+ iOS has no arbitrary-duration API; the native module
67
+ approximates short buzzes with a heavy impact and longer ones
68
+ with the legacy system vibration sound.
69
+ """
70
+ _call("vibrate", duration_ms=int(duration_ms))
71
+
72
+ @staticmethod
73
+ def cancel() -> None:
74
+ """Cancel an in-progress vibration (Android only)."""
75
+ _call("cancel")