pythonnative 0.49.0__tar.gz → 0.50.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.49.0 → pythonnative-0.50.0}/.github/workflows/release.yml +80 -0
- {pythonnative-0.49.0/src/pythonnative.egg-info → pythonnative-0.50.0}/PKG-INFO +7 -5
- {pythonnative-0.49.0 → pythonnative-0.50.0}/README.md +5 -4
- {pythonnative-0.49.0 → pythonnative-0.50.0}/pyproject.toml +6 -2
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/__init__.py +1 -1
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/bootstrap.py +5 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/bridge/commits.py +1 -1
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/bridge/web.py +1 -0
- pythonnative-0.50.0/src/pythonnative/cli/keys.py +178 -0
- pythonnative-0.50.0/src/pythonnative/cli/launch.py +261 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/cli/pn.py +292 -130
- pythonnative-0.50.0/src/pythonnative/devclient.py +1452 -0
- pythonnative-0.50.0/src/pythonnative/devserver/compat.py +176 -0
- pythonnative-0.50.0/src/pythonnative/devserver/editor.py +95 -0
- pythonnative-0.50.0/src/pythonnative/devserver/hub.py +464 -0
- pythonnative-0.50.0/src/pythonnative/devserver/packages.py +226 -0
- pythonnative-0.50.0/src/pythonnative/devserver/qr.py +526 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/server.py +399 -30
- pythonnative-0.50.0/src/pythonnative/devserver/static/devsupport.js +358 -0
- pythonnative-0.50.0/src/pythonnative/devserver/static/devtools/connection.js +136 -0
- pythonnative-0.50.0/src/pythonnative/devserver/static/devtools/devtools.css +753 -0
- pythonnative-0.50.0/src/pythonnative/devserver/static/devtools/devtools.js +379 -0
- pythonnative-0.50.0/src/pythonnative/devserver/static/devtools/index.html +49 -0
- pythonnative-0.50.0/src/pythonnative/devserver/static/devtools/panels/components.js +610 -0
- pythonnative-0.50.0/src/pythonnative/devserver/static/devtools/panels/connect.js +166 -0
- pythonnative-0.50.0/src/pythonnative/devserver/static/devtools/panels/console.js +343 -0
- pythonnative-0.50.0/src/pythonnative/devserver/static/devtools/panels/network.js +306 -0
- pythonnative-0.50.0/src/pythonnative/devserver/static/devtools/panels/panel.js +50 -0
- pythonnative-0.50.0/src/pythonnative/devserver/static/devtools/panels/performance.js +435 -0
- pythonnative-0.50.0/src/pythonnative/devserver/static/devtools/panels/problems.js +175 -0
- pythonnative-0.50.0/src/pythonnative/devserver/static/devtools/report.js +134 -0
- pythonnative-0.50.0/src/pythonnative/devserver/static/devtools/tree.js +143 -0
- pythonnative-0.50.0/src/pythonnative/devserver/static/devtools/util.js +184 -0
- pythonnative-0.50.0/src/pythonnative/devserver/static/devtools/values.js +79 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/host.js +99 -14
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/index.html +2 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/preview.css +194 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/shell.js +7 -0
- pythonnative-0.50.0/src/pythonnative/devtools/__init__.py +16 -0
- pythonnative-0.50.0/src/pythonnative/devtools/agent.py +524 -0
- pythonnative-0.50.0/src/pythonnative/devtools/console.py +134 -0
- pythonnative-0.50.0/src/pythonnative/devtools/debugger.py +164 -0
- pythonnative-0.50.0/src/pythonnative/devtools/inspector.py +381 -0
- pythonnative-0.50.0/src/pythonnative/devtools/perf.py +194 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/diagnostics.py +67 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/element.py +4 -2
- pythonnative-0.50.0/src/pythonnative/errors.py +422 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/gestures.py +17 -17
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/hooks.py +7 -3
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/hosts/base.py +8 -5
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/hosts/native.py +14 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/hot_reload.py +18 -9
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/generated/NativeProps.kt +502 -502
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/generated/NativeValues.kt +22 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/generated/PNContracts.kt +3 -3
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/TransactionApplier.kt +18 -1
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/BuiltinModules.kt +13 -2
- pythonnative-0.50.0/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/DevSupportModule.kt +429 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/DeviceModules.kt +14 -3
- pythonnative-0.50.0/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/ErrorOverlay.kt +220 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/HostModule.kt +1 -1
- pythonnative-0.50.0/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/DevSupportRobolectricTest.kt +196 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Bridge/PNRegistry.swift +1 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Bridge/PNTransaction.swift +26 -1
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Generated/NativeProps.swift +502 -502
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Generated/NativeValues.swift +40 -1
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Generated/PNContracts.swift +3 -3
- pythonnative-0.50.0/src/pythonnative/native/ios/Sources/PythonNativeKit/Modules/DevSupportModule.swift +381 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Modules/HostModule.swift +1 -1
- pythonnative-0.50.0/src/pythonnative/native/ios/Sources/PythonNativeKit/Modules/PNErrorOverlay.swift +269 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Support/PNWindow.swift +28 -2
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNCommitTests.swift +30 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNModuleTests.swift +105 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native_modules/linking.py +20 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/net.py +99 -2
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/preview.py +134 -18
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/project/android.py +11 -4
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/project/builder.py +27 -6
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/project/bundle.py +3 -1
- pythonnative-0.50.0/src/pythonnative/project/go.py +383 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/project/ios.py +9 -2
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/reconciler/core.py +44 -3
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/sdk/_builtin_contracts.json +1 -1
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/sdk/codegen.py +2 -2
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/sdk/templates/contracts.kt +1 -1
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/sdk/templates/contracts.swift +1 -1
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/sdk/templates/values.kt +22 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/sdk/templates/values.swift +40 -1
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/MainActivity.kt +13 -10
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/ios_template/ios_template/SceneDelegate.swift +3 -1
- {pythonnative-0.49.0 → pythonnative-0.50.0/src/pythonnative.egg-info}/PKG-INFO +7 -5
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative.egg-info/SOURCES.txt +40 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative.egg-info/requires.txt +1 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_cli.py +44 -38
- pythonnative-0.50.0/tests/test_cli_keys.py +153 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_devclient.py +75 -34
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_devserver.py +20 -4
- pythonnative-0.50.0/tests/test_devserver_session.py +496 -0
- pythonnative-0.50.0/tests/test_devtools.py +300 -0
- pythonnative-0.50.0/tests/test_devtools_page.py +224 -0
- pythonnative-0.50.0/tests/test_errors.py +173 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_hosts.py +1 -1
- pythonnative-0.50.0/tests/test_qr.py +279 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_release_packaging.py +3 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_runtime_correctness.py +1 -1
- pythonnative-0.49.0/src/pythonnative/devclient.py +0 -869
- pythonnative-0.49.0/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/ErrorOverlay.kt +0 -42
- pythonnative-0.49.0/src/pythonnative/native/ios/Sources/PythonNativeKit/Modules/PNErrorOverlay.swift +0 -47
- {pythonnative-0.49.0 → pythonnative-0.50.0}/LICENSE +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/MANIFEST.in +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/scripts/check-distributions.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/scripts/cibuildwheel.toml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/scripts/release-assets.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/setup.cfg +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/setup.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/_ios_log.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/alerts.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/animated.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/animation_graph.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/appearance.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/assets/__init__.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/assets/fonts.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/bridge/__init__.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/bridge/android.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/bridge/codec.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/bridge/fake.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/bridge/ios.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/bridge/list_store.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/cli/__init__.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/component.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/components/__init__.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/components/_base.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/components/controls.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/components/events.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/components/graphics.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/components/layout.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/components/lists.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/components/media.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/components/overlays.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/components/pressable.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/components/props.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/components/structural.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/components/text.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/__init__.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/auth.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/animation_graph.js +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/assets.js +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/bridge.js +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/colors.js +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/contracts.js +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/layout.js +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/list-store.js +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/renderer.js +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/yoga/LICENSE +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/yoga/binaries/yoga-wasm-base64-esm.js +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/yoga/src/generated/YGEnums.d.ts +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/yoga/src/generated/YGEnums.js +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/yoga/src/generated/YGEnums.js.map +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/yoga/src/index.d.ts +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/yoga/src/index.js +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/yoga/src/index.js.map +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/yoga/src/load.d.ts +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/yoga/src/load.js +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/yoga/src/load.js.map +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/yoga/src/wrapAssembly.d.ts +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/yoga/src/wrapAssembly.js +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/static/yoga/src/wrapAssembly.js.map +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/watcher.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/devserver/ws.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/equality.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/events.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/handles.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/hosts/__init__.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/icons/LICENSE-lucide.txt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/icons/__init__.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/icons/_lucide.json +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/icons/_names.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/journal.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/layout.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/lint.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/list_data.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/mutations.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/build.gradle +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/gradle.properties +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/settings.gradle +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/AndroidManifest.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/cpp/CMakeLists.txt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/cpp/yoga_jni.cpp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/generated/NativeModules.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/PNBridge.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/PythonHost.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/animation/AnimationGraph.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/animation/AnimationSpecs.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/animation/PNAnimator.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/assets/PNAssets.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/CommitState.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/JsonUtil.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/MainThread.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/PNLog.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/PNRegistry.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/PNTransaction.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/bridge/ViewRegistry.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/BuiltinComponents.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ButtonManager.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ComponentManager.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ContainerManagers.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ControlManagers.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/DatePickerManager.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/EffectManagers.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ImageLoader.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ImageManager.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ListStore.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ModalManager.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/PNColor.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/PNTheme.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/PickerManager.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/PortalManager.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/PressableManager.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ScreenStackManager.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ScreenTransitions.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ScrollViewManager.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/SegmentedControlManager.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/StatusBarManager.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/SvgManager.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/TabBarManager.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/TextInputManager.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/TextManager.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/ViewStyler.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/VirtualListManager.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/components/WebViewManager.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/gestures/GestureArbiter.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/gestures/GestureCoordinator.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/gestures/GestureRecognizers.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/graphics/SvgPath.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/layout/NativeLayout.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/layout/YogaNode.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/AssetModules.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/MediaModules.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/NativeModule.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/NotificationsModule.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/PermissionsModule.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/PlatformModules.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/StorageModules.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/modules/SystemModules.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/plugins/GeneratedPlugins.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/screens/PNKeyboard.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/screens/PNScreenFragment.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/screens/ScreenRegistry.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/views/PNAccessibilityDelegate.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/views/PNBorderDrawable.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/views/PNEditText.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/views/PNFrameLayout.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/java/com/pythonnative/runtime/views/PNScrollViews.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/res/anim/pn_fade_in.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/res/anim/pn_fade_out.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/res/anim/pn_hold.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/res/anim/pn_slide_in_bottom.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/res/anim/pn_slide_in_left.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/res/anim/pn_slide_in_right.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/res/anim/pn_slide_out_bottom.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/res/anim/pn_slide_out_left.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/res/anim/pn_slide_out_right.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/res/drawable/pn_ic_arrow_back.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/res/values/pn_ids.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/main/res/xml/pn_file_paths.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/generated/PNRecordFixtures.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/AnimationSpecsTest.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/AssetsAndSvgTest.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/ContractFixtureTest.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/GestureArbiterTest.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/NativeLifecycleTest.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/PNColorTest.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/PNTransactionTest.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/PromiseTest.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/RoundOneRobolectricTest.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/RoundTwoLogicTest.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/RoundTwoRobolectricTest.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/ScreenTransitionsTest.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/android/src/test/java/com/pythonnative/runtime/StyleAccessibilityDeviceTest.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Package.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Animation/PNAnimationGraph.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Animation/PNAnimator.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Bridge/PNBridge.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Bridge/PNCommit.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Bridge/PNViewRegistry.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNButtonManagers.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNColor.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNComponentManager.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNContainerView.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNControlManagers.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNEffectManagers.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNImageManager.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNListStore.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNOverlayManagers.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNPressableManager.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNScreenStackManager.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNScrollViewManager.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNSvgManager.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNTabBarManager.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNTextInputManager.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNTextManager.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNTransform.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNViewManager.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNViewState.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNViewStyler.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNVirtualListManager.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Components/PNWebViewManager.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Generated/NativeModules.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Gestures/PNGestureCoordinator.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Layout/PNLayout.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Modules/AlertModule.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Modules/EnvironmentModules.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Modules/ImagesModule.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Modules/LifecycleModules.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Modules/MediaModules.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Modules/PNNativeModule.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Modules/PermissionModules.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Modules/SystemModules.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Plugins/PNPluginRegistration.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Resources/PrivacyInfo.xcprivacy +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Screens/PNScreenRegistry.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Screens/PNViewController.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Support/PNAssets.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Support/PNCompat.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Support/PNJSON.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Sources/PythonNativeKit/Support/PNLog.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Tests/NativeTests.xcodeproj/project.pbxproj +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Tests/NativeTests.xcodeproj/xcshareddata/xcschemes/NativeTests.xcscheme +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/Fixtures/validation.json +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNAnimationGraphTests.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNAssetTests.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNColorTests.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNContractFixtureTests.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNContractParityTests.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNGestureTests.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNLifecycleTests.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNManagerTests.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNParityTests.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNRecordFixtures.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Tests/PythonNativeKitTests/PNTransactionTests.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/ios/Tests/TestHost/main.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/LICENSE +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/Package.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/VENDORED.md +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/include/PNStyle.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/include/module.modulemap +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/include/yoga/YGConfig.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/include/yoga/YGEnums.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/include/yoga/YGMacros.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/include/yoga/YGNode.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/include/yoga/YGNodeLayout.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/include/yoga/YGNodeStyle.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/include/yoga/YGPixelGrid.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/include/yoga/YGValue.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/include/yoga/Yoga.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/python.cpp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/style.cpp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/CMakeLists.txt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/YGConfig.cpp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/YGConfig.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/YGEnums.cpp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/YGEnums.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/YGMacros.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/YGNode.cpp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/YGNode.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/YGNodeLayout.cpp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/YGNodeLayout.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/YGNodeStyle.cpp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/YGNodeStyle.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/YGPixelGrid.cpp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/YGPixelGrid.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/YGValue.cpp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/YGValue.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/Yoga.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/algorithm/AbsoluteLayout.cpp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/algorithm/AbsoluteLayout.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/algorithm/Align.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/algorithm/Baseline.cpp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/algorithm/Baseline.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/algorithm/BoundAxis.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/algorithm/Cache.cpp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/algorithm/Cache.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/algorithm/CalculateLayout.cpp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/algorithm/CalculateLayout.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/algorithm/FlexDirection.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/algorithm/FlexLine.cpp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/algorithm/FlexLine.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/algorithm/PixelGrid.cpp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/algorithm/PixelGrid.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/algorithm/SizingMode.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/algorithm/TrailingPosition.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/config/Config.cpp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/config/Config.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/debug/AssertFatal.cpp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/debug/AssertFatal.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/debug/Log.cpp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/debug/Log.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/enums/Align.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/enums/BoxSizing.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/enums/Dimension.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/enums/Direction.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/enums/Display.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/enums/Edge.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/enums/Errata.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/enums/ExperimentalFeature.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/enums/FlexDirection.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/enums/Gutter.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/enums/Justify.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/enums/LogLevel.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/enums/MeasureMode.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/enums/NodeType.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/enums/Overflow.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/enums/PhysicalEdge.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/enums/PositionType.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/enums/Unit.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/enums/Wrap.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/enums/YogaEnums.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/event/event.cpp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/event/event.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/module.modulemap +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/node/CachedMeasurement.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/node/LayoutResults.cpp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/node/LayoutResults.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/node/LayoutableChildren.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/node/Node.cpp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/node/Node.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/numeric/Comparison.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/numeric/FloatOptional.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/style/SmallValueBuffer.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/style/Style.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/style/StyleLength.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/style/StyleValueHandle.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native/yoga/yoga/style/StyleValuePool.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native_modules/__init__.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native_modules/accessibility_info.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native_modules/app_state.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native_modules/battery.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native_modules/biometrics.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native_modules/camera.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native_modules/clipboard.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native_modules/device.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native_modules/dimensions.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native_modules/fallback.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native_modules/file_system.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native_modules/haptics.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native_modules/images.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native_modules/keyboard.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native_modules/localization.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native_modules/location.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native_modules/net_info.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native_modules/notifications.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native_modules/permissions.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native_modules/registry.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native_modules/secure_store.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native_modules/share.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native_views/__init__.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/native_views/bridge_backend.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/navigation/__init__.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/navigation/container.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/navigation/handle.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/navigation/hooks.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/navigation/host.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/navigation/linking.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/navigation/navigators.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/navigation/ref.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/navigation/screen.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/navigation/state.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/platform.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/platform_metrics.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/profiling.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/project/__init__.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/project/artifacts.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/project/bytecode.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/project/config.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/project/deps.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/project/devices.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/project/doctor.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/project/fingerprint.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/project/icons.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/project/lockfile.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/project/permissions.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/project/plugins.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/project/runtime_assets.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/prop_checks.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/py.typed +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/query.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/reconciler/__init__.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/reconciler/boundaries.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/reconciler/children.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/reconciler/layout_pass.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/reconciler/vnode.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/refresh.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/runtime.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/scheduler.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/sdk/__init__.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/sdk/_components.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/sdk/builtins.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/sdk/commands.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/sdk/contract_codegen.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/sdk/module_codegen.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/sdk/native_types.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/sdk/schema.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/sdk/services.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/sdk/types.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/storage.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/store.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/style.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/suspense.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/svg.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/build.gradle +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/proguard-rules.pro +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/debug/AndroidManifest.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/main/AndroidManifest.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/ScreenFragment.kt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/main/res/drawable/ic_launcher_background.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/main/res/layout/activity_main.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-hdpi/ic_launcher.webp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-mdpi/ic_launcher.webp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xhdpi/ic_launcher.webp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/main/res/navigation/nav_graph.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/main/res/values/colors.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/main/res/values/strings.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/main/res/values/themes.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/main/res/values-night/themes.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/main/res/xml/backup_rules.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/app/src/main/res/xml/data_extraction_rules.xml +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/build.gradle +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/gradle/wrapper/gradle-wrapper.jar +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/gradle/wrapper/gradle-wrapper.properties +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/gradle.properties +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/gradlew +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/gradlew.bat +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/android_template/settings.gradle +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/ios_template/PNFinalizePython.sh +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/ios_template/ios_template/AppDelegate.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/ios_template/ios_template/Assets.xcassets/AccentColor.colorset/Contents.json +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/ios_template/ios_template/Assets.xcassets/AppIcon.appiconset/Contents.json +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/ios_template/ios_template/Assets.xcassets/Contents.json +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/ios_template/ios_template/Base.lproj/LaunchScreen.storyboard +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/ios_template/ios_template/BridgingHeader.h +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/ios_template/ios_template/Info.plist +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/ios_template/ios_template/PrivacyInfo.xcprivacy +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/ios_template/ios_template/PythonRuntime.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/ios_template/ios_template/ViewController.swift +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/ios_template/ios_template.xcodeproj/project.pbxproj +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/templates/ios_template/ios_template.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/testing/__init__.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/testing/backend.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/testing/clock.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/testing/harness.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/testing/pytest_plugin.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/testing/queries.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/theme.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative/utils.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative.egg-info/dependency_links.txt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative.egg-info/entry_points.txt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/src/pythonnative.egg-info/top_level.txt +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_alert.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_animated.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_animated_easing.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_animated_graph.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_appearance.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_assets.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_async_hooks.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_authoring.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_bridge.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_codegen.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_components.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_contract_fixtures.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_core_semantics.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_device_modules.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_devserver_ws.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_e2e_suite_renders.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_element.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_events.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_extended_components.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_gesture_activation.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_gesture_composition.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_gestures.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_handles.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_hooks.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_hot_reload.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_identity_bailout.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_inbox.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_incremental_pipeline.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_incremental_render.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_interaction_props.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_ios_log.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_layout.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_lint.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_list_features.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_metric_hooks.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_mutations.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_native_lists.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_native_modules.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_native_values.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_native_views.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_navigation.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_net.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_new_components.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_performance_budgets.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_platform.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_platform_metrics.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_reconciler.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_ref.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_release_workflow.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_runtime.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_runtime_contracts.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_runtime_overhaul.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_sdk.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_smoke.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_storage.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_store.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_style.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_suspense.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_testing_library.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_theme.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_transitions.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_typed_events.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_typing_conformance.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_utils.py +0 -0
- {pythonnative-0.49.0 → pythonnative-0.50.0}/tests/test_web_transport.py +0 -0
|
@@ -113,3 +113,83 @@ jobs:
|
|
|
113
113
|
uses: pypa/gh-action-pypi-publish@release/v1
|
|
114
114
|
with:
|
|
115
115
|
skip-existing: true
|
|
116
|
+
|
|
117
|
+
# PythonNative Go, the prebuilt dev client, ships as release assets that
|
|
118
|
+
# `pn go` downloads for the matching version (RFC 0006). Its builds run
|
|
119
|
+
# after PyPI publishing so a toolchain hiccup never blocks the package.
|
|
120
|
+
go:
|
|
121
|
+
name: Build PythonNative Go (${{ matrix.name }})
|
|
122
|
+
needs: [release, publish]
|
|
123
|
+
if: needs.release.outputs.tag != '' && needs.release.outputs.commit != ''
|
|
124
|
+
strategy:
|
|
125
|
+
fail-fast: false
|
|
126
|
+
matrix:
|
|
127
|
+
# The simulator app's Python runtime is staged for one architecture,
|
|
128
|
+
# so each Mac architecture gets its own asset, built on a runner of
|
|
129
|
+
# that architecture (`pn go` downloads the one matching the Mac).
|
|
130
|
+
include:
|
|
131
|
+
- name: ios-arm64
|
|
132
|
+
platform: ios
|
|
133
|
+
runner: macos-15
|
|
134
|
+
- name: ios-x86_64
|
|
135
|
+
platform: ios
|
|
136
|
+
runner: macos-15-intel
|
|
137
|
+
- name: android
|
|
138
|
+
platform: android
|
|
139
|
+
runner: ubuntu-24.04
|
|
140
|
+
runs-on: ${{ matrix.runner }}
|
|
141
|
+
env:
|
|
142
|
+
DEVELOPER_DIR: /Applications/Xcode_26.3.app/Contents/Developer
|
|
143
|
+
timeout-minutes: 45
|
|
144
|
+
steps:
|
|
145
|
+
- uses: actions/checkout@v4
|
|
146
|
+
with:
|
|
147
|
+
ref: ${{ needs.release.outputs.commit }}
|
|
148
|
+
- uses: astral-sh/setup-uv@v10.0.1
|
|
149
|
+
with:
|
|
150
|
+
enable-cache: true
|
|
151
|
+
python-version: '3.13'
|
|
152
|
+
- name: Set up Java 17
|
|
153
|
+
if: matrix.platform == 'android'
|
|
154
|
+
uses: actions/setup-java@v4
|
|
155
|
+
with:
|
|
156
|
+
distribution: 'temurin'
|
|
157
|
+
java-version: '17'
|
|
158
|
+
- name: Set up Gradle
|
|
159
|
+
if: matrix.platform == 'android'
|
|
160
|
+
uses: gradle/actions/setup-gradle@v4
|
|
161
|
+
- name: Install PythonNative
|
|
162
|
+
run: uv sync --locked
|
|
163
|
+
- name: Build and package
|
|
164
|
+
run: uv run python scripts/build-go.py --platform ${{ matrix.platform }} --out go-dist
|
|
165
|
+
- uses: actions/upload-artifact@v4
|
|
166
|
+
with:
|
|
167
|
+
name: go-${{ matrix.name }}
|
|
168
|
+
path: go-dist/
|
|
169
|
+
if-no-files-found: error
|
|
170
|
+
|
|
171
|
+
go-assets:
|
|
172
|
+
name: Attach PythonNative Go to the release
|
|
173
|
+
needs: [release, go]
|
|
174
|
+
runs-on: ubuntu-24.04
|
|
175
|
+
permissions:
|
|
176
|
+
contents: write
|
|
177
|
+
steps:
|
|
178
|
+
- uses: actions/checkout@v4
|
|
179
|
+
with:
|
|
180
|
+
ref: ${{ needs.release.outputs.commit }}
|
|
181
|
+
- uses: actions/download-artifact@v4
|
|
182
|
+
with:
|
|
183
|
+
pattern: go-*
|
|
184
|
+
path: go-dist
|
|
185
|
+
merge-multiple: true
|
|
186
|
+
- uses: astral-sh/setup-uv@v10.0.1
|
|
187
|
+
with:
|
|
188
|
+
python-version: '3.13'
|
|
189
|
+
- name: Write checksums
|
|
190
|
+
run: uv run python scripts/build-go.py --checksums go-dist
|
|
191
|
+
- name: Upload
|
|
192
|
+
env:
|
|
193
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
194
|
+
RELEASE_TAG: ${{ needs.release.outputs.tag }}
|
|
195
|
+
run: gh release upload "$RELEASE_TAG" go-dist/* --clobber
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pythonnative
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.50.0
|
|
4
4
|
Summary: Cross-platform native UI toolkit for Android and iOS
|
|
5
5
|
Author: Owen Carey
|
|
6
6
|
License: MIT License
|
|
@@ -40,6 +40,7 @@ Classifier: Topic :: Software Development :: User Interfaces
|
|
|
40
40
|
Requires-Python: >=3.13
|
|
41
41
|
Description-Content-Type: text/markdown
|
|
42
42
|
License-File: LICENSE
|
|
43
|
+
Requires-Dist: debugpy>=1.8
|
|
43
44
|
Provides-Extra: build
|
|
44
45
|
Requires-Dist: Pillow>=10.0; extra == "build"
|
|
45
46
|
Dynamic: license-file
|
|
@@ -88,7 +89,9 @@ PythonNative is a cross-platform toolkit for building native Android and iOS app
|
|
|
88
89
|
- **Device APIs:** Python facades expose camera, location, notifications, storage, permissions, keyboard, dimensions and pixel ratio, device info, localization, accessibility settings, and other native services, with a Python fallback for headless tests. Test permissions and platform behavior on your deployment targets.
|
|
89
90
|
- **Native extension SDK:** Python dataclasses and protocols define contracts; `define_component` returns a typed element factory and `pn codegen` generates props and module adapters for Swift and Kotlin. Plugins package native sources and resources, and builds verify matching contracts at startup.
|
|
90
91
|
- **Testing library:** `pythonnative.testing` renders components headlessly with Testing Library-style queries (`get_by_role`, `get_by_placeholder_text`, `within`, `find_by_*`), a virtual clock for timers, and a pytest plugin that resets the runtime between tests.
|
|
91
|
-
- **
|
|
92
|
+
- **PythonNative Go:** a prebuilt dev client, published with each release, runs any project without native code, so the project itself is never compiled. `i` / `a` in `pn start` open it on the iOS Simulator (which still needs Xcode installed) or an Android emulator, and a phone with Go installed opens the project by scanning the QR code `pn start` prints. Go isn't in the app stores: Android phones install the APK, and iPhones need Go built and signed with your Apple team. Projects that add native code run in their own debug build, which `pn run` rebuilds only when something native changes.
|
|
93
|
+
- **DevTools and debugging:** `pn start` serves DevTools, with a component tree showing props and hooks (and editable state), a console with a REPL inside the running app, problems with component stacks and source excerpts, network requests, and live performance with trace capture. VS Code attaches `debugpy` breakpoints to Python on the preview, a simulator, or a phone. On device, a dev menu (shake or Cmd+D) offers reload, an element inspector, and a performance monitor, and errors show a screen with the component stack and your source.
|
|
94
|
+
- **Development tools:** Fast Refresh preserves compatible component state, `pn lint` checks the rules of hooks, and `pn init` scaffolds tests, type checking, debugger settings, and CI.
|
|
92
95
|
- **Browser preview:** `pn preview` runs your Python application against a browser renderer with DOM widgets, Yoga WebAssembly layout, and JavaScript animation graphs. It supports iteration on application logic and UI; fonts, platform controls, and device APIs require mobile testing.
|
|
93
96
|
- **App packaging and dependency locks:** `pn run` and `pn build` stage bundled app templates, native libraries, and Python sources. Target-specific wheel locks record dependency versions and hashes for mobile builds. Binary dependencies need compatible mobile wheels; `pn deps` reports target resolution.
|
|
94
97
|
|
|
@@ -125,9 +128,8 @@ def App() -> pn.Node:
|
|
|
125
128
|
|
|
126
129
|
```bash
|
|
127
130
|
pn init my-app && cd my-app
|
|
128
|
-
pn
|
|
129
|
-
pn run ios #
|
|
130
|
-
pn run android
|
|
131
|
+
pn start # dev server: scan the QR code, or press i (iOS), a (Android), w (browser), j (DevTools)
|
|
132
|
+
pn run ios # the project's own debug build, for projects that add native code
|
|
131
133
|
pn build ios # standalone release artifacts
|
|
132
134
|
```
|
|
133
135
|
|
|
@@ -42,7 +42,9 @@ PythonNative is a cross-platform toolkit for building native Android and iOS app
|
|
|
42
42
|
- **Device APIs:** Python facades expose camera, location, notifications, storage, permissions, keyboard, dimensions and pixel ratio, device info, localization, accessibility settings, and other native services, with a Python fallback for headless tests. Test permissions and platform behavior on your deployment targets.
|
|
43
43
|
- **Native extension SDK:** Python dataclasses and protocols define contracts; `define_component` returns a typed element factory and `pn codegen` generates props and module adapters for Swift and Kotlin. Plugins package native sources and resources, and builds verify matching contracts at startup.
|
|
44
44
|
- **Testing library:** `pythonnative.testing` renders components headlessly with Testing Library-style queries (`get_by_role`, `get_by_placeholder_text`, `within`, `find_by_*`), a virtual clock for timers, and a pytest plugin that resets the runtime between tests.
|
|
45
|
-
- **
|
|
45
|
+
- **PythonNative Go:** a prebuilt dev client, published with each release, runs any project without native code, so the project itself is never compiled. `i` / `a` in `pn start` open it on the iOS Simulator (which still needs Xcode installed) or an Android emulator, and a phone with Go installed opens the project by scanning the QR code `pn start` prints. Go isn't in the app stores: Android phones install the APK, and iPhones need Go built and signed with your Apple team. Projects that add native code run in their own debug build, which `pn run` rebuilds only when something native changes.
|
|
46
|
+
- **DevTools and debugging:** `pn start` serves DevTools, with a component tree showing props and hooks (and editable state), a console with a REPL inside the running app, problems with component stacks and source excerpts, network requests, and live performance with trace capture. VS Code attaches `debugpy` breakpoints to Python on the preview, a simulator, or a phone. On device, a dev menu (shake or Cmd+D) offers reload, an element inspector, and a performance monitor, and errors show a screen with the component stack and your source.
|
|
47
|
+
- **Development tools:** Fast Refresh preserves compatible component state, `pn lint` checks the rules of hooks, and `pn init` scaffolds tests, type checking, debugger settings, and CI.
|
|
46
48
|
- **Browser preview:** `pn preview` runs your Python application against a browser renderer with DOM widgets, Yoga WebAssembly layout, and JavaScript animation graphs. It supports iteration on application logic and UI; fonts, platform controls, and device APIs require mobile testing.
|
|
47
49
|
- **App packaging and dependency locks:** `pn run` and `pn build` stage bundled app templates, native libraries, and Python sources. Target-specific wheel locks record dependency versions and hashes for mobile builds. Binary dependencies need compatible mobile wheels; `pn deps` reports target resolution.
|
|
48
50
|
|
|
@@ -79,9 +81,8 @@ def App() -> pn.Node:
|
|
|
79
81
|
|
|
80
82
|
```bash
|
|
81
83
|
pn init my-app && cd my-app
|
|
82
|
-
pn
|
|
83
|
-
pn run ios #
|
|
84
|
-
pn run android
|
|
84
|
+
pn start # dev server: scan the QR code, or press i (iOS), a (Android), w (browser), j (DevTools)
|
|
85
|
+
pn run ios # the project's own debug build, for projects that add native code
|
|
85
86
|
pn build ios # standalone release artifacts
|
|
86
87
|
```
|
|
87
88
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pythonnative"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.50.0"
|
|
8
8
|
description = "Cross-platform native UI toolkit for Android and iOS"
|
|
9
9
|
authors = [
|
|
10
10
|
{ name = "Owen Carey" }
|
|
@@ -26,7 +26,11 @@ classifiers = [
|
|
|
26
26
|
"Programming Language :: Python :: 3.14",
|
|
27
27
|
"Topic :: Software Development :: User Interfaces",
|
|
28
28
|
]
|
|
29
|
-
|
|
29
|
+
# debugpy is development tooling: `pn start` syncs its sources to dev
|
|
30
|
+
# clients for breakpoint debugging (RFC 0006). App bundles never include it.
|
|
31
|
+
dependencies = [
|
|
32
|
+
"debugpy>=1.8",
|
|
33
|
+
]
|
|
30
34
|
|
|
31
35
|
[project.optional-dependencies]
|
|
32
36
|
build = [
|
|
@@ -88,6 +88,11 @@ def start(dev: bool = False, strict: bool = False, entry: Optional[str] = None)
|
|
|
88
88
|
|
|
89
89
|
client = devclient.start_if_configured()
|
|
90
90
|
status_["dev_server"] = client.server_label if client is not None else None
|
|
91
|
+
if client is None:
|
|
92
|
+
# No server yet: the dev menu, inspector, and performance
|
|
93
|
+
# monitor still work locally; a connection replaces this
|
|
94
|
+
# agent with one that reports to DevTools.
|
|
95
|
+
devclient.install_local_agent()
|
|
91
96
|
# An overlay from the last session may already hold assets the
|
|
92
97
|
# bundle doesn't; point the native resolver at it right away.
|
|
93
98
|
from .assets import configure_native
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"""Single-key commands for ``pn start``, like Metro's terminal UI.
|
|
2
|
+
|
|
3
|
+
When stdin is a terminal, ``pn start`` reads keys without waiting for
|
|
4
|
+
Enter. [`KeyCommands.handle`][pythonnative.cli.keys.KeyCommands.handle]
|
|
5
|
+
maps each key to an action; it's separate from the terminal handling so it
|
|
6
|
+
can be tested without one.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import os
|
|
12
|
+
import subprocess
|
|
13
|
+
import sys
|
|
14
|
+
import threading
|
|
15
|
+
import webbrowser
|
|
16
|
+
from typing import Any, Callable, Dict, List, Optional, Tuple
|
|
17
|
+
|
|
18
|
+
__all__ = ["HELP", "KeyCommands", "read_keys"]
|
|
19
|
+
|
|
20
|
+
Logger = Callable[[str], None]
|
|
21
|
+
|
|
22
|
+
HELP: List[Tuple[str, str]] = [
|
|
23
|
+
("i", "open on the iOS Simulator (in PythonNative Go when the project can run there)"),
|
|
24
|
+
("a", "open on an Android emulator or device (in PythonNative Go when possible)"),
|
|
25
|
+
("I / A", "build and run the project's own development app"),
|
|
26
|
+
("w", "open the browser preview"),
|
|
27
|
+
("j", "open DevTools"),
|
|
28
|
+
("r", "reload every connected app"),
|
|
29
|
+
("m", "open the dev menu on every connected device"),
|
|
30
|
+
("d", "show how to attach a debugger"),
|
|
31
|
+
("c", "clear the terminal"),
|
|
32
|
+
("?", "show these commands"),
|
|
33
|
+
("q", "quit"),
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
LAUNCH_CONFIG = """{
|
|
37
|
+
"name": "PythonNative: Attach",
|
|
38
|
+
"type": "debugpy",
|
|
39
|
+
"request": "attach",
|
|
40
|
+
"connect": {"host": "127.0.0.1", "port": %d},
|
|
41
|
+
"justMyCode": true
|
|
42
|
+
}"""
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class KeyCommands:
|
|
46
|
+
"""Turn keys into dev-server actions.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
session: The running ``PreviewSession``.
|
|
50
|
+
port: The dev server's port (passed to ``pn go`` and ``pn run``).
|
|
51
|
+
log: Terminal logger.
|
|
52
|
+
stop: Called by ``q``.
|
|
53
|
+
spawn: Runs a ``pn`` subcommand in the background (tests replace it).
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
def __init__(
|
|
57
|
+
self,
|
|
58
|
+
session: Any,
|
|
59
|
+
port: int,
|
|
60
|
+
log: Logger,
|
|
61
|
+
stop: Callable[[], None],
|
|
62
|
+
spawn: Optional[Callable[[List[str]], None]] = None,
|
|
63
|
+
) -> None:
|
|
64
|
+
self.session = session
|
|
65
|
+
self.port = port
|
|
66
|
+
self.log = log
|
|
67
|
+
self.stop = stop
|
|
68
|
+
self.spawn = spawn or self._spawn
|
|
69
|
+
self._running: Dict[str, subprocess.Popen[bytes]] = {}
|
|
70
|
+
|
|
71
|
+
def help_lines(self) -> List[str]:
|
|
72
|
+
"""The command list, aligned."""
|
|
73
|
+
return [f" {key:<6} {text}" for key, text in HELP]
|
|
74
|
+
|
|
75
|
+
def handle(self, key: str) -> bool:
|
|
76
|
+
"""Run the action for ``key``; returns ``False`` once the server should stop."""
|
|
77
|
+
server = self.session.server
|
|
78
|
+
if key in ("i", "a", "I", "A"):
|
|
79
|
+
platform = "ios" if key.lower() == "i" else "android"
|
|
80
|
+
use_go = key.islower() and self._go_compatible()
|
|
81
|
+
command = ["go" if use_go else "run", platform, "--port", str(self.port)]
|
|
82
|
+
if not use_go:
|
|
83
|
+
command.append("--no-logs")
|
|
84
|
+
what = "PythonNative Go" if use_go else "the project's development app"
|
|
85
|
+
self.log(f"[pn] opening {what} on {'iOS' if platform == 'ios' else 'Android'}...")
|
|
86
|
+
self.spawn(command)
|
|
87
|
+
elif key == "w":
|
|
88
|
+
webbrowser.open(server.info.preview_url("localhost"))
|
|
89
|
+
elif key == "j":
|
|
90
|
+
webbrowser.open(server.info.devtools_url("localhost"))
|
|
91
|
+
elif key == "r":
|
|
92
|
+
self.log("[pn] reloading every connected app")
|
|
93
|
+
server.broadcast_command("reload")
|
|
94
|
+
elif key == "m":
|
|
95
|
+
self.log("[pn] opening the dev menu on connected devices")
|
|
96
|
+
server.broadcast_command("menu")
|
|
97
|
+
elif key == "d":
|
|
98
|
+
self._debug_help()
|
|
99
|
+
elif key == "c":
|
|
100
|
+
sys.stdout.write("\033[2J\033[H")
|
|
101
|
+
sys.stdout.flush()
|
|
102
|
+
elif key in ("?", "h"):
|
|
103
|
+
for line in ["", " Commands:", *self.help_lines(), ""]:
|
|
104
|
+
self.log(line)
|
|
105
|
+
elif key in ("q", "\x03", "\x04"):
|
|
106
|
+
self.stop()
|
|
107
|
+
return False
|
|
108
|
+
return True
|
|
109
|
+
|
|
110
|
+
def _go_compatible(self) -> bool:
|
|
111
|
+
try:
|
|
112
|
+
runtime = self.session.server.project_runtime
|
|
113
|
+
except Exception:
|
|
114
|
+
return True
|
|
115
|
+
if not runtime.go_compatible:
|
|
116
|
+
reasons = runtime.plugins + runtime.native_packages
|
|
117
|
+
self.log(
|
|
118
|
+
f"[pn] this project needs native code PythonNative Go doesn't have ({', '.join(reasons)}); "
|
|
119
|
+
"building its development app instead"
|
|
120
|
+
)
|
|
121
|
+
return False
|
|
122
|
+
return True
|
|
123
|
+
|
|
124
|
+
def _debug_help(self) -> None:
|
|
125
|
+
server = self.session.server
|
|
126
|
+
if not server.debug_port:
|
|
127
|
+
self.log("[pn] the debugger proxy is off (start with --debug-port 5678)")
|
|
128
|
+
return
|
|
129
|
+
target = server.hub.default_target()
|
|
130
|
+
where = target.label() if target is not None else "the next app that connects"
|
|
131
|
+
self.log(f"[pn] debugger: attach a Debug Adapter Protocol client to 127.0.0.1:{server.debug_port}")
|
|
132
|
+
self.log(f"[pn] it debugs {where}; pick another in DevTools or with the device's dev menu")
|
|
133
|
+
self.log("[pn] VS Code launch configuration (pn init writes it to .vscode/launch.json):")
|
|
134
|
+
for line in (LAUNCH_CONFIG % server.debug_port).split("\n"):
|
|
135
|
+
self.log(" " + line)
|
|
136
|
+
|
|
137
|
+
def _spawn(self, args: List[str]) -> None:
|
|
138
|
+
"""Run ``pn <args>`` in the background, outside the preview's web environment."""
|
|
139
|
+
name = " ".join(args[:2])
|
|
140
|
+
previous = self._running.get(name)
|
|
141
|
+
if previous is not None and previous.poll() is None:
|
|
142
|
+
self.log(f"[pn] `pn {name}` is still running")
|
|
143
|
+
return
|
|
144
|
+
env = {key: value for key, value in os.environ.items() if key != "PN_PLATFORM"}
|
|
145
|
+
process = subprocess.Popen(
|
|
146
|
+
[sys.executable, "-m", "pythonnative.cli.pn", *args], env=env, stdin=subprocess.DEVNULL
|
|
147
|
+
)
|
|
148
|
+
self._running[name] = process
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def read_keys(handle: Callable[[str], bool], stopped: threading.Event) -> None:
|
|
152
|
+
"""Read single keys from the terminal until ``handle`` returns ``False`` or ``stopped`` is set.
|
|
153
|
+
|
|
154
|
+
The terminal is put in cbreak mode (keys arrive without Enter, and
|
|
155
|
+
Ctrl+C still interrupts) and restored on exit.
|
|
156
|
+
"""
|
|
157
|
+
try:
|
|
158
|
+
import select
|
|
159
|
+
import termios
|
|
160
|
+
import tty
|
|
161
|
+
except ImportError: # Windows: no key commands.
|
|
162
|
+
return
|
|
163
|
+
fd = sys.stdin.fileno()
|
|
164
|
+
try:
|
|
165
|
+
saved = termios.tcgetattr(fd)
|
|
166
|
+
except termios.error:
|
|
167
|
+
return
|
|
168
|
+
try:
|
|
169
|
+
tty.setcbreak(fd)
|
|
170
|
+
while not stopped.is_set():
|
|
171
|
+
ready, _, _ = select.select([fd], [], [], 0.25)
|
|
172
|
+
if not ready:
|
|
173
|
+
continue
|
|
174
|
+
key = os.read(fd, 1).decode("utf-8", errors="ignore")
|
|
175
|
+
if key and not handle(key):
|
|
176
|
+
break
|
|
177
|
+
finally:
|
|
178
|
+
termios.tcsetattr(fd, termios.TCSADRAIN, saved)
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
"""Device-facing steps shared by ``pn run``, ``pn go``, and ``pn start``'s keys.
|
|
2
|
+
|
|
3
|
+
These shell out to ``xcrun simctl``, ``xcrun devicectl``, ``adb``, and the
|
|
4
|
+
Android emulator, so they're exercised on real toolchains rather than in
|
|
5
|
+
unit tests (which cover the pure helpers: links and URLs).
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
import shlex
|
|
12
|
+
import subprocess
|
|
13
|
+
import time
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import Any, Callable, Dict, List, Optional
|
|
16
|
+
|
|
17
|
+
from ..project import devices as devices_mod
|
|
18
|
+
|
|
19
|
+
Logger = Callable[[str], None]
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"boot_android_emulator",
|
|
23
|
+
"booted_ios_udid",
|
|
24
|
+
"ensure_android_device",
|
|
25
|
+
"install_android",
|
|
26
|
+
"install_ios_simulator",
|
|
27
|
+
"open_link_android",
|
|
28
|
+
"launch_ios_device",
|
|
29
|
+
"launch_ios_simulator",
|
|
30
|
+
"select_ios_simulator",
|
|
31
|
+
"server_connect_url",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# ======================================================================
|
|
36
|
+
# URLs
|
|
37
|
+
# ======================================================================
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def server_connect_url(platform: str, device: Optional[devices_mod.Device], port: int, token: str) -> str:
|
|
41
|
+
"""The server URL a launched dev client should use to reach ``pn start``.
|
|
42
|
+
|
|
43
|
+
Simulators share the host's loopback. Android emulators and USB
|
|
44
|
+
devices reach it through ``adb reverse`` (set up by the caller), so
|
|
45
|
+
``localhost`` works for every Android target. A physical iOS device is
|
|
46
|
+
on the LAN, so it gets the first LAN address. The URL carries the dev
|
|
47
|
+
``token`` the server requires.
|
|
48
|
+
"""
|
|
49
|
+
from ..devserver.auth import with_token
|
|
50
|
+
|
|
51
|
+
host = "localhost"
|
|
52
|
+
if platform == "ios" and device is not None and device.kind == "device":
|
|
53
|
+
from ..devserver import lan_addresses
|
|
54
|
+
|
|
55
|
+
host = next(iter(lan_addresses()), host)
|
|
56
|
+
return with_token(f"http://{host}:{port}/", token)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
# ======================================================================
|
|
60
|
+
# iOS
|
|
61
|
+
# ======================================================================
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def booted_ios_udid() -> Optional[str]:
|
|
65
|
+
"""A booted iOS Simulator's UDID, or ``None``."""
|
|
66
|
+
try:
|
|
67
|
+
result = subprocess.run(
|
|
68
|
+
["xcrun", "simctl", "list", "devices", "booted", "--json"], check=False, capture_output=True, text=True
|
|
69
|
+
)
|
|
70
|
+
except FileNotFoundError:
|
|
71
|
+
return None
|
|
72
|
+
try:
|
|
73
|
+
data = json.loads(result.stdout or "{}")
|
|
74
|
+
except json.JSONDecodeError:
|
|
75
|
+
return None
|
|
76
|
+
for devices in (data.get("devices") or {}).values():
|
|
77
|
+
for device in devices or []:
|
|
78
|
+
if device.get("state") == "Booted" and device.get("udid"):
|
|
79
|
+
return str(device["udid"])
|
|
80
|
+
return None
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def select_ios_simulator() -> Optional[str]:
|
|
84
|
+
"""A simulator UDID to target: the booted one, else an iPhone 15, else the first available iPhone.
|
|
85
|
+
|
|
86
|
+
The fallback order is deliberate: a full-size iPhone keeps layouts (and
|
|
87
|
+
the E2E suite's taps) the same from run to run, where picking by name
|
|
88
|
+
could land on a compact model such as the iPhone SE.
|
|
89
|
+
"""
|
|
90
|
+
booted = booted_ios_udid()
|
|
91
|
+
if booted:
|
|
92
|
+
return booted
|
|
93
|
+
try:
|
|
94
|
+
result = subprocess.run(
|
|
95
|
+
["xcrun", "simctl", "list", "devices", "available", "--json"], check=False, capture_output=True, text=True
|
|
96
|
+
)
|
|
97
|
+
except FileNotFoundError:
|
|
98
|
+
return None
|
|
99
|
+
try:
|
|
100
|
+
data = json.loads(result.stdout or "{}")
|
|
101
|
+
except json.JSONDecodeError:
|
|
102
|
+
return None
|
|
103
|
+
devices: List[Dict[str, Any]] = [d for entries in (data.get("devices") or {}).values() for d in (entries or [])]
|
|
104
|
+
for device in devices:
|
|
105
|
+
if "iphone 15" in str(device.get("name") or "").lower() and device.get("isAvailable"):
|
|
106
|
+
return str(device.get("udid"))
|
|
107
|
+
for device in devices:
|
|
108
|
+
if device.get("isAvailable") and str(device.get("name") or "").lower().startswith("iphone"):
|
|
109
|
+
return str(device.get("udid"))
|
|
110
|
+
return None
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def boot_ios_simulator(udid: str) -> None:
|
|
114
|
+
"""Boot ``udid`` (a no-op when it's booted) and bring Simulator.app forward."""
|
|
115
|
+
subprocess.run(["xcrun", "simctl", "boot", udid], check=False, capture_output=True)
|
|
116
|
+
subprocess.run(["open", "-a", "Simulator"], check=False, capture_output=True)
|
|
117
|
+
subprocess.run(["xcrun", "simctl", "bootstatus", udid, "-b"], check=False, capture_output=True)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def install_ios_simulator(udid: str, app: Path) -> bool:
|
|
121
|
+
"""Install an ``.app`` on a simulator."""
|
|
122
|
+
return subprocess.run(["xcrun", "simctl", "install", udid, str(app)], check=False).returncode == 0
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def launch_ios_simulator(
|
|
126
|
+
udid: str, bundle_id: str, link: Optional[str], *, console: bool = False
|
|
127
|
+
) -> "subprocess.Popen[bytes]":
|
|
128
|
+
"""Relaunch an app on a simulator, handing it a connect link.
|
|
129
|
+
|
|
130
|
+
The link travels in the launch environment (``PN_CONNECT_LINK``)
|
|
131
|
+
rather than through ``simctl openurl``, which makes iOS ask the user to
|
|
132
|
+
confirm opening the app. With ``console``, the app's stdout and stderr
|
|
133
|
+
stream to this terminal and the returned process runs until the app
|
|
134
|
+
exits.
|
|
135
|
+
"""
|
|
136
|
+
import os
|
|
137
|
+
|
|
138
|
+
from ..devclient import LINK_ENV
|
|
139
|
+
|
|
140
|
+
env = {**os.environ, "SIMCTL_CHILD_PYTHONUNBUFFERED": "1"}
|
|
141
|
+
if link:
|
|
142
|
+
env["SIMCTL_CHILD_" + LINK_ENV] = link
|
|
143
|
+
command = ["xcrun", "simctl", "launch", "--terminate-running-process"]
|
|
144
|
+
if console:
|
|
145
|
+
command.append("--console-pty")
|
|
146
|
+
return subprocess.Popen([*command, udid, bundle_id], env=env)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def launch_ios_device(identifier: str, bundle_id: str, link: Optional[str]) -> bool:
|
|
150
|
+
"""Relaunch an app on a physical device, handing it a connect link."""
|
|
151
|
+
from ..devclient import LINK_ENV
|
|
152
|
+
|
|
153
|
+
command = ["xcrun", "devicectl", "device", "process", "launch", "--terminate-existing"]
|
|
154
|
+
if link:
|
|
155
|
+
command += ["--environment-variables", json.dumps({LINK_ENV: link})]
|
|
156
|
+
command += ["--device", identifier, bundle_id]
|
|
157
|
+
return subprocess.run(command, check=False).returncode == 0
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
# ======================================================================
|
|
161
|
+
# Android
|
|
162
|
+
# ======================================================================
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def _emulator_binary() -> Optional[Path]:
|
|
166
|
+
from ..project.android import sdk_dir
|
|
167
|
+
|
|
168
|
+
candidate = sdk_dir() / "emulator" / "emulator"
|
|
169
|
+
return candidate if candidate.exists() else None
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def list_avds() -> List[str]:
|
|
173
|
+
"""The Android Virtual Devices this machine has."""
|
|
174
|
+
emulator = _emulator_binary()
|
|
175
|
+
if emulator is None:
|
|
176
|
+
return []
|
|
177
|
+
result = subprocess.run([str(emulator), "-list-avds"], check=False, capture_output=True, text=True)
|
|
178
|
+
return [line.strip() for line in (result.stdout or "").splitlines() if line.strip() and " " not in line.strip()]
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def boot_android_emulator(log: Logger, avd: Optional[str] = None, timeout: float = 240.0) -> Optional[str]:
|
|
182
|
+
"""Boot an emulator and wait until Android finished booting; returns its serial."""
|
|
183
|
+
emulator = _emulator_binary()
|
|
184
|
+
avds = list_avds()
|
|
185
|
+
name = avd or (avds[0] if avds else None)
|
|
186
|
+
if emulator is None or name is None:
|
|
187
|
+
log("No Android emulator to boot: create one in Android Studio's Device Manager.")
|
|
188
|
+
return None
|
|
189
|
+
log(f"Booting the Android emulator {name}...")
|
|
190
|
+
subprocess.Popen(
|
|
191
|
+
[str(emulator), "-avd", name, "-netdelay", "none", "-netspeed", "full"],
|
|
192
|
+
stdout=subprocess.DEVNULL,
|
|
193
|
+
stderr=subprocess.DEVNULL,
|
|
194
|
+
start_new_session=True,
|
|
195
|
+
)
|
|
196
|
+
deadline = time.monotonic() + timeout
|
|
197
|
+
while time.monotonic() < deadline:
|
|
198
|
+
for device in devices_mod.list_android_devices():
|
|
199
|
+
if device.kind == "emulator" and device.is_ready:
|
|
200
|
+
booted = subprocess.run(
|
|
201
|
+
["adb", "-s", device.identifier, "shell", "getprop", "sys.boot_completed"],
|
|
202
|
+
check=False,
|
|
203
|
+
capture_output=True,
|
|
204
|
+
text=True,
|
|
205
|
+
)
|
|
206
|
+
if booted.stdout.strip() == "1":
|
|
207
|
+
return device.identifier
|
|
208
|
+
time.sleep(2.0)
|
|
209
|
+
log("The emulator didn't finish booting in time.")
|
|
210
|
+
return None
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def ensure_android_device(device: Optional[devices_mod.Device], log: Logger) -> Optional[str]:
|
|
214
|
+
"""A ready Android serial: ``device``'s, the first connected one, or a freshly booted emulator."""
|
|
215
|
+
if device is not None:
|
|
216
|
+
return device.identifier
|
|
217
|
+
ready = [d for d in devices_mod.list_android_devices() if d.is_ready]
|
|
218
|
+
if ready:
|
|
219
|
+
return ready[0].identifier
|
|
220
|
+
return boot_android_emulator(log)
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def _adb(serial: Optional[str], *args: str, capture: bool = False) -> subprocess.CompletedProcess[str]:
|
|
224
|
+
command = ["adb", *(["-s", serial] if serial else []), *args]
|
|
225
|
+
return subprocess.run(command, check=False, capture_output=capture, text=True)
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def install_android(serial: Optional[str], apk: Path, package: str, log: Logger) -> bool:
|
|
229
|
+
"""Install an APK, replacing an installed copy signed with a different key."""
|
|
230
|
+
result = _adb(serial, "install", "-r", str(apk), capture=True)
|
|
231
|
+
if result.returncode == 0:
|
|
232
|
+
return True
|
|
233
|
+
output = (result.stdout or "") + (result.stderr or "")
|
|
234
|
+
if "INSTALL_FAILED_UPDATE_INCOMPATIBLE" in output or "signatures do not match" in output:
|
|
235
|
+
log(f"Replacing the installed {package}, which was signed with a different key.")
|
|
236
|
+
_adb(serial, "uninstall", package, capture=True)
|
|
237
|
+
return _adb(serial, "install", str(apk)).returncode == 0
|
|
238
|
+
log(output.strip())
|
|
239
|
+
return False
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def reverse_port(serial: Optional[str], port: int) -> None:
|
|
243
|
+
"""Let the device reach ``localhost:port`` on this machine (``adb reverse``)."""
|
|
244
|
+
_adb(serial, "reverse", f"tcp:{port}", f"tcp:{port}", capture=True)
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def open_link_android(serial: Optional[str], link: str, package: str) -> bool:
|
|
248
|
+
"""Open a deep link in ``package`` (launching it when needed)."""
|
|
249
|
+
# `adb shell` runs its arguments through the device's shell.
|
|
250
|
+
command = f"am start -a android.intent.action.VIEW -d {shlex.quote(link)} {shlex.quote(package)}"
|
|
251
|
+
return _adb(serial, "shell", command).returncode == 0
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def stop_android_app(serial: Optional[str], package: str) -> None:
|
|
255
|
+
"""Force-stop ``package`` so the next link cold-starts it."""
|
|
256
|
+
_adb(serial, "shell", "am", "force-stop", package, capture=True)
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
def describe(device: Optional[devices_mod.Device]) -> Dict[str, Any]:
|
|
260
|
+
"""A loggable description of a target device."""
|
|
261
|
+
return device.to_dict() if device is not None else {}
|