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,123 @@
1
+ """Open URLs, deep links, and the system settings page.
2
+
3
+ [`Linking`][pythonnative.Linking] wraps ``UIApplication.openURL`` /
4
+ ``Intent(ACTION_VIEW)`` (in the native ``Linking`` module) so a Python
5
+ app can hand a URL (``https:``, ``mailto:``, ``tel:``, a custom
6
+ scheme, ...) to the OS.
7
+
8
+ Outbound methods hand the URL to the OS and return at once, so they
9
+ are synchronous; the ``bool`` says whether the platform accepted the
10
+ request. Off device they return ``False``.
11
+
12
+ Inbound deep links flow the other way: declare your schemes in
13
+ ``pythonnative.toml`` (``app.url_schemes``) and the native module
14
+ pushes a ``url`` event for every URL that opens the app, which lands in
15
+ [`dispatch_url`][pythonnative.native_modules.linking.dispatch_url]. The
16
+ URL that cold-started the app is kept and returned by
17
+ ``get_initial_url``; later URLs reach subscribers added with
18
+ ``add_listener``.
19
+
20
+ Example:
21
+ ```python
22
+ import pythonnative as pn
23
+
24
+ if url := pn.Linking.get_initial_url():
25
+ navigate_to(url)
26
+
27
+ unsubscribe = pn.Linking.add_listener(navigate_to)
28
+ ```
29
+ """
30
+
31
+ from __future__ import annotations
32
+
33
+ from typing import Any, Callable, List, Optional
34
+
35
+ from .registry import native_module, on_event
36
+
37
+ _initial_url: Optional[str] = None
38
+ _url_listeners: List[Callable[[str], None]] = []
39
+
40
+
41
+ def _call_bool(method: str, **args: Any) -> bool:
42
+ return bool(native_module("Linking").call(method, **args))
43
+
44
+
45
+ class Linking:
46
+ """System URL / deep-link interface (synchronous).
47
+
48
+ Raises:
49
+ NativeModuleError: If the native module fails.
50
+ """
51
+
52
+ @staticmethod
53
+ def open_url(url: str) -> bool:
54
+ """Hand ``url`` to the OS. Returns ``True`` if it was accepted."""
55
+ return _call_bool("open_url", url=url)
56
+
57
+ @staticmethod
58
+ def can_open_url(url: str) -> bool:
59
+ """Return ``True`` when some installed app can handle ``url``."""
60
+ return _call_bool("can_open_url", url=url)
61
+
62
+ @staticmethod
63
+ def open_settings() -> bool:
64
+ """Open this app's entry in the system Settings app."""
65
+ return _call_bool("open_settings")
66
+
67
+ @staticmethod
68
+ def get_initial_url() -> Optional[str]:
69
+ """Return the URL that launched the app, if any."""
70
+ return _initial_url
71
+
72
+ @staticmethod
73
+ def add_listener(callback: Callable[[str], None]) -> Callable[[], None]:
74
+ """Subscribe to deep links that arrive while the app is running.
75
+
76
+ Args:
77
+ callback: Called with the full URL string for every inbound
78
+ deep link (including the initial one, which is
79
+ dispatched right after startup).
80
+
81
+ Returns:
82
+ A zero-arg function that unsubscribes when called.
83
+ """
84
+ _url_listeners.append(callback)
85
+
86
+ def _unsubscribe() -> None:
87
+ try:
88
+ _url_listeners.remove(callback)
89
+ except ValueError:
90
+ pass
91
+
92
+ return _unsubscribe
93
+
94
+
95
+ def set_initial_url(url: Optional[str]) -> None:
96
+ """Record the launch URL (or clear it with ``None``)."""
97
+ global _initial_url
98
+ _initial_url = url
99
+
100
+
101
+ def dispatch_url(url: str) -> None:
102
+ """Deliver an inbound deep link.
103
+
104
+ The first URL ever dispatched is also recorded as the initial URL
105
+ (a cold start from a deep link reaches Python only after the
106
+ interpreter boots, so native can't report it earlier than this).
107
+
108
+ Args:
109
+ url: The full URL string that opened the app.
110
+ """
111
+ global _initial_url
112
+ if _initial_url is None:
113
+ _initial_url = url
114
+ for listener in list(_url_listeners):
115
+ try:
116
+ listener(url)
117
+ except Exception as exc:
118
+ from .. import diagnostics
119
+
120
+ diagnostics.warn(f"Linking listener raised while handling {url!r}: {exc!r}")
121
+
122
+
123
+ on_event("Linking", "url", lambda payload: dispatch_url(str(payload)))
@@ -0,0 +1,75 @@
1
+ """Cross-platform location / GPS access.
2
+
3
+ [`Location.get_current`][pythonnative.native_modules.location.Location.get_current]
4
+ is a coroutine that resolves to a ``(latitude, longitude)`` tuple, or
5
+ ``None`` if no fix is available (the user denied permission, location
6
+ services are off, or the request timed out).
7
+ The native ``Location`` module owns the ``CLLocationManager`` /
8
+ ``LocationManager`` session and resolves the call with
9
+ ``{"latitude", "longitude", "accuracy", "altitude", "timestamp"}``.
10
+
11
+ Permission prompts are triggered the first time a location-using API
12
+ is called; ensure the appropriate manifest entries
13
+ (``android.permission.ACCESS_FINE_LOCATION``) and Info.plist keys
14
+ (``NSLocationWhenInUseUsageDescription``) are present.
15
+
16
+ Example:
17
+ ```python
18
+ import pythonnative as pn
19
+
20
+ async def show_position():
21
+ coords = await pn.Location.get_current()
22
+ if coords is None:
23
+ return
24
+ lat, lon = coords
25
+ print(f"You are at {lat:.5f}, {lon:.5f}")
26
+ ```
27
+ """
28
+
29
+ from __future__ import annotations
30
+
31
+ from typing import Any, Dict, Optional, Tuple
32
+
33
+ from .registry import NativeModuleError, native_module
34
+
35
+ Coords = Tuple[float, float]
36
+
37
+
38
+ class Location:
39
+ """GPS / location-services interface."""
40
+
41
+ @staticmethod
42
+ async def get_current(**options: Any) -> Optional[Coords]:
43
+ """Request the device's current location.
44
+
45
+ Args:
46
+ **options: Forwarded to the native module (``accuracy``,
47
+ ``timeout``). Unknown keys are ignored.
48
+
49
+ Returns:
50
+ ``(latitude, longitude)`` if a fix was obtained, otherwise
51
+ ``None``.
52
+
53
+ Raises:
54
+ NativeModuleError: If the native module fails.
55
+ """
56
+ fix = await Location.get_current_fix(**options)
57
+ if fix is None:
58
+ return None
59
+ return (fix["latitude"], fix["longitude"])
60
+
61
+ @staticmethod
62
+ async def get_current_fix(**options: Any) -> Optional[Dict[str, float]]:
63
+ """Like ``get_current`` but returns the full fix dict.
64
+
65
+ Keys: ``latitude``, ``longitude``, and when the platform reports
66
+ them ``accuracy`` (meters), ``altitude`` (meters), ``speed``
67
+ (m/s), ``heading`` (degrees), ``timestamp`` (Unix seconds).
68
+ """
69
+ result = await native_module("Location").call_async("get_current", **options)
70
+ if not isinstance(result, dict):
71
+ return None
72
+ fix: Dict[str, float] = {k: float(v) for k, v in result.items() if v is not None}
73
+ if "latitude" not in fix or "longitude" not in fix:
74
+ raise NativeModuleError("Location", "get_current", f"fix is missing coordinates: {sorted(result)}")
75
+ return fix
@@ -0,0 +1,112 @@
1
+ """Network connectivity state.
2
+
3
+ [`NetInfo`][pythonnative.NetInfo] reports whether the device is online
4
+ and over what kind of connection. ``fetch`` returns a snapshot dict;
5
+ ``add_listener`` (and the [`use_net_info`][pythonnative.use_net_info]
6
+ hook) deliver live updates pushed by the native ``NetInfo`` module
7
+ (``NWPathMonitor`` on iOS, ``ConnectivityManager.NetworkCallback`` on
8
+ Android) as ``change`` events. Off device, tests push snapshots through
9
+ [`dispatch_net_info`][pythonnative.native_modules.net_info.dispatch_net_info].
10
+
11
+ A snapshot looks like::
12
+
13
+ {"is_connected": True, "type": "wifi", "is_internet_reachable": True}
14
+
15
+ ``type`` is one of ``"wifi"``, ``"cellular"``, ``"ethernet"``,
16
+ ``"none"``, or ``"unknown"``.
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ from typing import Any, Callable, Dict, List
22
+
23
+ from .. import diagnostics
24
+ from ..hooks import use_effect, use_state
25
+ from .registry import native_module, on_event
26
+
27
+ NetInfoState = Dict[str, object]
28
+
29
+ _listeners: List[Callable[[NetInfoState], None]] = []
30
+ _last_state: NetInfoState = {
31
+ "is_connected": True,
32
+ "type": "unknown",
33
+ "is_internet_reachable": True,
34
+ }
35
+
36
+
37
+ class NetInfo:
38
+ """Network connectivity interface."""
39
+
40
+ @staticmethod
41
+ def fetch() -> NetInfoState:
42
+ """Return a fresh snapshot of connectivity state."""
43
+ global _last_state
44
+ snapshot = native_module("NetInfo").call("fetch")
45
+ if isinstance(snapshot, dict):
46
+ _last_state = _normalize(snapshot)
47
+ return dict(_last_state)
48
+
49
+ @staticmethod
50
+ def add_listener(callback: Callable[[NetInfoState], None]) -> Callable[[], None]:
51
+ """Subscribe to connectivity changes; returns an unsubscribe fn."""
52
+ _listeners.append(callback)
53
+
54
+ def _unsubscribe() -> None:
55
+ try:
56
+ _listeners.remove(callback)
57
+ except ValueError:
58
+ pass
59
+
60
+ return _unsubscribe
61
+
62
+
63
+ def _normalize(snapshot: Dict[str, Any]) -> NetInfoState:
64
+ return {
65
+ "is_connected": bool(snapshot.get("is_connected", False)),
66
+ "type": str(snapshot.get("type", "unknown")),
67
+ "is_internet_reachable": bool(snapshot.get("is_internet_reachable", False)),
68
+ }
69
+
70
+
71
+ def dispatch_net_info(state: NetInfoState) -> None:
72
+ """Push a new connectivity snapshot and notify listeners."""
73
+ global _last_state
74
+ _last_state = dict(state)
75
+ for listener in list(_listeners):
76
+ try:
77
+ listener(dict(state))
78
+ except Exception:
79
+ diagnostics.swallowed("net_info.dispatch_net_info")
80
+
81
+
82
+ def _on_native_change(payload: Any) -> None:
83
+ if not isinstance(payload, dict):
84
+ return
85
+ state = _normalize(payload)
86
+ if state == _last_state:
87
+ return
88
+ dispatch_net_info(state)
89
+
90
+
91
+ on_event("NetInfo", "change", _on_native_change)
92
+
93
+
94
+ def use_net_info() -> NetInfoState:
95
+ """Subscribe a component to [`NetInfo`][pythonnative.NetInfo].
96
+
97
+ Returns:
98
+ The latest connectivity snapshot dict; the component
99
+ re-renders whenever connectivity changes.
100
+ """
101
+ state, set_state = use_state(NetInfo.fetch)
102
+
103
+ def _subscribe() -> Callable[[], None]:
104
+ set_state(NetInfo.fetch())
105
+
106
+ def on_change(snapshot: NetInfoState) -> None:
107
+ set_state(snapshot)
108
+
109
+ return NetInfo.add_listener(on_change)
110
+
111
+ use_effect(_subscribe, [])
112
+ return state
@@ -0,0 +1,129 @@
1
+ """Local notifications and remote push registration.
2
+
3
+ Coroutines for requesting permission and scheduling / cancelling local
4
+ notifications, backed by the native ``Notifications`` module
5
+ (``UNUserNotificationCenter`` on iOS, ``NotificationManager`` on
6
+ Android).
7
+
8
+ On iOS you must ``await Notifications.request_permission()`` before
9
+ scheduling. On Android 13+ the ``POST_NOTIFICATIONS`` runtime
10
+ permission is requested automatically the first time you schedule a
11
+ notification (the template manifest declares it); earlier Android
12
+ versions don't prompt at all.
13
+
14
+ For remote (server-sent) pushes, enable the ``remote_notifications``
15
+ capability in ``pythonnative.toml`` and call
16
+ ``Notifications.get_device_token()`` to register with APNs and receive
17
+ the device token your server needs. Android remote push requires
18
+ Firebase Cloud Messaging, which needs a per-app ``google-services.json``
19
+ and is not wired up by the built-in module; ``get_device_token`` returns
20
+ ``None`` there.
21
+
22
+ Example:
23
+ ```python
24
+ import pythonnative as pn
25
+
26
+ async def setup_reminders():
27
+ if not await pn.Notifications.request_permission():
28
+ return
29
+ await pn.Notifications.schedule(
30
+ title="Reminder",
31
+ body="Time for a walk!",
32
+ delay_seconds=60,
33
+ identifier="walk",
34
+ )
35
+ ```
36
+ """
37
+
38
+ from __future__ import annotations
39
+
40
+ from typing import Any, Optional
41
+
42
+ from .registry import native_module
43
+
44
+
45
+ class Notifications:
46
+ """Local notification interface."""
47
+
48
+ @staticmethod
49
+ async def request_permission() -> bool:
50
+ """Request notification permission from the user.
51
+
52
+ On Android 12 and below the manifest declaration is sufficient
53
+ and this returns ``True`` without prompting. On Android 13+
54
+ (API 33) the ``POST_NOTIFICATIONS`` runtime permission prompt
55
+ is shown if the user hasn't decided yet.
56
+
57
+ Returns:
58
+ ``True`` if granted (or no prompt is needed), ``False`` if
59
+ the user declined (always ``False`` off device).
60
+
61
+ Raises:
62
+ NativeModuleError: If the native module fails.
63
+ """
64
+ return bool(await native_module("Notifications").call_async("request_permission"))
65
+
66
+ @staticmethod
67
+ async def schedule(
68
+ title: str,
69
+ body: str = "",
70
+ *,
71
+ delay_seconds: float = 0,
72
+ identifier: str = "default",
73
+ **options: Any,
74
+ ) -> bool:
75
+ """Schedule a local notification.
76
+
77
+ Args:
78
+ title: Notification title.
79
+ body: Notification body text.
80
+ delay_seconds: Seconds from now until delivery. Use ``0``
81
+ for an effectively immediate notification.
82
+ identifier: Stable ID used by
83
+ [`cancel`][pythonnative.native_modules.notifications.Notifications.cancel]
84
+ to target this notification.
85
+ **options: Forwarded to the native module (``sound``,
86
+ ``badge``, ...). Unknown keys are ignored.
87
+
88
+ Returns:
89
+ ``True`` once scheduled, ``False`` if the user has denied
90
+ notification permission (so nothing was scheduled).
91
+
92
+ Raises:
93
+ NativeModuleError: If the native module fails.
94
+ """
95
+ result = await native_module("Notifications").call_async(
96
+ "schedule",
97
+ title=title,
98
+ body=body,
99
+ delay_seconds=float(delay_seconds),
100
+ identifier=identifier,
101
+ **options,
102
+ )
103
+ return bool(result)
104
+
105
+ @staticmethod
106
+ async def cancel(identifier: str = "default") -> None:
107
+ """Cancel a pending notification by its identifier (a no-op when none is pending)."""
108
+ await native_module("Notifications").call_async("cancel", identifier=identifier)
109
+
110
+ @staticmethod
111
+ async def get_device_token() -> Optional[str]:
112
+ """Register for remote notifications and return the device token.
113
+
114
+ On iOS this calls ``registerForRemoteNotifications`` and waits
115
+ for the APNs callback; the token is a lowercase hex string your
116
+ server passes to APNs. Requires the ``remote_notifications``
117
+ capability (which adds the ``aps-environment`` entitlement) and
118
+ a real device (the simulator has no APNs connection).
119
+
120
+ Returns:
121
+ The APNs token, or ``None`` on platforms without built-in
122
+ remote push support (Android and off device).
123
+
124
+ Raises:
125
+ NativeModuleError: If APNs registration fails; ``code`` is
126
+ ``"apns"`` and the message carries the system's error.
127
+ """
128
+ token = await native_module("Notifications").call_async("get_device_token")
129
+ return str(token) if token else None
@@ -0,0 +1,108 @@
1
+ """Runtime permission checks and requests.
2
+
3
+ [`Permissions`][pythonnative.Permissions] normalizes the very different
4
+ iOS and Android permission models behind two calls, both served by the
5
+ native ``Permissions`` module:
6
+
7
+ - ``check(permission)``: synchronous, returns a status without
8
+ prompting.
9
+ - ``request(permission)``: a coroutine that shows the system prompt
10
+ (if needed) and resolves to the resulting status.
11
+
12
+ Statuses are ``"granted"``, ``"denied"``, ``"blocked"`` (denied with
13
+ "don't ask again" / Settings required), or ``"undetermined"``.
14
+
15
+ Permission names are the same words you declare in the
16
+ ``[permissions]`` table of ``pythonnative.toml``, so the string that
17
+ puts ``NSCameraUsageDescription`` in your Info.plist is the string you
18
+ pass here: ``"camera"``, ``"microphone"``, ``"photo_library"``,
19
+ ``"location_when_in_use"``, ``"contacts"``, ``"notifications"``. The
20
+ full list is [`RUNTIME_PERMISSIONS`][pythonnative.native_modules.permissions.RUNTIME_PERMISSIONS];
21
+ capabilities that have no runtime prompt (``vibration``,
22
+ ``background_fetch``, ...) are declared in the config only. A name
23
+ outside the list raises ``ValueError`` before anything reaches native.
24
+
25
+ Example:
26
+ ```python
27
+ import pythonnative as pn
28
+
29
+ async def scan():
30
+ if await pn.Permissions.request("camera") != "granted":
31
+ return
32
+ await pn.Camera.take_photo()
33
+ ```
34
+ """
35
+
36
+ from __future__ import annotations
37
+
38
+ from typing import Literal
39
+
40
+ from .registry import native_module
41
+
42
+ PermissionStatus = Literal["granted", "denied", "blocked", "undetermined"]
43
+ """Outcome of a check or request."""
44
+
45
+ PermissionName = Literal[
46
+ "camera",
47
+ "microphone",
48
+ "photo_library",
49
+ "location_when_in_use",
50
+ "contacts",
51
+ "notifications",
52
+ ]
53
+ """A capability that has a runtime prompt; the same names as ``[permissions]`` in ``pythonnative.toml``."""
54
+
55
+ GRANTED: PermissionStatus = "granted"
56
+ DENIED: PermissionStatus = "denied"
57
+ BLOCKED: PermissionStatus = "blocked"
58
+ UNDETERMINED: PermissionStatus = "undetermined"
59
+
60
+ _STATUSES = (GRANTED, DENIED, BLOCKED, UNDETERMINED)
61
+
62
+ RUNTIME_PERMISSIONS = (
63
+ "camera",
64
+ "microphone",
65
+ "photo_library",
66
+ "location_when_in_use",
67
+ "contacts",
68
+ "notifications",
69
+ )
70
+ """Every permission name ``check`` / ``request`` accept, in the ``[permissions]`` vocabulary."""
71
+
72
+
73
+ def _coerce(value: object) -> PermissionStatus:
74
+ status = str(value) if value is not None else UNDETERMINED
75
+ return status if status in _STATUSES else UNDETERMINED
76
+
77
+
78
+ def _validate(permission: str) -> str:
79
+ if permission not in RUNTIME_PERMISSIONS:
80
+ raise ValueError(
81
+ f"Unknown permission {permission!r}. Use one of {', '.join(RUNTIME_PERMISSIONS)} "
82
+ "(the same names as [permissions] in pythonnative.toml)."
83
+ )
84
+ return permission
85
+
86
+
87
+ class Permissions:
88
+ """Runtime permission interface.
89
+
90
+ Raises:
91
+ ValueError: For a permission name outside
92
+ [`RUNTIME_PERMISSIONS`][pythonnative.native_modules.permissions.RUNTIME_PERMISSIONS].
93
+ NativeModuleError: If the native module fails.
94
+ """
95
+
96
+ @staticmethod
97
+ def check(permission: PermissionName) -> PermissionStatus:
98
+ """Return the current status of ``permission`` without prompting."""
99
+ return _coerce(native_module("Permissions").call("check", permission=_validate(permission)))
100
+
101
+ @staticmethod
102
+ async def request(permission: PermissionName) -> PermissionStatus:
103
+ """Prompt for ``permission`` (if needed) and return the result.
104
+
105
+ Off device (``pn preview``, tests) the answer is always
106
+ ``"undetermined"``: there is no prompt to show.
107
+ """
108
+ return _coerce(await native_module("Permissions").call_async("request", permission=_validate(permission)))