pythonnative 0.36.0__tar.gz → 0.38.0__tar.gz
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.
- {pythonnative-0.36.0/src/pythonnative.egg-info → pythonnative-0.38.0}/PKG-INFO +10 -12
- {pythonnative-0.36.0 → pythonnative-0.38.0}/README.md +6 -3
- {pythonnative-0.36.0 → pythonnative-0.38.0}/pyproject.toml +14 -17
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/__init__.py +14 -4
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/_ios_log.py +1 -1
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/alerts.py +24 -86
- pythonnative-0.38.0/src/pythonnative/bootstrap.py +90 -0
- pythonnative-0.38.0/src/pythonnative/bridge/__init__.py +306 -0
- pythonnative-0.38.0/src/pythonnative/bridge/android.py +78 -0
- pythonnative-0.38.0/src/pythonnative/bridge/codec.py +164 -0
- pythonnative-0.38.0/src/pythonnative/bridge/fake.py +236 -0
- pythonnative-0.38.0/src/pythonnative/bridge/ios.py +138 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/cli/pn.py +96 -10
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/components/_base.py +31 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/components/controls.py +19 -16
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/components/layout.py +70 -11
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/components/lists.py +6 -6
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/gestures.py +40 -16
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/hooks.py +41 -26
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/hosts/__init__.py +13 -36
- pythonnative-0.38.0/src/pythonnative/hosts/native.py +348 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/images.py +6 -5
- pythonnative-0.38.0/src/pythonnative/native_modules/__init__.py +122 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/native_modules/app_state.py +10 -6
- pythonnative-0.38.0/src/pythonnative/native_modules/battery.py +75 -0
- pythonnative-0.38.0/src/pythonnative/native_modules/biometrics.py +42 -0
- pythonnative-0.38.0/src/pythonnative/native_modules/camera.py +65 -0
- pythonnative-0.38.0/src/pythonnative/native_modules/clipboard.py +46 -0
- pythonnative-0.38.0/src/pythonnative/native_modules/desktop.py +322 -0
- pythonnative-0.38.0/src/pythonnative/native_modules/file_system.py +145 -0
- pythonnative-0.38.0/src/pythonnative/native_modules/haptics.py +75 -0
- pythonnative-0.38.0/src/pythonnative/native_modules/linking.py +123 -0
- pythonnative-0.38.0/src/pythonnative/native_modules/location.py +75 -0
- pythonnative-0.38.0/src/pythonnative/native_modules/net_info.py +112 -0
- pythonnative-0.38.0/src/pythonnative/native_modules/notifications.py +129 -0
- pythonnative-0.38.0/src/pythonnative/native_modules/permissions.py +108 -0
- pythonnative-0.38.0/src/pythonnative/native_modules/registry.py +513 -0
- pythonnative-0.38.0/src/pythonnative/native_modules/secure_store.py +52 -0
- pythonnative-0.38.0/src/pythonnative/native_modules/share.py +51 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/native_views/__init__.py +67 -86
- pythonnative-0.38.0/src/pythonnative/native_views/bridge_backend.py +264 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/navigation/__init__.py +2 -1
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/navigation/hooks.py +46 -7
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/navigation/state.py +30 -9
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/platform.py +19 -15
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/platform_metrics.py +3 -3
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/project/android.py +23 -3
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/project/builder.py +99 -48
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/project/config.py +96 -26
- pythonnative-0.38.0/src/pythonnative/project/deps.py +703 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/project/doctor.py +53 -4
- pythonnative-0.38.0/src/pythonnative/project/plugins.py +366 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/project/runtime_assets.py +13 -14
- pythonnative-0.38.0/src/pythonnative/py.typed +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/runtime.py +35 -203
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/sdk/__init__.py +48 -33
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/sdk/_components.py +57 -76
- pythonnative-0.38.0/src/pythonnative/storage.py +184 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/style.py +94 -44
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/build.gradle +11 -11
- pythonnative-0.38.0/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/MainActivity.kt +127 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/ScreenFragment.kt +16 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/build.gradle +10 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/gradle/wrapper/gradle-wrapper.properties +1 -1
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/build.gradle +48 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/AndroidManifest.xml +11 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/PNBridge.kt +214 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/PythonHost.kt +20 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/animation/AnimationSpecs.kt +141 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/animation/PNAnimator.kt +249 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/bridge/JsonUtil.kt +175 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/bridge/MainThread.kt +32 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/bridge/PNLog.kt +33 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/bridge/PNRegistry.kt +82 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/bridge/PNTransaction.kt +80 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/bridge/TransactionApplier.kt +115 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/bridge/ViewRegistry.kt +74 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/components/BuiltinComponents.kt +35 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/components/ButtonManager.kt +33 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/components/ComponentManager.kt +213 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/components/ContainerManagers.kt +69 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/components/ControlManagers.kt +186 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/components/DatePickerManager.kt +123 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/components/ImageLoader.kt +141 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/components/ImageManager.kt +156 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/components/ModalManager.kt +134 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/components/PNColor.kt +201 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/components/PickerManager.kt +87 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/components/PortalManager.kt +55 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/components/PressableManager.kt +122 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/components/ScrollViewManager.kt +214 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/components/SegmentedControlManager.kt +113 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/components/StatusBarManager.kt +52 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/components/TabBarManager.kt +131 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/components/TextInputManager.kt +245 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/components/TextManager.kt +233 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/components/ViewStyler.kt +355 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/components/VirtualListManager.kt +179 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/components/WebViewManager.kt +149 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/gestures/GestureArbiter.kt +233 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/gestures/GestureCoordinator.kt +127 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/gestures/GestureRecognizers.kt +527 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/modules/BuiltinModules.kt +73 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/modules/DeviceModules.kt +316 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/modules/HostModule.kt +97 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/modules/MediaModules.kt +200 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/modules/NativeModule.kt +135 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/modules/NotificationsModule.kt +100 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/modules/PermissionsModule.kt +99 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/modules/StorageModules.kt +89 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/modules/SystemModules.kt +178 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/plugins/GeneratedPlugins.kt +16 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/screens/Navigator.kt +116 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/screens/PNScreenFragment.kt +223 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/screens/ScreenRegistry.kt +80 -0
- {pythonnative-0.36.0/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template → pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/views}/PNAccessibilityDelegate.kt +5 -4
- {pythonnative-0.36.0/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template → pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/views}/PNBorderDrawable.kt +12 -3
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/views/PNEditText.kt +18 -0
- {pythonnative-0.36.0/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template → pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/views}/PNFrameLayout.kt +9 -10
- {pythonnative-0.36.0/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template → pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/main/java/com/pythonnative/runtime/views}/PNVirtualListView.java +9 -12
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/test/java/com/pythonnative/runtime/AnimationSpecsTest.kt +75 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/test/java/com/pythonnative/runtime/GestureArbiterTest.kt +197 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/test/java/com/pythonnative/runtime/PNColorTest.kt +47 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/test/java/com/pythonnative/runtime/PNTransactionTest.kt +78 -0
- pythonnative-0.38.0/src/pythonnative/templates/android_template/pythonnative/src/test/java/com/pythonnative/runtime/PromiseTest.kt +75 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/settings.gradle +1 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Package.swift +21 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Animation/PNAnimator.swift +301 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Bridge/PNBridge.swift +191 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Bridge/PNRegistry.swift +140 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Bridge/PNTransaction.swift +165 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Bridge/PNViewRegistry.swift +53 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Components/PNButtonManagers.swift +206 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Components/PNColor.swift +173 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Components/PNComponentManager.swift +183 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Components/PNContainerView.swift +56 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Components/PNControlManagers.swift +281 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Components/PNImageManager.swift +221 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Components/PNOverlayManagers.swift +243 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Components/PNPressableManager.swift +114 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Components/PNScrollViewManager.swift +197 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Components/PNTabBarManager.swift +106 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Components/PNTextInputManager.swift +289 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Components/PNTextManager.swift +230 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Components/PNTransform.swift +82 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Components/PNViewManager.swift +86 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Components/PNViewState.swift +87 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Components/PNViewStyler.swift +340 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Components/PNVirtualListManager.swift +257 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Components/PNWebViewManager.swift +124 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Gestures/PNGestureCoordinator.swift +260 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Modules/AlertModule.swift +92 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Modules/HostModule.swift +158 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Modules/LifecycleModules.swift +174 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Modules/MediaModules.swift +177 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Modules/PNNativeModule.swift +125 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Modules/PermissionModules.swift +266 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Modules/SystemModules.swift +251 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Plugins/PNPluginRegistration.swift +8 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Screens/PNScreenRegistry.swift +46 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Screens/PNViewController.swift +251 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Support/PNCompat.swift +46 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Support/PNJSON.swift +173 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Support/PNLog.swift +47 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Sources/PythonNativeKit/Support/PNWindow.swift +51 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Tests/PythonNativeKitTests/PNColorTests.swift +50 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Tests/PythonNativeKitTests/PNGestureTests.swift +101 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Tests/PythonNativeKitTests/PNManagerTests.swift +124 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Tests/PythonNativeKitTests/PNModuleTests.swift +98 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/PythonNativeKit/Tests/PythonNativeKitTests/PNTransactionTests.swift +91 -0
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/ios_template/AppDelegate.swift +51 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/ios_template/ios_template/Info.plist +4 -4
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/ios_template/ios_template/PythonRuntime.swift +41 -48
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/ios_template/ios_template/SceneDelegate.swift +11 -16
- pythonnative-0.38.0/src/pythonnative/templates/ios_template/ios_template/ViewController.swift +29 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/ios_template/ios_template.xcodeproj/project.pbxproj +82 -10
- pythonnative-0.38.0/src/pythonnative/utils.py +137 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/virtual_rows.py +13 -23
- {pythonnative-0.36.0 → pythonnative-0.38.0/src/pythonnative.egg-info}/PKG-INFO +10 -12
- pythonnative-0.38.0/src/pythonnative.egg-info/SOURCES.txt +310 -0
- pythonnative-0.38.0/src/pythonnative.egg-info/requires.txt +4 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_animated.py +2 -2
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_animated_graph.py +5 -5
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_appearance.py +21 -4
- pythonnative-0.38.0/tests/test_bridge.py +558 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_cli.py +153 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_gestures.py +21 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_hosts.py +3 -74
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_metric_hooks.py +11 -9
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_native_lists.py +6 -6
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_native_modules.py +143 -25
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_navigation.py +42 -1
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_new_components.py +28 -15
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_sdk.py +56 -74
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_storage.py +5 -9
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_style.py +17 -2
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_utils.py +6 -3
- pythonnative-0.36.0/src/pythonnative/hosts/android.py +0 -269
- pythonnative-0.36.0/src/pythonnative/hosts/ios.py +0 -404
- pythonnative-0.36.0/src/pythonnative/native_modules/__init__.py +0 -102
- pythonnative-0.36.0/src/pythonnative/native_modules/battery.py +0 -140
- pythonnative-0.36.0/src/pythonnative/native_modules/biometrics.py +0 -157
- pythonnative-0.36.0/src/pythonnative/native_modules/camera.py +0 -337
- pythonnative-0.36.0/src/pythonnative/native_modules/clipboard.py +0 -143
- pythonnative-0.36.0/src/pythonnative/native_modules/file_system.py +0 -242
- pythonnative-0.36.0/src/pythonnative/native_modules/haptics.py +0 -181
- pythonnative-0.36.0/src/pythonnative/native_modules/linking.py +0 -235
- pythonnative-0.36.0/src/pythonnative/native_modules/location.py +0 -229
- pythonnative-0.36.0/src/pythonnative/native_modules/net_info.py +0 -225
- pythonnative-0.36.0/src/pythonnative/native_modules/notifications.py +0 -357
- pythonnative-0.36.0/src/pythonnative/native_modules/permissions.py +0 -224
- pythonnative-0.36.0/src/pythonnative/native_modules/secure_store.py +0 -193
- pythonnative-0.36.0/src/pythonnative/native_modules/share.py +0 -156
- pythonnative-0.36.0/src/pythonnative/native_views/android.py +0 -3702
- pythonnative-0.36.0/src/pythonnative/native_views/ios.py +0 -5253
- pythonnative-0.36.0/src/pythonnative/storage.py +0 -409
- pythonnative-0.36.0/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/MainActivity.kt +0 -259
- pythonnative-0.36.0/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/Navigator.kt +0 -43
- pythonnative-0.36.0/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/ScreenFragment.kt +0 -154
- pythonnative-0.36.0/src/pythonnative/templates/android_template/build.gradle +0 -7
- pythonnative-0.36.0/src/pythonnative/templates/ios_template/ios_template/AppDelegate.swift +0 -93
- pythonnative-0.36.0/src/pythonnative/templates/ios_template/ios_template/ViewController.swift +0 -159
- pythonnative-0.36.0/src/pythonnative/utils.py +0 -220
- pythonnative-0.36.0/src/pythonnative.egg-info/SOURCES.txt +0 -200
- pythonnative-0.36.0/src/pythonnative.egg-info/requires.txt +0 -11
- {pythonnative-0.36.0 → pythonnative-0.38.0}/LICENSE +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/setup.cfg +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/animated.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/appearance.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/cli/__init__.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/component.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/components/__init__.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/components/media.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/components/overlays.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/components/pressable.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/components/structural.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/components/text.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/diagnostics.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/element.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/events.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/hosts/base.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/hosts/desktop.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/hot_reload.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/layout.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/mutations.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/native_views/base.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/native_views/desktop.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/navigation/container.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/navigation/handle.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/navigation/host.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/navigation/linking.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/navigation/navigators.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/navigation/screen.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/net.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/preview.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/project/__init__.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/project/devices.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/project/icons.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/project/ios.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/project/permissions.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/reconciler/__init__.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/reconciler/boundaries.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/reconciler/children.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/reconciler/core.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/reconciler/layout_pass.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/reconciler/vnode.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/scheduler.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/suspense.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/proguard-rules.pro +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/src/androidTest/java/com/pythonnative/android_template/ExampleInstrumentedTest.kt +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/src/main/AndroidManifest.xml +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/src/main/res/drawable/ic_launcher_background.xml +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/src/main/res/layout/activity_main.xml +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-hdpi/ic_launcher.webp +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-mdpi/ic_launcher.webp +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xhdpi/ic_launcher.webp +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/src/main/res/navigation/nav_graph.xml +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/src/main/res/values/colors.xml +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/src/main/res/values/strings.xml +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/src/main/res/values/themes.xml +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/src/main/res/values-night/themes.xml +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/src/main/res/xml/backup_rules.xml +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/src/main/res/xml/data_extraction_rules.xml +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/app/src/test/java/com/pythonnative/android_template/ExampleUnitTest.kt +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/gradle/wrapper/gradle-wrapper.jar +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/gradle.properties +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/gradlew +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/android_template/gradlew.bat +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/ios_template/ios_template/Assets.xcassets/AccentColor.colorset/Contents.json +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/ios_template/ios_template/Assets.xcassets/AppIcon.appiconset/Contents.json +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/ios_template/ios_template/Assets.xcassets/Contents.json +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/ios_template/ios_template/Base.lproj/LaunchScreen.storyboard +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/ios_template/ios_template/BridgingHeader.h +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/ios_template/ios_template.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/ios_template/ios_templateTests/ios_templateTests.swift +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/ios_template/ios_templateUITests/ios_templateUITests.swift +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/templates/ios_template/ios_templateUITests/ios_templateUITestsLaunchTests.swift +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/testing/__init__.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/testing/backend.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative/testing/harness.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative.egg-info/dependency_links.txt +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative.egg-info/entry_points.txt +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/src/pythonnative.egg-info/top_level.txt +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_alert.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_async_hooks.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_components.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_core_semantics.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_desktop_backend.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_element.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_events.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_extended_components.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_gesture_composition.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_hooks.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_hot_reload.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_images.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_incremental_render.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_interaction_props.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_ios_log.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_layout.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_mutations.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_native_views.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_net.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_platform.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_platform_metrics.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_reconciler.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_ref.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_runtime.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_smoke.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_suspense.py +0 -0
- {pythonnative-0.36.0 → pythonnative-0.38.0}/tests/test_transitions.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pythonnative
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.38.0
|
|
4
4
|
Summary: Cross-platform native UI toolkit for Android and iOS
|
|
5
5
|
Author: Owen Carey
|
|
6
6
|
License: MIT License
|
|
@@ -34,18 +34,13 @@ Classifier: Intended Audience :: Developers
|
|
|
34
34
|
Classifier: License :: OSI Approved :: MIT License
|
|
35
35
|
Classifier: Programming Language :: Python :: 3
|
|
36
36
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
37
|
-
Classifier: Programming Language :: Python :: 3.
|
|
38
|
-
Classifier: Programming Language :: Python :: 3.
|
|
39
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
40
39
|
Classifier: Topic :: Software Development :: User Interfaces
|
|
41
|
-
Requires-Python: >=3.
|
|
40
|
+
Requires-Python: >=3.13
|
|
42
41
|
Description-Content-Type: text/markdown
|
|
43
42
|
License-File: LICENSE
|
|
44
43
|
Requires-Dist: requests>=2.31.0
|
|
45
|
-
Requires-Dist: tomli>=2.0; python_version < "3.11"
|
|
46
|
-
Requires-Dist: typing_extensions>=4.4; python_version < "3.11"
|
|
47
|
-
Provides-Extra: ios
|
|
48
|
-
Requires-Dist: rubicon-objc<0.5.0,>=0.4.6; extra == "ios"
|
|
49
44
|
Provides-Extra: build
|
|
50
45
|
Requires-Dist: Pillow>=10.0; extra == "build"
|
|
51
46
|
Dynamic: license-file
|
|
@@ -78,7 +73,7 @@ Dynamic: license-file
|
|
|
78
73
|
|
|
79
74
|
## Overview
|
|
80
75
|
|
|
81
|
-
PythonNative is a cross-platform toolkit for building native Android and iOS apps in Python. It provides a **declarative, React-like component model** with hooks and automatic reconciliation
|
|
76
|
+
PythonNative is a cross-platform toolkit for building native Android and iOS apps in Python. It provides a **declarative, React-like component model** with hooks and automatic reconciliation on top of a **native rendering core** written in Swift and Kotlin. Write function components with `use_state`, `use_effect`, and friends, just like React, and let PythonNative handle creating and updating native views.
|
|
82
77
|
|
|
83
78
|
## Features
|
|
84
79
|
|
|
@@ -88,15 +83,16 @@ PythonNative is a cross-platform toolkit for building native Android and iOS app
|
|
|
88
83
|
- **Hooks and function components:** Manage state with `use_state`, side effects with `use_effect` / `use_layout_effect`, refs and imperative handles with `use_ref` / `use_imperative_handle`, and navigation with `use_navigation`, all through one consistent pattern. Components can return a single element, a list of siblings, or `None`, and `Fragment`, `Portal`, and reactive `Provider` context work the way they do in React.
|
|
89
84
|
- **Async-first rendering:** One `asyncio` event loop runs the whole framework on the platform's main thread. Components can be `async def` and `await` data directly in the body; `Suspense` boundaries show declarative loading states while they wait. `use_resource` fetches during render, `use_effect` accepts coroutine callbacks (cancelled automatically on unmount), `lazy` code-splits components, and `use_transition` / `use_deferred_value` keep the UI responsive during expensive updates.
|
|
90
85
|
- **Developer feedback that finds your bugs:** In dev mode (`pn preview`, hot reload, or `PN_DEV=1`), uncaught errors from renders, effects, and event handlers show a full-screen RedBox with the traceback; unknown style keys and duplicate list keys print "did you mean" warnings; and conditional hooks raise a `HookOrderError` at the source instead of silently cross-wiring state.
|
|
91
|
-
- **Typed `style` prop:** Pass all visual and layout properties through a single `style` dict, fully described by the `pn.Style` `TypedDict` and the ergonomic `pn.style(...)` helper for IDE autocomplete and static checking. Compose reusable styles with `StyleSheet
|
|
86
|
+
- **Typed `style` prop and theme:** Pass all visual and layout properties through a single `style` dict, fully described by the `pn.Style` `TypedDict` and the ergonomic `pn.style(...)` helper for IDE autocomplete and static checking. Compose reusable styles with `StyleSheet`, and read design tokens from a typed, immutable `pn.Theme` via `use_theme()` that follows light and dark mode by default.
|
|
92
87
|
- **Cross-platform flexbox engine:** A pure-Python, Yoga-style layout engine computes frames once and applies them to native views, so `flex`, `padding`, `aspect_ratio`, and `position: "absolute"` produce the same geometry on Android and iOS.
|
|
93
88
|
- **Virtual view tree + reconciler:** Element trees are diffed and patched with minimal native mutations, similar to React's reconciliation. Each commit lands as **one batched transaction** of mutation ops, and event callbacks are routed through a tag-based registry so re-renders that only change closures cost zero native calls. State updates re-render **locally**: only the component whose state changed (and its subtree) re-runs, and unchanged leaves reuse cached intrinsic measurements, so deep UIs stay responsive instead of re-rendering the whole app from the root on every tap.
|
|
94
89
|
- **Native-driven animations:** The `Animated` API (timing / spring / decay / loop / stagger, awaitable or fire-and-forget) hands animations to Core Animation and `ViewPropertyAnimator` whenever possible, so no Python code runs per frame; a pure-Python ticker covers the rest. `interpolate`, arithmetic operators on animated nodes, `Animated.event` scroll binding, and `diff_clamp` cover the scroll-driven patterns (collapsing headers, parallax) that define native feel.
|
|
95
90
|
- **Native gesture system:** Attach `Tap`, `LongPress`, `Pan`, `Swipe`, `Fling`, `Pinch`, and `Rotation` recognizers to any view via the `gestures=` prop, backed by `UIGestureRecognizer` on iOS and a unit-testable pure-Python arbiter on Android and desktop. Compose them with `Race`, `Exclusive`, and `Simultaneous` for cross-gesture arbitration (single vs. double tap, drag vs. long press).
|
|
96
91
|
- **Virtualized lists:** `FlatList` / `SectionList` window their rows in Python over the platform scroll view: uniform, exact, or measured variable heights, grids, headers/footers, infinite scroll, and an imperative scroll controller, identical on every platform.
|
|
97
|
-
- **
|
|
92
|
+
- **Native rendering core:** each commit is one serialized transaction applied by Swift and Kotlin component managers, the same shape as React Native's Fabric. Device APIs are native modules registered by name (TurboModules-style), callable from thin Python facades.
|
|
98
93
|
- **Custom-component SDK:** Wrap any platform widget as a first-class element with type-checked props via `pythonnative.sdk` (`Props`, `@native_component`, `element_factory`). Plugins distributed on PyPI auto-register through the `pythonnative.handlers` entry-point group.
|
|
99
94
|
- **CLI scaffolding:** `pn init` creates a ready-to-run project; `pn run android` and `pn run ios` build and launch your app.
|
|
95
|
+
- **PyPI packages, binary wheels included:** List requirements in `pythonnative.toml` and the CLI resolves them for the *device* (iOS wheels via PEP 730 and BeeWare's index, Android wheels via PEP 738 and Chaquopy), bundling numpy, Pillow, cryptography, and friends alongside pure-Python packages. `pn deps` reports what each target resolves to before you build, and a weekly-checked compatibility matrix keeps the docs honest.
|
|
100
96
|
- **Instant desktop preview:** `pn preview` renders your app in a native desktop window via Tkinter with Fast Refresh on every save: iterate on layout, state, and navigation in milliseconds without booting a simulator or device. The reconciler, hooks, layout engine, and navigation are the same code that ships to the phone.
|
|
101
97
|
- **Native-backed navigation:** Declarative `Stack`, `Tab`, and `Drawer` navigators inspired by React Navigation. The root stack drives the platform's native navigation controller (`UINavigationController` on iOS, AndroidX Navigation Component on Android), so transitions, back gestures, and the hardware back button match what users expect; `use_back_handler` intercepts the back action when a screen needs to.
|
|
102
98
|
- **Fast Refresh hot reload:** `pn run --hot-reload` watches `app/` and patches edits into the running app on save, preserving component state across most changes.
|
|
@@ -106,6 +102,8 @@ PythonNative is a cross-platform toolkit for building native Android and iOS app
|
|
|
106
102
|
|
|
107
103
|
### Installation
|
|
108
104
|
|
|
105
|
+
Requires Python 3.13 or newer.
|
|
106
|
+
|
|
109
107
|
```bash
|
|
110
108
|
pip install pythonnative
|
|
111
109
|
```
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
|
|
27
27
|
## Overview
|
|
28
28
|
|
|
29
|
-
PythonNative is a cross-platform toolkit for building native Android and iOS apps in Python. It provides a **declarative, React-like component model** with hooks and automatic reconciliation
|
|
29
|
+
PythonNative is a cross-platform toolkit for building native Android and iOS apps in Python. It provides a **declarative, React-like component model** with hooks and automatic reconciliation on top of a **native rendering core** written in Swift and Kotlin. Write function components with `use_state`, `use_effect`, and friends, just like React, and let PythonNative handle creating and updating native views.
|
|
30
30
|
|
|
31
31
|
## Features
|
|
32
32
|
|
|
@@ -36,15 +36,16 @@ PythonNative is a cross-platform toolkit for building native Android and iOS app
|
|
|
36
36
|
- **Hooks and function components:** Manage state with `use_state`, side effects with `use_effect` / `use_layout_effect`, refs and imperative handles with `use_ref` / `use_imperative_handle`, and navigation with `use_navigation`, all through one consistent pattern. Components can return a single element, a list of siblings, or `None`, and `Fragment`, `Portal`, and reactive `Provider` context work the way they do in React.
|
|
37
37
|
- **Async-first rendering:** One `asyncio` event loop runs the whole framework on the platform's main thread. Components can be `async def` and `await` data directly in the body; `Suspense` boundaries show declarative loading states while they wait. `use_resource` fetches during render, `use_effect` accepts coroutine callbacks (cancelled automatically on unmount), `lazy` code-splits components, and `use_transition` / `use_deferred_value` keep the UI responsive during expensive updates.
|
|
38
38
|
- **Developer feedback that finds your bugs:** In dev mode (`pn preview`, hot reload, or `PN_DEV=1`), uncaught errors from renders, effects, and event handlers show a full-screen RedBox with the traceback; unknown style keys and duplicate list keys print "did you mean" warnings; and conditional hooks raise a `HookOrderError` at the source instead of silently cross-wiring state.
|
|
39
|
-
- **Typed `style` prop:** Pass all visual and layout properties through a single `style` dict, fully described by the `pn.Style` `TypedDict` and the ergonomic `pn.style(...)` helper for IDE autocomplete and static checking. Compose reusable styles with `StyleSheet
|
|
39
|
+
- **Typed `style` prop and theme:** Pass all visual and layout properties through a single `style` dict, fully described by the `pn.Style` `TypedDict` and the ergonomic `pn.style(...)` helper for IDE autocomplete and static checking. Compose reusable styles with `StyleSheet`, and read design tokens from a typed, immutable `pn.Theme` via `use_theme()` that follows light and dark mode by default.
|
|
40
40
|
- **Cross-platform flexbox engine:** A pure-Python, Yoga-style layout engine computes frames once and applies them to native views, so `flex`, `padding`, `aspect_ratio`, and `position: "absolute"` produce the same geometry on Android and iOS.
|
|
41
41
|
- **Virtual view tree + reconciler:** Element trees are diffed and patched with minimal native mutations, similar to React's reconciliation. Each commit lands as **one batched transaction** of mutation ops, and event callbacks are routed through a tag-based registry so re-renders that only change closures cost zero native calls. State updates re-render **locally**: only the component whose state changed (and its subtree) re-runs, and unchanged leaves reuse cached intrinsic measurements, so deep UIs stay responsive instead of re-rendering the whole app from the root on every tap.
|
|
42
42
|
- **Native-driven animations:** The `Animated` API (timing / spring / decay / loop / stagger, awaitable or fire-and-forget) hands animations to Core Animation and `ViewPropertyAnimator` whenever possible, so no Python code runs per frame; a pure-Python ticker covers the rest. `interpolate`, arithmetic operators on animated nodes, `Animated.event` scroll binding, and `diff_clamp` cover the scroll-driven patterns (collapsing headers, parallax) that define native feel.
|
|
43
43
|
- **Native gesture system:** Attach `Tap`, `LongPress`, `Pan`, `Swipe`, `Fling`, `Pinch`, and `Rotation` recognizers to any view via the `gestures=` prop, backed by `UIGestureRecognizer` on iOS and a unit-testable pure-Python arbiter on Android and desktop. Compose them with `Race`, `Exclusive`, and `Simultaneous` for cross-gesture arbitration (single vs. double tap, drag vs. long press).
|
|
44
44
|
- **Virtualized lists:** `FlatList` / `SectionList` window their rows in Python over the platform scroll view: uniform, exact, or measured variable heights, grids, headers/footers, infinite scroll, and an imperative scroll controller, identical on every platform.
|
|
45
|
-
- **
|
|
45
|
+
- **Native rendering core:** each commit is one serialized transaction applied by Swift and Kotlin component managers, the same shape as React Native's Fabric. Device APIs are native modules registered by name (TurboModules-style), callable from thin Python facades.
|
|
46
46
|
- **Custom-component SDK:** Wrap any platform widget as a first-class element with type-checked props via `pythonnative.sdk` (`Props`, `@native_component`, `element_factory`). Plugins distributed on PyPI auto-register through the `pythonnative.handlers` entry-point group.
|
|
47
47
|
- **CLI scaffolding:** `pn init` creates a ready-to-run project; `pn run android` and `pn run ios` build and launch your app.
|
|
48
|
+
- **PyPI packages, binary wheels included:** List requirements in `pythonnative.toml` and the CLI resolves them for the *device* (iOS wheels via PEP 730 and BeeWare's index, Android wheels via PEP 738 and Chaquopy), bundling numpy, Pillow, cryptography, and friends alongside pure-Python packages. `pn deps` reports what each target resolves to before you build, and a weekly-checked compatibility matrix keeps the docs honest.
|
|
48
49
|
- **Instant desktop preview:** `pn preview` renders your app in a native desktop window via Tkinter with Fast Refresh on every save: iterate on layout, state, and navigation in milliseconds without booting a simulator or device. The reconciler, hooks, layout engine, and navigation are the same code that ships to the phone.
|
|
49
50
|
- **Native-backed navigation:** Declarative `Stack`, `Tab`, and `Drawer` navigators inspired by React Navigation. The root stack drives the platform's native navigation controller (`UINavigationController` on iOS, AndroidX Navigation Component on Android), so transitions, back gestures, and the hardware back button match what users expect; `use_back_handler` intercepts the back action when a screen needs to.
|
|
50
51
|
- **Fast Refresh hot reload:** `pn run --hot-reload` watches `app/` and patches edits into the running app on save, preserving component state across most changes.
|
|
@@ -54,6 +55,8 @@ PythonNative is a cross-platform toolkit for building native Android and iOS app
|
|
|
54
55
|
|
|
55
56
|
### Installation
|
|
56
57
|
|
|
58
|
+
Requires Python 3.13 or newer.
|
|
59
|
+
|
|
57
60
|
```bash
|
|
58
61
|
pip install pythonnative
|
|
59
62
|
```
|
|
@@ -4,13 +4,17 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pythonnative"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.38.0"
|
|
8
8
|
description = "Cross-platform native UI toolkit for Android and iOS"
|
|
9
9
|
authors = [
|
|
10
10
|
{ name = "Owen Carey" }
|
|
11
11
|
]
|
|
12
12
|
readme = "README.md"
|
|
13
|
-
|
|
13
|
+
# The host interpreter must match the embedded runtime (app.python_version)
|
|
14
|
+
# for device builds, and the embedded runtimes are 3.13 and 3.14: CPython
|
|
15
|
+
# gained official iOS support (PEP 730) and Android support (PEP 738) in
|
|
16
|
+
# 3.13, which is what makes binary wheels from PyPI installable at all.
|
|
17
|
+
requires-python = ">=3.13"
|
|
14
18
|
license = { file = "LICENSE" }
|
|
15
19
|
classifiers = [
|
|
16
20
|
"Development Status :: 2 - Pre-Alpha",
|
|
@@ -18,21 +22,15 @@ classifiers = [
|
|
|
18
22
|
"License :: OSI Approved :: MIT License",
|
|
19
23
|
"Programming Language :: Python :: 3",
|
|
20
24
|
"Programming Language :: Python :: 3 :: Only",
|
|
21
|
-
"Programming Language :: Python :: 3.
|
|
22
|
-
"Programming Language :: Python :: 3.
|
|
23
|
-
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Programming Language :: Python :: 3.13",
|
|
26
|
+
"Programming Language :: Python :: 3.14",
|
|
24
27
|
"Topic :: Software Development :: User Interfaces",
|
|
25
28
|
]
|
|
26
29
|
dependencies = [
|
|
27
30
|
"requests>=2.31.0",
|
|
28
|
-
"tomli>=2.0; python_version < '3.11'",
|
|
29
|
-
"typing_extensions>=4.4; python_version < '3.11'",
|
|
30
31
|
]
|
|
31
32
|
|
|
32
33
|
[project.optional-dependencies]
|
|
33
|
-
ios = [
|
|
34
|
-
"rubicon-objc>=0.4.6,<0.5.0",
|
|
35
|
-
]
|
|
36
34
|
build = [
|
|
37
35
|
"Pillow>=10.0",
|
|
38
36
|
]
|
|
@@ -47,8 +45,9 @@ dev = [
|
|
|
47
45
|
"pytest>=8.0",
|
|
48
46
|
"pytest-asyncio>=0.23",
|
|
49
47
|
"Pillow>=10.0",
|
|
50
|
-
# `pn run ios`
|
|
51
|
-
#
|
|
48
|
+
# `pn deps` and `pn run ios` shell out to `sys.executable -m pip` to
|
|
49
|
+
# resolve and vendor the app's [requirements].packages for the device
|
|
50
|
+
# platform tags (project/deps.py), and the test suite exercises that
|
|
52
51
|
# path. `uv sync` does not seed pip the way `uv venv --seed` did.
|
|
53
52
|
"pip>=24.0",
|
|
54
53
|
]
|
|
@@ -92,11 +91,12 @@ license-files = ["LICENSE*"]
|
|
|
92
91
|
# Include template directories inside the package so importlib.resources can find them
|
|
93
92
|
[tool.setuptools.package-data]
|
|
94
93
|
pythonnative = [
|
|
94
|
+
"py.typed",
|
|
95
95
|
"templates/**",
|
|
96
96
|
]
|
|
97
97
|
|
|
98
98
|
[tool.ruff]
|
|
99
|
-
target-version = "
|
|
99
|
+
target-version = "py313"
|
|
100
100
|
line-length = 120
|
|
101
101
|
extend-exclude = [
|
|
102
102
|
"templates",
|
|
@@ -137,10 +137,7 @@ convention = "google"
|
|
|
137
137
|
|
|
138
138
|
[tool.black]
|
|
139
139
|
line-length = 120
|
|
140
|
-
target-version = ['
|
|
141
|
-
|
|
142
|
-
[tool.pytest.ini_options]
|
|
143
|
-
asyncio_mode = "auto"
|
|
140
|
+
target-version = ['py313']
|
|
144
141
|
|
|
145
142
|
# ── Semantic Release ────────────────────────────────────────────────
|
|
146
143
|
|
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
PythonNative is a cross-platform toolkit that turns Python ``@component``
|
|
4
4
|
functions into real, native Android and iOS views. The component model
|
|
5
|
-
is React-like (function components plus hooks)
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
is React-like (function components plus hooks). Python owns the
|
|
6
|
+
component tree, reconciliation, and layout; each commit crosses once
|
|
7
|
+
into a native rendering core (Swift ``PythonNativeKit`` on iOS, the
|
|
8
|
+
Kotlin ``pythonnative`` module on Android) that owns every platform
|
|
9
|
+
view, gesture, animation, and device API. There is no JavaScript.
|
|
8
10
|
|
|
9
11
|
Key building blocks:
|
|
10
12
|
|
|
@@ -60,7 +62,7 @@ Example:
|
|
|
60
62
|
```
|
|
61
63
|
"""
|
|
62
64
|
|
|
63
|
-
__version__ = "0.
|
|
65
|
+
__version__ = "0.38.0"
|
|
64
66
|
|
|
65
67
|
from . import appearance, diagnostics, gestures, images, runtime, sdk
|
|
66
68
|
from .alerts import Alert
|
|
@@ -188,6 +190,7 @@ from .style import (
|
|
|
188
190
|
AutoCapitalize,
|
|
189
191
|
Color,
|
|
190
192
|
Dimension,
|
|
193
|
+
Display,
|
|
191
194
|
EdgeInsets,
|
|
192
195
|
FlexDirection,
|
|
193
196
|
FlexWrap,
|
|
@@ -196,6 +199,7 @@ from .style import (
|
|
|
196
199
|
KeyboardType,
|
|
197
200
|
LayoutDirection,
|
|
198
201
|
Overflow,
|
|
202
|
+
PointerEvents,
|
|
199
203
|
Position,
|
|
200
204
|
ReturnKeyType,
|
|
201
205
|
ScaleType,
|
|
@@ -205,6 +209,8 @@ from .style import (
|
|
|
205
209
|
StyleSheet,
|
|
206
210
|
TextAlign,
|
|
207
211
|
TextDecoration,
|
|
212
|
+
TextTransform,
|
|
213
|
+
Theme,
|
|
208
214
|
ThemeContext,
|
|
209
215
|
TransformSpec,
|
|
210
216
|
default_theme,
|
|
@@ -312,6 +318,7 @@ __all__ = [
|
|
|
312
318
|
"DEFAULT_DARK_THEME",
|
|
313
319
|
"DEFAULT_LIGHT_THEME",
|
|
314
320
|
"Dimension",
|
|
321
|
+
"Display",
|
|
315
322
|
"EdgeInsets",
|
|
316
323
|
"FlexDirection",
|
|
317
324
|
"FlexWrap",
|
|
@@ -320,6 +327,7 @@ __all__ = [
|
|
|
320
327
|
"KeyboardType",
|
|
321
328
|
"LayoutDirection",
|
|
322
329
|
"Overflow",
|
|
330
|
+
"PointerEvents",
|
|
323
331
|
"Position",
|
|
324
332
|
"ReturnKeyType",
|
|
325
333
|
"ScaleType",
|
|
@@ -329,6 +337,8 @@ __all__ = [
|
|
|
329
337
|
"StyleSheet",
|
|
330
338
|
"TextAlign",
|
|
331
339
|
"TextDecoration",
|
|
340
|
+
"TextTransform",
|
|
341
|
+
"Theme",
|
|
332
342
|
"ThemeContext",
|
|
333
343
|
"TransformSpec",
|
|
334
344
|
"default_theme",
|
|
@@ -14,7 +14,7 @@ straight to fd 2 is a small, reliable fix: fd 2 *is* visible to
|
|
|
14
14
|
`simctl` (that is exactly how `NSLog` reaches the terminal), so
|
|
15
15
|
Python output lands next to the Swift logs with correct ordering.
|
|
16
16
|
|
|
17
|
-
This module is intentionally self-contained (no
|
|
17
|
+
This module is intentionally self-contained (no bridge or
|
|
18
18
|
platform-specific C bindings required), so it is safe to import
|
|
19
19
|
early during `pythonnative` package initialization.
|
|
20
20
|
"""
|
|
@@ -30,77 +30,39 @@ Example:
|
|
|
30
30
|
|
|
31
31
|
from __future__ import annotations
|
|
32
32
|
|
|
33
|
-
import asyncio
|
|
34
33
|
from typing import Any, Dict, List, Optional, Sequence
|
|
35
34
|
|
|
36
|
-
from .
|
|
37
|
-
from .runtime import resolve_future
|
|
35
|
+
from .native_modules.registry import native_module
|
|
38
36
|
|
|
39
37
|
# ======================================================================
|
|
40
38
|
# Internal dispatch helpers
|
|
41
39
|
# ======================================================================
|
|
42
40
|
|
|
43
41
|
|
|
44
|
-
def
|
|
42
|
+
async def _present(
|
|
45
43
|
*,
|
|
46
44
|
title: str,
|
|
47
45
|
message: Optional[str],
|
|
48
46
|
buttons: List[Dict[str, Any]],
|
|
49
47
|
style: str,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
"""Route an alert request to the active platform presenter.
|
|
48
|
+
) -> int:
|
|
49
|
+
"""Ask the native ``Alert`` module to present and await the chosen index.
|
|
53
50
|
|
|
54
51
|
``buttons`` is a list of ``{"label": str, "style":
|
|
55
|
-
"default"|"cancel"|"destructive"}`` dicts. The
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
52
|
+
"default"|"cancel"|"destructive"}`` dicts. The module resolves with
|
|
53
|
+
the index the user picked, or ``-1`` if the dialog was dismissed
|
|
54
|
+
without a selection. Off device the
|
|
55
|
+
[`DesktopAlert`][pythonnative.native_modules.desktop.DesktopAlert]
|
|
56
|
+
implementation records the call and answers from the queue set by
|
|
57
|
+
[`Alert.set_test_response`][pythonnative.alerts.Alert.set_test_response].
|
|
59
58
|
"""
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
from .native_views.ios import _present_alert as _ios_present_alert
|
|
63
|
-
|
|
64
|
-
_ios_present_alert(
|
|
65
|
-
title=title,
|
|
66
|
-
message=message,
|
|
67
|
-
buttons=buttons,
|
|
68
|
-
style=style,
|
|
69
|
-
on_result=on_result,
|
|
70
|
-
)
|
|
71
|
-
return
|
|
72
|
-
except Exception:
|
|
73
|
-
on_result(-1)
|
|
74
|
-
return
|
|
75
|
-
|
|
76
|
-
if Platform.is_android:
|
|
77
|
-
try:
|
|
78
|
-
from .native_views.android import _present_alert as _android_present_alert
|
|
79
|
-
|
|
80
|
-
_android_present_alert(
|
|
81
|
-
title=title,
|
|
82
|
-
message=message,
|
|
83
|
-
buttons=buttons,
|
|
84
|
-
style=style,
|
|
85
|
-
on_result=on_result,
|
|
86
|
-
)
|
|
87
|
-
return
|
|
88
|
-
except Exception:
|
|
89
|
-
on_result(-1)
|
|
90
|
-
return
|
|
91
|
-
|
|
92
|
-
# Test backend: record the call so unit tests can assert on it,
|
|
93
|
-
# then deliver the configured response.
|
|
94
|
-
Alert._test_log.append(
|
|
95
|
-
{
|
|
96
|
-
"title": title,
|
|
97
|
-
"message": message,
|
|
98
|
-
"buttons": list(buttons),
|
|
99
|
-
"style": style,
|
|
100
|
-
}
|
|
59
|
+
result = await native_module("Alert").call_async(
|
|
60
|
+
"present", title=title, message=message, buttons=buttons, style=style
|
|
101
61
|
)
|
|
102
|
-
|
|
103
|
-
|
|
62
|
+
try:
|
|
63
|
+
return int(result)
|
|
64
|
+
except (TypeError, ValueError):
|
|
65
|
+
return -1
|
|
104
66
|
|
|
105
67
|
|
|
106
68
|
# ======================================================================
|
|
@@ -170,12 +132,8 @@ class Alert:
|
|
|
170
132
|
[`choose`][pythonnative.alerts.Alert.choose] and ``await``
|
|
171
133
|
the result.
|
|
172
134
|
"""
|
|
173
|
-
|
|
174
|
-
title=title,
|
|
175
|
-
message=message,
|
|
176
|
-
buttons=[{"label": button, "style": "default"}],
|
|
177
|
-
style="alert",
|
|
178
|
-
on_result=lambda _idx: None,
|
|
135
|
+
native_module("Alert").call(
|
|
136
|
+
"show", title=title, message=message, buttons=[{"label": button, "style": "default"}], style="alert"
|
|
179
137
|
)
|
|
180
138
|
|
|
181
139
|
@staticmethod
|
|
@@ -206,13 +164,7 @@ class Alert:
|
|
|
206
164
|
await save()
|
|
207
165
|
```
|
|
208
166
|
"""
|
|
209
|
-
|
|
210
|
-
future: asyncio.Future[bool] = loop.create_future()
|
|
211
|
-
|
|
212
|
-
def _on_result(index: int) -> None:
|
|
213
|
-
resolve_future(future, index == 1)
|
|
214
|
-
|
|
215
|
-
_dispatch_alert(
|
|
167
|
+
index = await _present(
|
|
216
168
|
title=title,
|
|
217
169
|
message=message,
|
|
218
170
|
buttons=[
|
|
@@ -220,9 +172,8 @@ class Alert:
|
|
|
220
172
|
{"label": confirm_label, "style": "default"},
|
|
221
173
|
],
|
|
222
174
|
style="alert",
|
|
223
|
-
on_result=_on_result,
|
|
224
175
|
)
|
|
225
|
-
return
|
|
176
|
+
return index == 1
|
|
226
177
|
|
|
227
178
|
@staticmethod
|
|
228
179
|
async def choose(
|
|
@@ -265,9 +216,6 @@ class Alert:
|
|
|
265
216
|
if not options:
|
|
266
217
|
raise ValueError("Alert.choose requires at least one option")
|
|
267
218
|
|
|
268
|
-
loop = asyncio.get_running_loop()
|
|
269
|
-
future: asyncio.Future[Optional[str]] = loop.create_future()
|
|
270
|
-
|
|
271
219
|
destructive = set(destructive_labels)
|
|
272
220
|
buttons: List[Dict[str, Any]] = [
|
|
273
221
|
{
|
|
@@ -279,20 +227,10 @@ class Alert:
|
|
|
279
227
|
if cancel_label is not None:
|
|
280
228
|
buttons.append({"label": cancel_label, "style": "cancel"})
|
|
281
229
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
resolve_future(future, None)
|
|
287
|
-
|
|
288
|
-
_dispatch_alert(
|
|
289
|
-
title=title,
|
|
290
|
-
message=message,
|
|
291
|
-
buttons=buttons,
|
|
292
|
-
style=style,
|
|
293
|
-
on_result=_on_result,
|
|
294
|
-
)
|
|
295
|
-
return await future
|
|
230
|
+
index = await _present(title=title, message=message, buttons=buttons, style=style)
|
|
231
|
+
if 0 <= index < len(options):
|
|
232
|
+
return options[index]
|
|
233
|
+
return None
|
|
296
234
|
|
|
297
235
|
|
|
298
236
|
__all__ = ["Alert"]
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"""Entry point the native app templates run right after Python starts.
|
|
2
|
+
|
|
3
|
+
Both templates execute one line of Python once the interpreter is up:
|
|
4
|
+
|
|
5
|
+
```python
|
|
6
|
+
import pythonnative.bootstrap; pythonnative.bootstrap.start()
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
[`start`][pythonnative.bootstrap.start] connects the two halves of the
|
|
10
|
+
bridge (installing the native -> Python callback on iOS), verifies the
|
|
11
|
+
protocol version, routes ``print()`` to the console on iOS, and warms
|
|
12
|
+
the asyncio runtime. From then on the native runtime drives everything
|
|
13
|
+
through ``callback("host", ...)``; see ``docs/concepts/bridge.md``.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import os
|
|
19
|
+
import sys
|
|
20
|
+
import traceback
|
|
21
|
+
from typing import Any, Dict
|
|
22
|
+
|
|
23
|
+
__all__ = ["start", "status"]
|
|
24
|
+
|
|
25
|
+
_started: Dict[str, Any] = {}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def start(dev: bool = False, strict: bool = False) -> Dict[str, Any]:
|
|
29
|
+
"""Connect the bridge and prepare the runtime.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
dev: Enable dev mode (RedBox, validation warnings). Debug
|
|
33
|
+
templates pass ``True``; hot reload turns it on as well.
|
|
34
|
+
strict: Re-raise the failure after recording it. The templates
|
|
35
|
+
pass ``True`` so a broken bridge surfaces as a bootstrap
|
|
36
|
+
error screen with the full traceback.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
A status dict (``{"protocol": 1, "platform": "ios"}``) that the
|
|
40
|
+
template logs. Unless ``strict`` is set this never raises:
|
|
41
|
+
failures are printed and reported in the dict under
|
|
42
|
+
``"error"``.
|
|
43
|
+
"""
|
|
44
|
+
global _started
|
|
45
|
+
if _started and "error" not in _started:
|
|
46
|
+
return dict(_started)
|
|
47
|
+
status_: Dict[str, Any] = {"platform": None, "protocol": None}
|
|
48
|
+
try:
|
|
49
|
+
from .utils import IS_ANDROID, IS_IOS
|
|
50
|
+
|
|
51
|
+
status_["platform"] = "ios" if IS_IOS else "android" if IS_ANDROID else "off-device"
|
|
52
|
+
if IS_IOS:
|
|
53
|
+
try:
|
|
54
|
+
from . import _ios_log
|
|
55
|
+
|
|
56
|
+
_ios_log.install()
|
|
57
|
+
except Exception:
|
|
58
|
+
pass
|
|
59
|
+
from . import bridge
|
|
60
|
+
|
|
61
|
+
status_["protocol"] = bridge.handshake()
|
|
62
|
+
if dev or os.environ.get("PN_DEV") in ("1", "true"):
|
|
63
|
+
from . import diagnostics
|
|
64
|
+
|
|
65
|
+
diagnostics.set_dev_mode(True)
|
|
66
|
+
# Create the guest loop now so the first pump request has a
|
|
67
|
+
# loop to drive and effects can schedule work during mount.
|
|
68
|
+
from .runtime import get_loop
|
|
69
|
+
|
|
70
|
+
get_loop()
|
|
71
|
+
# Import the view backend eagerly: on a slow device the first
|
|
72
|
+
# commit shouldn't also pay for importing the reconciler.
|
|
73
|
+
from .native_views import get_registry
|
|
74
|
+
|
|
75
|
+
get_registry()
|
|
76
|
+
except Exception as exc:
|
|
77
|
+
status_["error"] = f"{type(exc).__name__}: {exc}"
|
|
78
|
+
print(f"[pn.bootstrap] start failed: {exc!r}", file=sys.stderr)
|
|
79
|
+
traceback.print_exc()
|
|
80
|
+
_started = status_
|
|
81
|
+
if strict:
|
|
82
|
+
raise
|
|
83
|
+
return dict(status_)
|
|
84
|
+
_started = status_
|
|
85
|
+
return dict(status_)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def status() -> Dict[str, Any]:
|
|
89
|
+
"""Return the result of the last [`start`][pythonnative.bootstrap.start] (empty before it ran)."""
|
|
90
|
+
return dict(_started)
|