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.
- pythonnative/__init__.py +411 -0
- pythonnative/_ios_log.py +92 -0
- pythonnative/_yoga.cp313-win_amd64.pyd +0 -0
- pythonnative/alerts.py +236 -0
- pythonnative/animated.py +1687 -0
- pythonnative/animation_graph.py +78 -0
- pythonnative/appearance.py +124 -0
- pythonnative/bootstrap.py +100 -0
- pythonnative/bridge/__init__.py +302 -0
- pythonnative/bridge/android.py +78 -0
- pythonnative/bridge/codec.py +170 -0
- pythonnative/bridge/commits.py +114 -0
- pythonnative/bridge/fake.py +243 -0
- pythonnative/bridge/ios.py +138 -0
- pythonnative/bridge/web.py +489 -0
- pythonnative/cli/__init__.py +7 -0
- pythonnative/cli/pn.py +1214 -0
- pythonnative/component.py +271 -0
- pythonnative/components/__init__.py +111 -0
- pythonnative/components/_base.py +166 -0
- pythonnative/components/controls.py +521 -0
- pythonnative/components/layout.py +518 -0
- pythonnative/components/lists.py +785 -0
- pythonnative/components/media.py +204 -0
- pythonnative/components/overlays.py +107 -0
- pythonnative/components/pressable.py +252 -0
- pythonnative/components/structural.py +167 -0
- pythonnative/components/text.py +291 -0
- pythonnative/devclient.py +824 -0
- pythonnative/devserver/__init__.py +34 -0
- pythonnative/devserver/server.py +718 -0
- pythonnative/devserver/static/animation_graph.js +82 -0
- pythonnative/devserver/static/bridge.js +147 -0
- pythonnative/devserver/static/colors.js +70 -0
- pythonnative/devserver/static/host.js +552 -0
- pythonnative/devserver/static/index.html +60 -0
- pythonnative/devserver/static/layout.js +85 -0
- pythonnative/devserver/static/preview.css +415 -0
- pythonnative/devserver/static/renderer.js +1994 -0
- pythonnative/devserver/static/shell.js +345 -0
- pythonnative/devserver/static/yoga/LICENSE +21 -0
- pythonnative/devserver/static/yoga/binaries/yoga-wasm-base64-esm.js +75 -0
- pythonnative/devserver/static/yoga/src/generated/YGEnums.d.ts +189 -0
- pythonnative/devserver/static/yoga/src/generated/YGEnums.js +211 -0
- pythonnative/devserver/static/yoga/src/generated/YGEnums.js.map +1 -0
- pythonnative/devserver/static/yoga/src/index.d.ts +12 -0
- pythonnative/devserver/static/yoga/src/index.js +16 -0
- pythonnative/devserver/static/yoga/src/index.js.map +1 -0
- pythonnative/devserver/static/yoga/src/load.d.ts +11 -0
- pythonnative/devserver/static/yoga/src/load.js +17 -0
- pythonnative/devserver/static/yoga/src/load.js.map +1 -0
- pythonnative/devserver/static/yoga/src/wrapAssembly.d.ts +155 -0
- pythonnative/devserver/static/yoga/src/wrapAssembly.js +125 -0
- pythonnative/devserver/static/yoga/src/wrapAssembly.js.map +1 -0
- pythonnative/devserver/watcher.py +267 -0
- pythonnative/devserver/ws.py +421 -0
- pythonnative/diagnostics.py +241 -0
- pythonnative/element.py +159 -0
- pythonnative/equality.py +19 -0
- pythonnative/events.py +231 -0
- pythonnative/gestures.py +1333 -0
- pythonnative/hooks.py +1621 -0
- pythonnative/hosts/__init__.py +63 -0
- pythonnative/hosts/base.py +596 -0
- pythonnative/hosts/native.py +302 -0
- pythonnative/hot_reload.py +585 -0
- pythonnative/layout.py +328 -0
- pythonnative/mutations.py +142 -0
- pythonnative/native/android/build.gradle +52 -0
- pythonnative/native/android/gradle.properties +3 -0
- pythonnative/native/android/settings.gradle +12 -0
- pythonnative/native/android/src/main/AndroidManifest.xml +11 -0
- pythonnative/native/android/src/main/cpp/CMakeLists.txt +9 -0
- pythonnative/native/android/src/main/cpp/yoga_jni.cpp +52 -0
- pythonnative/native/android/src/main/java/com/pythonnative/generated/NativeModules.kt +5 -0
- pythonnative/native/android/src/main/java/com/pythonnative/generated/NativeProps.kt +3705 -0
- pythonnative/native/android/src/main/java/com/pythonnative/generated/PNContracts.kt +129 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/PNBridge.kt +261 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/PythonHost.kt +20 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/animation/AnimationGraph.kt +108 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/animation/AnimationSpecs.kt +141 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/animation/PNAnimator.kt +257 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/CommitState.kt +106 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/JsonUtil.kt +175 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/MainThread.kt +40 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/PNLog.kt +33 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/PNRegistry.kt +82 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/PNTransaction.kt +80 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/TransactionApplier.kt +117 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/ViewRegistry.kt +74 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/BuiltinComponents.kt +37 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ButtonManager.kt +32 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ComponentManager.kt +213 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ContainerManagers.kt +69 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ControlManagers.kt +186 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/DatePickerManager.kt +123 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ImageLoader.kt +141 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ImageManager.kt +162 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ModalManager.kt +134 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/PNColor.kt +201 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/PickerManager.kt +86 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/PortalManager.kt +55 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/PressableManager.kt +122 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ScreenStackManager.kt +110 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ScrollViewManager.kt +214 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/SegmentedControlManager.kt +113 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/StatusBarManager.kt +52 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/TabBarManager.kt +131 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/TextInputManager.kt +250 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/TextManager.kt +233 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ViewStyler.kt +355 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/VirtualListManager.kt +159 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/WebViewManager.kt +149 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/gestures/GestureArbiter.kt +233 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/gestures/GestureCoordinator.kt +127 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/gestures/GestureRecognizers.kt +527 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/layout/NativeLayout.kt +145 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/layout/YogaNode.kt +29 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/BuiltinModules.kt +73 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/DeviceModules.kt +316 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/HostModule.kt +61 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/MediaModules.kt +200 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/NativeModule.kt +158 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/NotificationsModule.kt +100 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/PermissionsModule.kt +99 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/StorageModules.kt +89 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/SystemModules.kt +178 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/plugins/GeneratedPlugins.kt +16 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/screens/PNScreenFragment.kt +188 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/screens/ScreenRegistry.kt +80 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/views/PNAccessibilityDelegate.kt +48 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/views/PNBorderDrawable.kt +76 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/views/PNEditText.kt +18 -0
- pythonnative/native/android/src/main/java/com/pythonnative/runtime/views/PNFrameLayout.kt +49 -0
- pythonnative/native/android/src/test/java/com/pythonnative/runtime/AnimationSpecsTest.kt +75 -0
- pythonnative/native/android/src/test/java/com/pythonnative/runtime/GestureArbiterTest.kt +197 -0
- pythonnative/native/android/src/test/java/com/pythonnative/runtime/PNColorTest.kt +47 -0
- pythonnative/native/android/src/test/java/com/pythonnative/runtime/PNTransactionTest.kt +78 -0
- pythonnative/native/android/src/test/java/com/pythonnative/runtime/PromiseTest.kt +89 -0
- pythonnative/native/ios/Package.swift +23 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Animation/PNAnimationGraph.swift +199 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Animation/PNAnimator.swift +312 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Bridge/PNBridge.swift +255 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Bridge/PNCommit.swift +104 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Bridge/PNRegistry.swift +142 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Bridge/PNTransaction.swift +166 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Bridge/PNViewRegistry.swift +53 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Components/PNButtonManagers.swift +207 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Components/PNColor.swift +173 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Components/PNComponentManager.swift +183 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Components/PNContainerView.swift +56 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Components/PNControlManagers.swift +281 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Components/PNImageManager.swift +222 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Components/PNOverlayManagers.swift +243 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Components/PNPressableManager.swift +114 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Components/PNScreenStackManager.swift +107 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Components/PNScrollViewManager.swift +197 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Components/PNTabBarManager.swift +106 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Components/PNTextInputManager.swift +297 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Components/PNTextManager.swift +230 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Components/PNTransform.swift +82 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Components/PNViewManager.swift +86 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Components/PNViewState.swift +87 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Components/PNViewStyler.swift +340 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Components/PNVirtualListManager.swift +155 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Components/PNWebViewManager.swift +124 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Generated/NativeModules.swift +1 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Generated/NativeProps.swift +3775 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Generated/PNContracts.swift +46 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Gestures/PNGestureCoordinator.swift +260 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Layout/PNLayout.swift +173 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Modules/AlertModule.swift +92 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Modules/HostModule.swift +80 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Modules/LifecycleModules.swift +174 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Modules/MediaModules.swift +177 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Modules/PNNativeModule.swift +168 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Modules/PermissionModules.swift +266 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Modules/SystemModules.swift +251 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Plugins/PNPluginRegistration.swift +8 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Screens/PNScreenRegistry.swift +46 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Screens/PNViewController.swift +237 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Support/PNCompat.swift +46 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Support/PNJSON.swift +173 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Support/PNLog.swift +47 -0
- pythonnative/native/ios/Sources/PythonNativeKit/Support/PNWindow.swift +51 -0
- pythonnative/native/ios/Tests/PythonNativeKitTests/PNAnimationGraphTests.swift +26 -0
- pythonnative/native/ios/Tests/PythonNativeKitTests/PNColorTests.swift +50 -0
- pythonnative/native/ios/Tests/PythonNativeKitTests/PNCommitTests.swift +86 -0
- pythonnative/native/ios/Tests/PythonNativeKitTests/PNGestureTests.swift +101 -0
- pythonnative/native/ios/Tests/PythonNativeKitTests/PNManagerTests.swift +126 -0
- pythonnative/native/ios/Tests/PythonNativeKitTests/PNModuleTests.swift +111 -0
- pythonnative/native/ios/Tests/PythonNativeKitTests/PNTransactionTests.swift +91 -0
- pythonnative/native/yoga/LICENSE +21 -0
- pythonnative/native/yoga/Package.swift +9 -0
- pythonnative/native/yoga/VENDORED.md +2 -0
- pythonnative/native/yoga/include/PNStyle.h +10 -0
- pythonnative/native/yoga/include/module.modulemap +5 -0
- pythonnative/native/yoga/include/yoga/YGConfig.h +158 -0
- pythonnative/native/yoga/include/yoga/YGEnums.h +142 -0
- pythonnative/native/yoga/include/yoga/YGMacros.h +99 -0
- pythonnative/native/yoga/include/yoga/YGNode.h +304 -0
- pythonnative/native/yoga/include/yoga/YGNodeLayout.h +35 -0
- pythonnative/native/yoga/include/yoga/YGNodeStyle.h +130 -0
- pythonnative/native/yoga/include/yoga/YGPixelGrid.h +29 -0
- pythonnative/native/yoga/include/yoga/YGValue.h +84 -0
- pythonnative/native/yoga/include/yoga/Yoga.h +21 -0
- pythonnative/native/yoga/python.cpp +16 -0
- pythonnative/native/yoga/style.cpp +272 -0
- pythonnative/native/yoga/yoga/CMakeLists.txt +41 -0
- pythonnative/native/yoga/yoga/YGConfig.cpp +92 -0
- pythonnative/native/yoga/yoga/YGConfig.h +158 -0
- pythonnative/native/yoga/yoga/YGEnums.cpp +262 -0
- pythonnative/native/yoga/yoga/YGEnums.h +142 -0
- pythonnative/native/yoga/yoga/YGMacros.h +99 -0
- pythonnative/native/yoga/yoga/YGNode.cpp +366 -0
- pythonnative/native/yoga/yoga/YGNode.h +304 -0
- pythonnative/native/yoga/yoga/YGNodeLayout.cpp +92 -0
- pythonnative/native/yoga/yoga/YGNodeLayout.h +35 -0
- pythonnative/native/yoga/yoga/YGNodeStyle.cpp +405 -0
- pythonnative/native/yoga/yoga/YGNodeStyle.h +130 -0
- pythonnative/native/yoga/yoga/YGPixelGrid.cpp +22 -0
- pythonnative/native/yoga/yoga/YGPixelGrid.h +29 -0
- pythonnative/native/yoga/yoga/YGValue.cpp +20 -0
- pythonnative/native/yoga/yoga/YGValue.h +84 -0
- pythonnative/native/yoga/yoga/Yoga.h +21 -0
- pythonnative/native/yoga/yoga/algorithm/AbsoluteLayout.cpp +563 -0
- pythonnative/native/yoga/yoga/algorithm/AbsoluteLayout.h +41 -0
- pythonnative/native/yoga/yoga/algorithm/Align.h +72 -0
- pythonnative/native/yoga/yoga/algorithm/Baseline.cpp +78 -0
- pythonnative/native/yoga/yoga/algorithm/Baseline.h +21 -0
- pythonnative/native/yoga/yoga/algorithm/BoundAxis.h +79 -0
- pythonnative/native/yoga/yoga/algorithm/Cache.cpp +121 -0
- pythonnative/native/yoga/yoga/algorithm/Cache.h +30 -0
- pythonnative/native/yoga/yoga/algorithm/CalculateLayout.cpp +2428 -0
- pythonnative/native/yoga/yoga/algorithm/CalculateLayout.h +38 -0
- pythonnative/native/yoga/yoga/algorithm/FlexDirection.h +120 -0
- pythonnative/native/yoga/yoga/algorithm/FlexLine.cpp +124 -0
- pythonnative/native/yoga/yoga/algorithm/FlexLine.h +75 -0
- pythonnative/native/yoga/yoga/algorithm/PixelGrid.cpp +132 -0
- pythonnative/native/yoga/yoga/algorithm/PixelGrid.h +29 -0
- pythonnative/native/yoga/yoga/algorithm/SizingMode.h +73 -0
- pythonnative/native/yoga/yoga/algorithm/TrailingPosition.h +44 -0
- pythonnative/native/yoga/yoga/config/Config.cpp +135 -0
- pythonnative/native/yoga/yoga/config/Config.h +92 -0
- pythonnative/native/yoga/yoga/debug/AssertFatal.cpp +53 -0
- pythonnative/native/yoga/yoga/debug/AssertFatal.h +29 -0
- pythonnative/native/yoga/yoga/debug/Log.cpp +107 -0
- pythonnative/native/yoga/yoga/debug/Log.h +34 -0
- pythonnative/native/yoga/yoga/enums/Align.h +47 -0
- pythonnative/native/yoga/yoga/enums/BoxSizing.h +40 -0
- pythonnative/native/yoga/yoga/enums/Dimension.h +40 -0
- pythonnative/native/yoga/yoga/enums/Direction.h +41 -0
- pythonnative/native/yoga/yoga/enums/Display.h +41 -0
- pythonnative/native/yoga/yoga/enums/Edge.h +47 -0
- pythonnative/native/yoga/yoga/enums/Errata.h +41 -0
- pythonnative/native/yoga/yoga/enums/ExperimentalFeature.h +39 -0
- pythonnative/native/yoga/yoga/enums/FlexDirection.h +42 -0
- pythonnative/native/yoga/yoga/enums/Gutter.h +41 -0
- pythonnative/native/yoga/yoga/enums/Justify.h +44 -0
- pythonnative/native/yoga/yoga/enums/LogLevel.h +44 -0
- pythonnative/native/yoga/yoga/enums/MeasureMode.h +41 -0
- pythonnative/native/yoga/yoga/enums/NodeType.h +40 -0
- pythonnative/native/yoga/yoga/enums/Overflow.h +41 -0
- pythonnative/native/yoga/yoga/enums/PhysicalEdge.h +21 -0
- pythonnative/native/yoga/yoga/enums/PositionType.h +41 -0
- pythonnative/native/yoga/yoga/enums/Unit.h +42 -0
- pythonnative/native/yoga/yoga/enums/Wrap.h +41 -0
- pythonnative/native/yoga/yoga/enums/YogaEnums.h +85 -0
- pythonnative/native/yoga/yoga/event/event.cpp +87 -0
- pythonnative/native/yoga/yoga/event/event.h +130 -0
- pythonnative/native/yoga/yoga/module.modulemap +21 -0
- pythonnative/native/yoga/yoga/node/CachedMeasurement.h +53 -0
- pythonnative/native/yoga/yoga/node/LayoutResults.cpp +48 -0
- pythonnative/native/yoga/yoga/node/LayoutResults.h +122 -0
- pythonnative/native/yoga/yoga/node/LayoutableChildren.h +148 -0
- pythonnative/native/yoga/yoga/node/Node.cpp +443 -0
- pythonnative/native/yoga/yoga/node/Node.h +337 -0
- pythonnative/native/yoga/yoga/numeric/Comparison.h +81 -0
- pythonnative/native/yoga/yoga/numeric/FloatOptional.h +93 -0
- pythonnative/native/yoga/yoga/style/SmallValueBuffer.h +133 -0
- pythonnative/native/yoga/yoga/style/Style.h +757 -0
- pythonnative/native/yoga/yoga/style/StyleLength.h +107 -0
- pythonnative/native/yoga/yoga/style/StyleValueHandle.h +98 -0
- pythonnative/native/yoga/yoga/style/StyleValuePool.h +127 -0
- pythonnative/native_modules/__init__.py +124 -0
- pythonnative/native_modules/app_state.py +99 -0
- pythonnative/native_modules/battery.py +75 -0
- pythonnative/native_modules/biometrics.py +42 -0
- pythonnative/native_modules/camera.py +65 -0
- pythonnative/native_modules/clipboard.py +46 -0
- pythonnative/native_modules/fallback.py +324 -0
- pythonnative/native_modules/file_system.py +145 -0
- pythonnative/native_modules/haptics.py +75 -0
- pythonnative/native_modules/linking.py +123 -0
- pythonnative/native_modules/location.py +75 -0
- pythonnative/native_modules/net_info.py +112 -0
- pythonnative/native_modules/notifications.py +129 -0
- pythonnative/native_modules/permissions.py +108 -0
- pythonnative/native_modules/registry.py +526 -0
- pythonnative/native_modules/secure_store.py +52 -0
- pythonnative/native_modules/share.py +51 -0
- pythonnative/native_views/__init__.py +375 -0
- pythonnative/native_views/base.py +316 -0
- pythonnative/native_views/bridge_backend.py +277 -0
- pythonnative/navigation/__init__.py +103 -0
- pythonnative/navigation/container.py +154 -0
- pythonnative/navigation/handle.py +540 -0
- pythonnative/navigation/hooks.py +133 -0
- pythonnative/navigation/host.py +58 -0
- pythonnative/navigation/linking.py +200 -0
- pythonnative/navigation/navigators.py +659 -0
- pythonnative/navigation/screen.py +149 -0
- pythonnative/navigation/state.py +269 -0
- pythonnative/net.py +248 -0
- pythonnative/platform.py +166 -0
- pythonnative/platform_metrics.py +252 -0
- pythonnative/preview.py +287 -0
- pythonnative/profiling.py +101 -0
- pythonnative/project/__init__.py +68 -0
- pythonnative/project/android.py +557 -0
- pythonnative/project/builder.py +817 -0
- pythonnative/project/config.py +773 -0
- pythonnative/project/deps.py +719 -0
- pythonnative/project/devices.py +304 -0
- pythonnative/project/doctor.py +283 -0
- pythonnative/project/fingerprint.py +171 -0
- pythonnative/project/icons.py +247 -0
- pythonnative/project/ios.py +325 -0
- pythonnative/project/lockfile.py +100 -0
- pythonnative/project/permissions.py +361 -0
- pythonnative/project/plugins.py +519 -0
- pythonnative/project/runtime_assets.py +183 -0
- pythonnative/py.typed +0 -0
- pythonnative/query.py +153 -0
- pythonnative/reconciler/__init__.py +29 -0
- pythonnative/reconciler/boundaries.py +375 -0
- pythonnative/reconciler/children.py +88 -0
- pythonnative/reconciler/core.py +1165 -0
- pythonnative/reconciler/layout_pass.py +393 -0
- pythonnative/reconciler/vnode.py +266 -0
- pythonnative/refresh.py +55 -0
- pythonnative/runtime.py +306 -0
- pythonnative/scheduler.py +159 -0
- pythonnative/sdk/__init__.py +153 -0
- pythonnative/sdk/_components.py +427 -0
- pythonnative/sdk/builtins.py +91 -0
- pythonnative/sdk/codegen.py +149 -0
- pythonnative/sdk/module_codegen.py +184 -0
- pythonnative/sdk/schema.py +224 -0
- pythonnative/sdk/templates/contracts.kt +46 -0
- pythonnative/sdk/templates/contracts.swift +46 -0
- pythonnative/storage.py +184 -0
- pythonnative/style.py +841 -0
- pythonnative/suspense.py +183 -0
- pythonnative/templates/android_template/app/build.gradle +75 -0
- pythonnative/templates/android_template/app/proguard-rules.pro +21 -0
- pythonnative/templates/android_template/app/src/androidTest/java/com/pythonnative/android_template/ExampleInstrumentedTest.kt +24 -0
- pythonnative/templates/android_template/app/src/debug/AndroidManifest.xml +7 -0
- pythonnative/templates/android_template/app/src/main/AndroidManifest.xml +32 -0
- pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/MainActivity.kt +130 -0
- pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/ScreenFragment.kt +13 -0
- pythonnative/templates/android_template/app/src/main/res/drawable/ic_launcher_background.xml +170 -0
- pythonnative/templates/android_template/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +30 -0
- pythonnative/templates/android_template/app/src/main/res/layout/activity_main.xml +10 -0
- pythonnative/templates/android_template/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +6 -0
- pythonnative/templates/android_template/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +6 -0
- pythonnative/templates/android_template/app/src/main/res/mipmap-hdpi/ic_launcher.webp +0 -0
- pythonnative/templates/android_template/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp +0 -0
- pythonnative/templates/android_template/app/src/main/res/mipmap-mdpi/ic_launcher.webp +0 -0
- pythonnative/templates/android_template/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp +0 -0
- pythonnative/templates/android_template/app/src/main/res/mipmap-xhdpi/ic_launcher.webp +0 -0
- pythonnative/templates/android_template/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp +0 -0
- pythonnative/templates/android_template/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp +0 -0
- pythonnative/templates/android_template/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp +0 -0
- pythonnative/templates/android_template/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp +0 -0
- pythonnative/templates/android_template/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp +0 -0
- pythonnative/templates/android_template/app/src/main/res/navigation/nav_graph.xml +22 -0
- pythonnative/templates/android_template/app/src/main/res/values/colors.xml +5 -0
- pythonnative/templates/android_template/app/src/main/res/values/strings.xml +5 -0
- pythonnative/templates/android_template/app/src/main/res/values/themes.xml +9 -0
- pythonnative/templates/android_template/app/src/main/res/values-night/themes.xml +7 -0
- pythonnative/templates/android_template/app/src/main/res/xml/backup_rules.xml +13 -0
- pythonnative/templates/android_template/app/src/main/res/xml/data_extraction_rules.xml +19 -0
- pythonnative/templates/android_template/app/src/test/java/com/pythonnative/android_template/ExampleUnitTest.kt +17 -0
- pythonnative/templates/android_template/build.gradle +10 -0
- pythonnative/templates/android_template/gradle/wrapper/gradle-wrapper.jar +0 -0
- pythonnative/templates/android_template/gradle/wrapper/gradle-wrapper.properties +6 -0
- pythonnative/templates/android_template/gradle.properties +23 -0
- pythonnative/templates/android_template/gradlew +185 -0
- pythonnative/templates/android_template/gradlew.bat +89 -0
- pythonnative/templates/android_template/settings.gradle +17 -0
- pythonnative/templates/ios_template/ios_template/AppDelegate.swift +51 -0
- pythonnative/templates/ios_template/ios_template/Assets.xcassets/AccentColor.colorset/Contents.json +11 -0
- pythonnative/templates/ios_template/ios_template/Assets.xcassets/AppIcon.appiconset/Contents.json +13 -0
- pythonnative/templates/ios_template/ios_template/Assets.xcassets/Contents.json +6 -0
- pythonnative/templates/ios_template/ios_template/Base.lproj/LaunchScreen.storyboard +25 -0
- pythonnative/templates/ios_template/ios_template/BridgingHeader.h +14 -0
- pythonnative/templates/ios_template/ios_template/Info.plist +28 -0
- pythonnative/templates/ios_template/ios_template/PythonRuntime.swift +390 -0
- pythonnative/templates/ios_template/ios_template/SceneDelegate.swift +61 -0
- pythonnative/templates/ios_template/ios_template/ViewController.swift +23 -0
- pythonnative/templates/ios_template/ios_template.xcodeproj/project.pbxproj +745 -0
- pythonnative/templates/ios_template/ios_template.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- pythonnative/templates/ios_template/ios_templateTests/ios_templateTests.swift +36 -0
- pythonnative/templates/ios_template/ios_templateUITests/ios_templateUITests.swift +41 -0
- pythonnative/templates/ios_template/ios_templateUITests/ios_templateUITestsLaunchTests.swift +32 -0
- pythonnative/testing/__init__.py +53 -0
- pythonnative/testing/backend.py +276 -0
- pythonnative/testing/harness.py +369 -0
- pythonnative/utils.py +145 -0
- pythonnative-0.40.0.dist-info/DELVEWHEEL +2 -0
- pythonnative-0.40.0.dist-info/METADATA +150 -0
- pythonnative-0.40.0.dist-info/RECORD +418 -0
- pythonnative-0.40.0.dist-info/WHEEL +5 -0
- pythonnative-0.40.0.dist-info/entry_points.txt +2 -0
- pythonnative-0.40.0.dist-info/licenses/LICENSE +21 -0
- pythonnative-0.40.0.dist-info/top_level.txt +1 -0
- pythonnative.libs/msvcp140-a4c2229bdc2a2a630acdc095b4d86008.dll +0 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//
|
|
2
|
+
// ios_templateTests.swift
|
|
3
|
+
// ios_templateTests
|
|
4
|
+
//
|
|
5
|
+
// Created by Owen Carey on 6/19/23.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import XCTest
|
|
9
|
+
@testable import ios_template
|
|
10
|
+
|
|
11
|
+
final class ios_templateTests: XCTestCase {
|
|
12
|
+
|
|
13
|
+
override func setUpWithError() throws {
|
|
14
|
+
// Put setup code here. This method is called before the invocation of each test method in the class.
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
override func tearDownWithError() throws {
|
|
18
|
+
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
func testExample() throws {
|
|
22
|
+
// This is an example of a functional test case.
|
|
23
|
+
// Use XCTAssert and related functions to verify your tests produce the correct results.
|
|
24
|
+
// Any test you write for XCTest can be annotated as throws and async.
|
|
25
|
+
// Mark your test throws to produce an unexpected failure when your test encounters an uncaught error.
|
|
26
|
+
// Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards.
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
func testPerformanceExample() throws {
|
|
30
|
+
// This is an example of a performance test case.
|
|
31
|
+
self.measure {
|
|
32
|
+
// Put the code you want to measure the time of here.
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
//
|
|
2
|
+
// ios_templateUITests.swift
|
|
3
|
+
// ios_templateUITests
|
|
4
|
+
//
|
|
5
|
+
// Created by Owen Carey on 6/19/23.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import XCTest
|
|
9
|
+
|
|
10
|
+
final class ios_templateUITests: XCTestCase {
|
|
11
|
+
|
|
12
|
+
override func setUpWithError() throws {
|
|
13
|
+
// Put setup code here. This method is called before the invocation of each test method in the class.
|
|
14
|
+
|
|
15
|
+
// In UI tests it is usually best to stop immediately when a failure occurs.
|
|
16
|
+
continueAfterFailure = false
|
|
17
|
+
|
|
18
|
+
// In UI tests it's important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
override func tearDownWithError() throws {
|
|
22
|
+
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
func testExample() throws {
|
|
26
|
+
// UI tests must launch the application that they test.
|
|
27
|
+
let app = XCUIApplication()
|
|
28
|
+
app.launch()
|
|
29
|
+
|
|
30
|
+
// Use XCTAssert and related functions to verify your tests produce the correct results.
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
func testLaunchPerformance() throws {
|
|
34
|
+
if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) {
|
|
35
|
+
// This measures how long it takes to launch your application.
|
|
36
|
+
measure(metrics: [XCTApplicationLaunchMetric()]) {
|
|
37
|
+
XCUIApplication().launch()
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//
|
|
2
|
+
// ios_templateUITestsLaunchTests.swift
|
|
3
|
+
// ios_templateUITests
|
|
4
|
+
//
|
|
5
|
+
// Created by Owen Carey on 6/19/23.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import XCTest
|
|
9
|
+
|
|
10
|
+
final class ios_templateUITestsLaunchTests: XCTestCase {
|
|
11
|
+
|
|
12
|
+
override class var runsForEachTargetApplicationUIConfiguration: Bool {
|
|
13
|
+
true
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
override func setUpWithError() throws {
|
|
17
|
+
continueAfterFailure = false
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
func testLaunch() throws {
|
|
21
|
+
let app = XCUIApplication()
|
|
22
|
+
app.launch()
|
|
23
|
+
|
|
24
|
+
// Insert steps here to perform after app launch but before taking a screenshot,
|
|
25
|
+
// such as logging into a test account or navigating somewhere in the app
|
|
26
|
+
|
|
27
|
+
let attachment = XCTAttachment(screenshot: app.screenshot())
|
|
28
|
+
attachment.name = "Launch Screen"
|
|
29
|
+
attachment.lifetime = .keepAlways
|
|
30
|
+
add(attachment)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""Test utilities: render components without a device.
|
|
2
|
+
|
|
3
|
+
```python
|
|
4
|
+
import pythonnative as pn
|
|
5
|
+
from pythonnative.testing import render, render_hook
|
|
6
|
+
|
|
7
|
+
@pn.component
|
|
8
|
+
def Counter():
|
|
9
|
+
count, set_count = pn.use_state(0)
|
|
10
|
+
return pn.Column(
|
|
11
|
+
pn.Text(f"Count: {count}"),
|
|
12
|
+
pn.Button("+", on_press=lambda: set_count(count + 1)),
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
def test_counter_increments():
|
|
16
|
+
result = render(Counter())
|
|
17
|
+
result.press(result.get_by_text("+"))
|
|
18
|
+
assert result.get_by_text("Count: 1")
|
|
19
|
+
|
|
20
|
+
def test_use_state():
|
|
21
|
+
hook = render_hook(lambda: pn.use_state("a"))
|
|
22
|
+
hook.act(lambda: hook.current[1]("b"))
|
|
23
|
+
assert hook.current[0] == "b"
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
- [`render`][pythonnative.testing.render] mounts an element into a
|
|
27
|
+
[`FakeBackend`][pythonnative.testing.FakeBackend] and returns a
|
|
28
|
+
[`RenderResult`][pythonnative.testing.RenderResult] with Testing
|
|
29
|
+
Library-style queries (``get_by_text``, ``get_by_test_id``,
|
|
30
|
+
``get_by_label``, ``get_by_type``) and event helpers (``press``,
|
|
31
|
+
``fire``, ``change_text``, ``back``).
|
|
32
|
+
- [`render_hook`][pythonnative.testing.render_hook] runs a hook in a
|
|
33
|
+
throwaway component.
|
|
34
|
+
- [`settle`][pythonnative.testing.settle] pumps the framework loop so
|
|
35
|
+
async work (resources, queries, transitions) completes.
|
|
36
|
+
- [`FakeHost`][pythonnative.testing.FakeHost] stands in for a native
|
|
37
|
+
screen host so root stack navigators can be tested.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
from .backend import DEFAULT_INTRINSIC, FakeBackend, FakeView
|
|
41
|
+
from .harness import FakeHost, HookResult, RenderResult, render, render_hook, settle
|
|
42
|
+
|
|
43
|
+
__all__ = [
|
|
44
|
+
"DEFAULT_INTRINSIC",
|
|
45
|
+
"FakeBackend",
|
|
46
|
+
"FakeHost",
|
|
47
|
+
"FakeView",
|
|
48
|
+
"HookResult",
|
|
49
|
+
"RenderResult",
|
|
50
|
+
"render",
|
|
51
|
+
"render_hook",
|
|
52
|
+
"settle",
|
|
53
|
+
]
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
"""In-memory backend implementing the batched mutation protocol.
|
|
2
|
+
|
|
3
|
+
[`FakeBackend`][pythonnative.testing.FakeBackend] speaks the same
|
|
4
|
+
protocol as the platform registries (``apply_mutations``,
|
|
5
|
+
``resolve_view``, ``measure_intrinsic``, ``command``, plus the animation
|
|
6
|
+
hooks) while keeping a real tree of
|
|
7
|
+
[`FakeView`][pythonnative.testing.FakeView] objects, so tests can assert
|
|
8
|
+
on structure, props, and frames without a device.
|
|
9
|
+
|
|
10
|
+
Unlike the production registries (which isolate per-op failures so a
|
|
11
|
+
bad prop can't desync a device), the fake **raises** on malformed
|
|
12
|
+
transactions (unknown tags, double destroys, inserting into a destroyed
|
|
13
|
+
parent) so reconciler bugs fail tests loudly.
|
|
14
|
+
|
|
15
|
+
Recorded op shapes (in ``FakeBackend.ops``):
|
|
16
|
+
|
|
17
|
+
- ``("create", type_name, view.id)``
|
|
18
|
+
- ``("update", type_name, view.id, tuple(sorted(changed_keys)))``
|
|
19
|
+
- ``("insert_child", parent.id, child.id, index)``
|
|
20
|
+
- ``("destroy", view.id)``
|
|
21
|
+
- ``("set_frame", view.id, x, y, w, h)``
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
from __future__ import annotations
|
|
25
|
+
|
|
26
|
+
from typing import Any, Dict, Iterator, List, Optional, Sequence, Tuple
|
|
27
|
+
|
|
28
|
+
from ..mutations import CreateOp, DestroyOp, InsertOp, Mutation, SetFrameOp, UpdateOp
|
|
29
|
+
|
|
30
|
+
__all__ = ["DEFAULT_INTRINSIC", "FakeBackend", "FakeView"]
|
|
31
|
+
|
|
32
|
+
DEFAULT_INTRINSIC: Dict[str, Tuple[float, float]] = {
|
|
33
|
+
"Text": (60.0, 16.0),
|
|
34
|
+
"Button": (80.0, 32.0),
|
|
35
|
+
"Image": (40.0, 40.0),
|
|
36
|
+
"TextInput": (120.0, 32.0),
|
|
37
|
+
"TabBar": (320.0, 49.0),
|
|
38
|
+
}
|
|
39
|
+
"""Intrinsic sizes reported for content-sized leaves (what platform measure hooks would return)."""
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class FakeView:
|
|
43
|
+
"""Simulated native view: type, props, children, and last frame.
|
|
44
|
+
|
|
45
|
+
Attributes:
|
|
46
|
+
tag: The reconciler-assigned tag (use with ``fire`` / events).
|
|
47
|
+
type_name: Native type, e.g. ``"Text"``.
|
|
48
|
+
props: Native-safe props (event callbacks are stripped; they
|
|
49
|
+
live in the event registry keyed by ``tag``).
|
|
50
|
+
children: Child views in order.
|
|
51
|
+
frame: ``(x, y, width, height)`` from the last layout pass.
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
_next_id = 0
|
|
55
|
+
|
|
56
|
+
def __init__(self, tag: int, type_name: str, props: Dict[str, Any]) -> None:
|
|
57
|
+
FakeView._next_id += 1
|
|
58
|
+
self.id = FakeView._next_id
|
|
59
|
+
self.tag = tag
|
|
60
|
+
self.type_name = type_name
|
|
61
|
+
self.props: Dict[str, Any] = dict(props)
|
|
62
|
+
self.children: List[FakeView] = []
|
|
63
|
+
self.parent: Optional[FakeView] = None
|
|
64
|
+
self.frame: Tuple[float, float, float, float] = (0.0, 0.0, 0.0, 0.0)
|
|
65
|
+
self.destroyed = False
|
|
66
|
+
|
|
67
|
+
def __repr__(self) -> str:
|
|
68
|
+
label = self.text
|
|
69
|
+
suffix = f" {label!r}" if label else ""
|
|
70
|
+
return f"<{self.type_name} tag={self.tag}{suffix}>"
|
|
71
|
+
|
|
72
|
+
# -- content --------------------------------------------------------
|
|
73
|
+
|
|
74
|
+
@property
|
|
75
|
+
def text(self) -> Optional[str]:
|
|
76
|
+
"""Visible text for text-bearing views (``Text.text``, ``Button.title``, ``TextInput.value``)."""
|
|
77
|
+
for key in ("text", "title", "value", "placeholder"):
|
|
78
|
+
value = self.props.get(key)
|
|
79
|
+
if isinstance(value, str):
|
|
80
|
+
return value
|
|
81
|
+
return None
|
|
82
|
+
|
|
83
|
+
@property
|
|
84
|
+
def hidden(self) -> bool:
|
|
85
|
+
"""Whether this view is removed from layout (``display: "none"``)."""
|
|
86
|
+
return self.props.get("display") == "none" or self.type_name == "Screen" and self.props.get("active") is False
|
|
87
|
+
|
|
88
|
+
@property
|
|
89
|
+
def test_id(self) -> Optional[str]:
|
|
90
|
+
"""The ``test_id`` prop, if set."""
|
|
91
|
+
return self.props.get("test_id")
|
|
92
|
+
|
|
93
|
+
@property
|
|
94
|
+
def label(self) -> Optional[str]:
|
|
95
|
+
"""The ``accessibility_label`` prop, if set."""
|
|
96
|
+
return self.props.get("accessibility_label")
|
|
97
|
+
|
|
98
|
+
# -- traversal ------------------------------------------------------
|
|
99
|
+
|
|
100
|
+
def walk(self, *, include_hidden: bool = True) -> Iterator["FakeView"]:
|
|
101
|
+
"""Yield this view and every descendant, depth-first.
|
|
102
|
+
|
|
103
|
+
With ``include_hidden=False`` subtrees under a ``display: "none"``
|
|
104
|
+
view are skipped (what a user can see).
|
|
105
|
+
"""
|
|
106
|
+
if not include_hidden and self.hidden:
|
|
107
|
+
return
|
|
108
|
+
yield self
|
|
109
|
+
for child in self.children:
|
|
110
|
+
yield from child.walk(include_hidden=include_hidden)
|
|
111
|
+
|
|
112
|
+
def find_all(self, predicate_or_type: Any) -> List["FakeView"]:
|
|
113
|
+
"""Every view in this subtree matching a type name or predicate."""
|
|
114
|
+
if isinstance(predicate_or_type, str):
|
|
115
|
+
wanted = predicate_or_type
|
|
116
|
+
|
|
117
|
+
def predicate(v: "FakeView") -> bool:
|
|
118
|
+
return v.type_name == wanted
|
|
119
|
+
|
|
120
|
+
else:
|
|
121
|
+
predicate = predicate_or_type
|
|
122
|
+
return [v for v in self.walk() if predicate(v)]
|
|
123
|
+
|
|
124
|
+
def find_first(self, predicate_or_type: Any) -> Optional["FakeView"]:
|
|
125
|
+
"""Return the first view in this subtree matching a type name or predicate, or ``None``."""
|
|
126
|
+
found = self.find_all(predicate_or_type)
|
|
127
|
+
return found[0] if found else None
|
|
128
|
+
|
|
129
|
+
def dump(self, indent: int = 0) -> str:
|
|
130
|
+
"""Indented, human-readable subtree (for failing-test output)."""
|
|
131
|
+
line = " " * indent + repr(self)
|
|
132
|
+
x, y, w, h = self.frame
|
|
133
|
+
if w or h:
|
|
134
|
+
line += f" @({x:g},{y:g} {w:g}x{h:g})"
|
|
135
|
+
return "\n".join([line, *(c.dump(indent + 2) for c in self.children)])
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class FakeBackend:
|
|
139
|
+
"""Tag-table backend recording one tuple per applied mutation.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
intrinsic: Override the intrinsic sizes used by
|
|
143
|
+
``measure_intrinsic`` (defaults to
|
|
144
|
+
[`DEFAULT_INTRINSIC`][pythonnative.testing.backend.DEFAULT_INTRINSIC]).
|
|
145
|
+
"""
|
|
146
|
+
|
|
147
|
+
def __init__(self, intrinsic: Optional[Dict[str, Tuple[float, float]]] = None) -> None:
|
|
148
|
+
self.intrinsic = dict(DEFAULT_INTRINSIC if intrinsic is None else intrinsic)
|
|
149
|
+
self.views: Dict[int, FakeView] = {}
|
|
150
|
+
self.ops: List[Any] = []
|
|
151
|
+
self.batches: List[List[Any]] = []
|
|
152
|
+
self.measure_calls: List[int] = []
|
|
153
|
+
self.commands: List[Tuple[int, str, Dict[str, Any]]] = []
|
|
154
|
+
self.animated: List[Tuple[int, str, Any]] = []
|
|
155
|
+
self.last_create_props: Dict[str, Any] = {}
|
|
156
|
+
self.last_update_changes: Dict[str, Any] = {}
|
|
157
|
+
|
|
158
|
+
# ------------------------------------------------------------------
|
|
159
|
+
# Commit channel
|
|
160
|
+
# ------------------------------------------------------------------
|
|
161
|
+
|
|
162
|
+
def apply_mutations(self, ops: Sequence[Mutation]) -> None:
|
|
163
|
+
"""Apply one committed batch to the view tree, recording each op in ``ops`` and ``batches``.
|
|
164
|
+
|
|
165
|
+
Raises ``AssertionError`` on malformed transactions (unknown tags, double creates or destroys).
|
|
166
|
+
"""
|
|
167
|
+
batch: List[Any] = []
|
|
168
|
+
for op in ops:
|
|
169
|
+
recorded = self._apply_one(op)
|
|
170
|
+
self.ops.append(recorded)
|
|
171
|
+
batch.append(recorded)
|
|
172
|
+
self.batches.append(batch)
|
|
173
|
+
|
|
174
|
+
def _apply_one(self, op: Mutation) -> Tuple[Any, ...]:
|
|
175
|
+
if isinstance(op, CreateOp):
|
|
176
|
+
if op.tag in self.views:
|
|
177
|
+
raise AssertionError(f"create: tag {op.tag} already registered")
|
|
178
|
+
view = FakeView(op.tag, op.type_name, op.props)
|
|
179
|
+
self.views[op.tag] = view
|
|
180
|
+
self.last_create_props = dict(op.props)
|
|
181
|
+
return ("create", op.type_name, view.id)
|
|
182
|
+
|
|
183
|
+
if isinstance(op, UpdateOp):
|
|
184
|
+
view = self._require(op.tag, "update")
|
|
185
|
+
view.props.update(op.changed_props)
|
|
186
|
+
self.last_update_changes = dict(op.changed_props)
|
|
187
|
+
return ("update", view.type_name, view.id, tuple(sorted(op.changed_props)))
|
|
188
|
+
|
|
189
|
+
if isinstance(op, InsertOp):
|
|
190
|
+
parent = self._require(op.parent_tag, "insert_child")
|
|
191
|
+
child = self._require(op.child_tag, "insert_child")
|
|
192
|
+
if child.parent is not None:
|
|
193
|
+
child.parent.children.remove(child)
|
|
194
|
+
child.parent = None
|
|
195
|
+
index = max(0, min(op.index, len(parent.children)))
|
|
196
|
+
parent.children.insert(index, child)
|
|
197
|
+
child.parent = parent
|
|
198
|
+
return ("insert_child", parent.id, child.id, index)
|
|
199
|
+
|
|
200
|
+
if isinstance(op, DestroyOp):
|
|
201
|
+
view = self.views.pop(op.tag, None)
|
|
202
|
+
if view is None:
|
|
203
|
+
raise AssertionError(f"destroy: unknown tag {op.tag}")
|
|
204
|
+
if view.parent is not None:
|
|
205
|
+
view.parent.children.remove(view)
|
|
206
|
+
view.parent = None
|
|
207
|
+
view.destroyed = True
|
|
208
|
+
return ("destroy", view.id)
|
|
209
|
+
|
|
210
|
+
if isinstance(op, SetFrameOp):
|
|
211
|
+
view = self._require(op.tag, "set_frame")
|
|
212
|
+
view.frame = (op.x, op.y, op.width, op.height)
|
|
213
|
+
return ("set_frame", view.id, op.x, op.y, op.width, op.height)
|
|
214
|
+
|
|
215
|
+
raise AssertionError(f"unknown mutation op: {op!r}")
|
|
216
|
+
|
|
217
|
+
def _require(self, tag: int, op_name: str) -> FakeView:
|
|
218
|
+
view = self.views.get(tag)
|
|
219
|
+
if view is None:
|
|
220
|
+
raise AssertionError(f"{op_name}: unknown tag {tag}")
|
|
221
|
+
return view
|
|
222
|
+
|
|
223
|
+
# ------------------------------------------------------------------
|
|
224
|
+
# Imperative escape hatches
|
|
225
|
+
# ------------------------------------------------------------------
|
|
226
|
+
|
|
227
|
+
def resolve_view(self, tag: int) -> Optional[FakeView]:
|
|
228
|
+
"""Return the live view registered under ``tag``, or ``None``."""
|
|
229
|
+
return self.views.get(tag)
|
|
230
|
+
|
|
231
|
+
def measure_intrinsic(self, tag: int, max_width: float, max_height: float) -> Tuple[float, float]:
|
|
232
|
+
"""Return the configured intrinsic size for the view's type and record the call in ``measure_calls``.
|
|
233
|
+
|
|
234
|
+
Unknown tags and types without an entry measure as ``(0.0, 0.0)``; the constraints are ignored.
|
|
235
|
+
"""
|
|
236
|
+
view = self.views.get(tag)
|
|
237
|
+
if view is None:
|
|
238
|
+
return (0.0, 0.0)
|
|
239
|
+
self.measure_calls.append(view.id)
|
|
240
|
+
return self.intrinsic.get(view.type_name, (0.0, 0.0))
|
|
241
|
+
|
|
242
|
+
def command(self, tag: int, name: str, args: Optional[Dict[str, Any]] = None) -> Any:
|
|
243
|
+
"""Record an imperative view command in ``commands`` and return ``None``."""
|
|
244
|
+
self.commands.append((tag, name, dict(args or {})))
|
|
245
|
+
return None
|
|
246
|
+
|
|
247
|
+
def set_animated_property(self, tag: int, prop_name: str, value: Any) -> None:
|
|
248
|
+
"""Record an animated property write in ``animated`` without touching ``props``."""
|
|
249
|
+
self.animated.append((tag, prop_name, value))
|
|
250
|
+
|
|
251
|
+
def start_animation(self, tag: int, anim_id: int, prop_name: str, spec: Dict[str, Any]) -> bool:
|
|
252
|
+
"""Decline native animation (return ``False``) so animations run through the Python driver."""
|
|
253
|
+
return False
|
|
254
|
+
|
|
255
|
+
def cancel_animation(self, tag: int, anim_id: int) -> Any:
|
|
256
|
+
"""Do nothing; the fake never starts native animations."""
|
|
257
|
+
return None
|
|
258
|
+
|
|
259
|
+
# ------------------------------------------------------------------
|
|
260
|
+
# Diagnostics
|
|
261
|
+
# ------------------------------------------------------------------
|
|
262
|
+
|
|
263
|
+
def live_view_count(self) -> int:
|
|
264
|
+
"""Return how many views are currently registered (created and not yet destroyed)."""
|
|
265
|
+
return len(self.views)
|
|
266
|
+
|
|
267
|
+
def ops_of(self, kind: str) -> List[Any]:
|
|
268
|
+
"""Every recorded op tuple whose first element is ``kind``."""
|
|
269
|
+
return [op for op in self.ops if op[0] == kind]
|
|
270
|
+
|
|
271
|
+
def detached_views(self, type_name: Optional[str] = None) -> List[FakeView]:
|
|
272
|
+
"""Live views never inserted into a parent (``Portal`` overlays, the root)."""
|
|
273
|
+
out = [v for v in self.views.values() if v.parent is None]
|
|
274
|
+
if type_name is not None:
|
|
275
|
+
out = [v for v in out if v.type_name == type_name]
|
|
276
|
+
return out
|