pytron-kit 0.3.12__py3-none-macosx_11_0_universal2.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pytron/__init__.py +112 -0
- pytron/application.py +562 -0
- pytron/apputils/__init__.py +0 -0
- pytron/apputils/chrome_ipc.py +203 -0
- pytron/apputils/codegen.py +261 -0
- pytron/apputils/config.py +303 -0
- pytron/apputils/deadmansswitch.py +47 -0
- pytron/apputils/extras.py +76 -0
- pytron/apputils/native.py +148 -0
- pytron/apputils/shell.py +73 -0
- pytron/apputils/windows.py +286 -0
- pytron/cli.py +384 -0
- pytron/commands/__init__.py +0 -0
- pytron/commands/android.py +28 -0
- pytron/commands/build.py +26 -0
- pytron/commands/doctor.py +221 -0
- pytron/commands/engine.py +23 -0
- pytron/commands/frontend.py +60 -0
- pytron/commands/harvest.py +112 -0
- pytron/commands/helpers.py +239 -0
- pytron/commands/info.py +50 -0
- pytron/commands/init.py +521 -0
- pytron/commands/install.py +294 -0
- pytron/commands/login.py +130 -0
- pytron/commands/package.py +228 -0
- pytron/commands/plugin.py +442 -0
- pytron/commands/run.py +312 -0
- pytron/commands/scan.py +210 -0
- pytron/commands/show.py +23 -0
- pytron/commands/uninstall.py +150 -0
- pytron/commands/utils.py +42 -0
- pytron/commands/workflow.py +95 -0
- pytron/console.py +133 -0
- pytron/core.py +18 -0
- pytron/dependencies/WebView2Loader.dll +0 -0
- pytron/dependencies/__init__.py +1 -0
- pytron/dependencies/pytron_native.so +0 -0
- pytron/engines/chrome/adapter.py +445 -0
- pytron/engines/chrome/engine.py +576 -0
- pytron/engines/chrome/forge.py +147 -0
- pytron/engines/chrome/shell/package.json +8 -0
- pytron/engines/chrome/shell/preload.js +12 -0
- pytron/engines/chrome/shell/shell.js +534 -0
- pytron/exceptions.py +36 -0
- pytron/inspector.py +201 -0
- pytron/inspector_ui.py +512 -0
- pytron/installer/Installation.nsi +236 -0
- pytron/installer/header.bmp +0 -0
- pytron/installer/pytron.ico +0 -0
- pytron/installer/sidebar.bmp +0 -0
- pytron/llms.md +98 -0
- pytron/manifests/README.md +29 -0
- pytron/manifests/windows-utf8.manifest +44 -0
- pytron/menu.py +128 -0
- pytron/nsis-setup.exe +0 -0
- pytron/pack/__init__.py +0 -0
- pytron/pack/assets.py +131 -0
- pytron/pack/compilers.py +289 -0
- pytron/pack/crystal.py +297 -0
- pytron/pack/graph.py +377 -0
- pytron/pack/inference.py +157 -0
- pytron/pack/installers.py +402 -0
- pytron/pack/introspect.py +357 -0
- pytron/pack/metadata.py +213 -0
- pytron/pack/modules.py +618 -0
- pytron/pack/nuitka.py +108 -0
- pytron/pack/pipeline.py +107 -0
- pytron/pack/pyinstaller.py +176 -0
- pytron/pack/rust_engine.py +273 -0
- pytron/pack/secure.py +309 -0
- pytron/pack/secure_loader/bin/pytron_rust_bootloader +0 -0
- pytron/pack/secure_loader/icon.ico +0 -0
- pytron/pack/utils.py +110 -0
- pytron/pack/virtual_root.py +124 -0
- pytron/platforms/__init__.py +0 -0
- pytron/platforms/android/__init__.py +3 -0
- pytron/platforms/android/android.py +103 -0
- pytron/platforms/android/builder.py +736 -0
- pytron/platforms/android/ops/build.py +79 -0
- pytron/platforms/android/ops/init.py +63 -0
- pytron/platforms/android/ops/run.py +79 -0
- pytron/platforms/android/ops/sync.py +770 -0
- pytron/platforms/android/ops/utils.py +8 -0
- pytron/platforms/android/shell/README.md +30 -0
- pytron/platforms/android/shell/app/build.gradle +64 -0
- pytron/platforms/android/shell/app/src/main/AndroidManifest.xml +29 -0
- pytron/platforms/android/shell/app/src/main/assets/python/main.py +86 -0
- pytron/platforms/android/shell/app/src/main/assets/python/python314.zip +0 -0
- pytron/platforms/android/shell/app/src/main/cpp/CMakeLists.txt +25 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/Python.h +155 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/abstract.h +915 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/audit.h +30 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/bltinmodule.h +14 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/boolobject.h +54 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/bytearrayobject.h +44 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/bytesobject.h +66 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/ceval.h +145 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/codecs.h +176 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/compile.h +22 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/complexobject.h +30 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/abstract.h +104 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/audit.h +8 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/bytearrayobject.h +38 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/bytesobject.h +42 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/cellobject.h +50 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/ceval.h +43 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/classobject.h +71 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/code.h +340 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/compile.h +50 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/complexobject.h +33 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/context.h +107 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/critical_section.h +154 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/descrobject.h +62 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/dictobject.h +105 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/fileobject.h +16 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/fileutils.h +16 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/floatobject.h +27 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/frameobject.h +35 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/funcobject.h +185 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/genobject.h +56 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/import.h +30 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/initconfig.h +334 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/listobject.h +53 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/lock.h +74 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/longintrepr.h +184 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/longobject.h +89 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/memoryobject.h +50 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/methodobject.h +66 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/modsupport.h +26 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/monitoring.h +269 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/object.h +493 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/objimpl.h +104 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/odictobject.h +43 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/picklebufobject.h +31 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pthread_stubs.h +105 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyatomic.h +614 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyatomic_gcc.h +615 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyatomic_msc.h +1197 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyatomic_std.h +1112 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyctype.h +39 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pydebug.h +38 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyerrors.h +132 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyfpe.h +15 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyframe.h +45 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyhash.h +54 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pylifecycle.h +89 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pymem.h +84 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pystate.h +275 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pystats.h +194 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pythonrun.h +96 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pythread.h +43 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pytime.h +27 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/setobject.h +71 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/traceback.h +13 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/tracemalloc.h +32 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/tupleobject.h +40 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/unicodeobject.h +773 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/warnings.h +20 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/weakrefobject.h +66 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/critical_section.h +16 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/datetime.h +267 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/descrobject.h +100 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/dictobject.h +108 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/dynamic_annotations.h +499 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/enumobject.h +17 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/errcode.h +45 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/exports.h +105 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/fileobject.h +41 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/fileutils.h +62 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/floatobject.h +54 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/frameobject.h +20 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/genericaliasobject.h +14 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/import.h +103 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/mimalloc/mimalloc/atomic.h +392 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/mimalloc/mimalloc/internal.h +969 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/mimalloc/mimalloc/prim.h +329 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/mimalloc/mimalloc/track.h +147 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/mimalloc/mimalloc/types.h +721 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/mimalloc/mimalloc.h +565 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_abstract.h +61 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_asdl.h +112 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_ast.h +945 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_ast_state.h +271 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_atexit.h +31 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_audit.h +35 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_backoff.h +133 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_bitutils.h +186 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_blocks_output_buffer.h +321 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_brc.h +73 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_bytes_methods.h +82 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_bytesobject.h +149 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_c_array.h +39 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_call.h +206 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_capsule.h +17 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_cell.h +75 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_ceval.h +390 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_ceval_state.h +48 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_code.h +671 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_codecs.h +76 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_compile.h +230 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_complexobject.h +34 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_condvar.h +93 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_context.h +59 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_critical_section.h +237 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_crossinterp.h +406 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_crossinterp_data_registry.h +41 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_debug_offsets.h +379 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_descrobject.h +28 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_dict.h +410 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_dict_state.h +28 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_dtoa.h +40 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_emscripten_signal.h +30 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_emscripten_trampoline.h +70 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_exceptions.h +40 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_faulthandler.h +100 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_fileutils.h +320 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_fileutils_windows.h +98 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_floatobject.h +49 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_flowgraph.h +47 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_format.h +27 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_frame.h +61 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_freelist.h +111 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_freelist_state.h +70 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_function.h +53 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_gc.h +378 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_genobject.h +43 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_getopt.h +22 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_gil.h +66 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_global_objects.h +34 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_global_objects_fini_generated.h +1592 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_global_strings.h +854 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_hamt.h +113 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_hashtable.h +150 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_import.h +141 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_importdl.h +139 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_index_pool.h +36 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_initconfig.h +197 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_instruction_sequence.h +83 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_instruments.h +127 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_interp.h +109 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_interp_structs.h +977 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_interpframe.h +401 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_interpframe_structs.h +95 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_interpolation.h +26 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_intrinsics.h +51 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_jit.h +29 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_list.h +81 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_llist.h +106 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_lock.h +236 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_long.h +319 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_magic_number.h +305 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_memoryobject.h +20 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_mimalloc.h +69 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_modsupport.h +99 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_moduleobject.h +62 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_namespace.h +21 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_object.h +1029 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_object_alloc.h +71 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_object_deferred.h +32 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_object_stack.h +95 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_object_state.h +49 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_obmalloc.h +702 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_obmalloc_init.h +66 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_opcode_metadata.h +2117 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_opcode_utils.h +90 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_optimizer.h +318 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_parking_lot.h +97 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_parser.h +78 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pathconfig.h +26 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pyarena.h +68 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pyatomic_ft_wrappers.h +174 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pybuffer.h +21 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pyerrors.h +213 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pyhash.h +91 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pylifecycle.h +136 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pymath.h +205 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pymem.h +145 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pymem_init.h +103 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pystate.h +339 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pystats.h +21 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pythonrun.h +68 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pythread.h +172 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_qsbr.h +172 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_range.h +21 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_runtime.h +63 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_runtime_init.h +239 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_runtime_init_generated.h +1589 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_runtime_structs.h +310 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_semaphore.h +67 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_setobject.h +41 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_signal.h +108 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_sliceobject.h +20 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_stackref.h +791 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_stats.h +97 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_strhex.h +39 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_structs.h +88 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_structseq.h +40 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_symtable.h +201 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_sysmodule.h +32 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_template.h +26 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_time.h +334 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_token.h +110 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_traceback.h +111 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_tracemalloc.h +164 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_tstate.h +88 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_tuple.h +75 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_typedefs.h +18 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_typeobject.h +155 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_typevarobject.h +28 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_ucnhash.h +36 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_unicodeobject.h +308 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_unicodeobject_generated.h +3132 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_unionobject.h +26 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_uniqueid.h +57 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_uop_ids.h +335 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_uop_metadata.h +1204 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_warnings.h +21 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_weakref.h +133 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/intrcheck.h +23 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/iterobject.h +24 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/listobject.h +55 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/lock.h +16 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/longobject.h +178 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/marshal.h +31 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/memoryobject.h +34 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/methodobject.h +146 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/modsupport.h +146 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/moduleobject.h +122 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/monitoring.h +18 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/object.h +828 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/objimpl.h +211 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/opcode.h +43 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/opcode_ids.h +259 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/osdefs.h +57 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/osmodule.h +17 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/patchlevel.h +49 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/py_curses.h +117 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pyatomic.h +16 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pybuffer.h +145 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pycapsule.h +58 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pyconfig.h +2088 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pydtrace.h +59 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pyerrors.h +335 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pyexpat.h +62 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pyframe.h +26 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pyhash.h +59 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pylifecycle.h +80 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pymacconfig.h +91 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pymacro.h +243 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pymath.h +65 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pymem.h +110 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pyport.h +710 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pystate.h +132 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pystats.h +28 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pystrcmp.h +23 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pystrtod.h +37 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pythonrun.h +42 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pythread.h +131 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pytypedefs.h +30 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/rangeobject.h +27 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/refcount.h +555 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/setobject.h +49 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/sliceobject.h +69 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/structmember.h +56 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/structseq.h +46 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/sysmodule.h +27 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/traceback.h +26 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/tupleobject.h +46 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/typeslots.h +96 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/unicodeobject.h +1029 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/warnings.h +45 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/weakrefobject.h +46 -0
- pytron/platforms/android/shell/app/src/main/cpp/pytron_bridge.cpp +224 -0
- pytron/platforms/android/shell/app/src/main/java/com/pytron/shell/MainActivity.kt +208 -0
- pytron/platforms/android/shell/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- pytron/platforms/android/shell/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- pytron/platforms/android/shell/build.gradle +11 -0
- pytron/platforms/android/shell/gradle/wrapper/gradle-wrapper.jar +0 -0
- pytron/platforms/android/shell/gradle/wrapper/gradle-wrapper.properties +5 -0
- pytron/platforms/android/shell/gradle.properties +2 -0
- pytron/platforms/android/shell/gradlew.bat +85 -0
- pytron/platforms/android/shell/settings.gradle +16 -0
- pytron/platforms/darwin.py +82 -0
- pytron/platforms/darwin_ops/libs.py +31 -0
- pytron/platforms/darwin_ops/system.py +182 -0
- pytron/platforms/darwin_ops/utils.py +85 -0
- pytron/platforms/darwin_ops/webview.py +5 -0
- pytron/platforms/darwin_ops/window.py +102 -0
- pytron/platforms/interface.py +152 -0
- pytron/platforms/linux.py +82 -0
- pytron/platforms/linux_ops/libs.py +49 -0
- pytron/platforms/linux_ops/system.py +316 -0
- pytron/platforms/linux_ops/utils.py +19 -0
- pytron/platforms/linux_ops/webview.py +5 -0
- pytron/platforms/linux_ops/window.py +115 -0
- pytron/platforms/windows.py +136 -0
- pytron/platforms/windows_ops/__init__.py +0 -0
- pytron/platforms/windows_ops/constants.py +126 -0
- pytron/platforms/windows_ops/system.py +518 -0
- pytron/platforms/windows_ops/utils.py +3 -0
- pytron/platforms/windows_ops/webview.py +5 -0
- pytron/platforms/windows_ops/window.py +361 -0
- pytron/plugin.py +467 -0
- pytron/rcedit-x64.exe +0 -0
- pytron/router.py +146 -0
- pytron/serializer.py +240 -0
- pytron/shortcuts.py +279 -0
- pytron/state.py +76 -0
- pytron/tray.py +399 -0
- pytron/updater.py +181 -0
- pytron/utf8_hook.py +112 -0
- pytron/utils.py +44 -0
- pytron/webview.py +722 -0
- pytron_kit-0.3.12.dist-info/METADATA +131 -0
- pytron_kit-0.3.12.dist-info/RECORD +419 -0
- pytron_kit-0.3.12.dist-info/WHEEL +5 -0
- pytron_kit-0.3.12.dist-info/entry_points.txt +2 -0
- pytron_kit-0.3.12.dist-info/licenses/LICENSE +201 -0
- pytron_kit-0.3.12.dist-info/top_level.txt +1 -0
pytron/__init__.py
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import os
|
|
3
|
+
import io
|
|
4
|
+
|
|
5
|
+
# Best-effort: configure stdio to UTF-8 early when pytron is imported. This
|
|
6
|
+
# helps packaged apps avoid UnicodeEncodeError during prints/logging.
|
|
7
|
+
try:
|
|
8
|
+
os.environ.setdefault("PYTHONUTF8", "1")
|
|
9
|
+
os.environ.setdefault("PYTHONIOENCODING", "utf-8:surrogatepass")
|
|
10
|
+
except Exception:
|
|
11
|
+
# Environment setup is best-effort
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _early_reconfigure():
|
|
16
|
+
try:
|
|
17
|
+
if getattr(sys.stdout, "buffer", None) is not None:
|
|
18
|
+
sys.stdout = io.TextIOWrapper(
|
|
19
|
+
sys.stdout.buffer,
|
|
20
|
+
encoding="utf-8",
|
|
21
|
+
errors="surrogatepass",
|
|
22
|
+
line_buffering=True,
|
|
23
|
+
)
|
|
24
|
+
except Exception:
|
|
25
|
+
try:
|
|
26
|
+
sys.stdout.reconfigure(encoding="utf-8", errors="surrogatepass")
|
|
27
|
+
except Exception:
|
|
28
|
+
# Fallback failed, cannot reconfigure stdout
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
try:
|
|
32
|
+
if getattr(sys.stderr, "buffer", None) is not None:
|
|
33
|
+
sys.stderr = io.TextIOWrapper(
|
|
34
|
+
sys.stderr.buffer,
|
|
35
|
+
encoding="utf-8",
|
|
36
|
+
errors="surrogatepass",
|
|
37
|
+
line_buffering=True,
|
|
38
|
+
)
|
|
39
|
+
except Exception:
|
|
40
|
+
try:
|
|
41
|
+
sys.stderr.reconfigure(encoding="utf-8", errors="surrogatepass")
|
|
42
|
+
except Exception:
|
|
43
|
+
# Fallback failed, cannot reconfigure stderr
|
|
44
|
+
pass
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
# Skip reconfiguration if running under pytest to avoid conflict with capture
|
|
48
|
+
if "pytest" not in sys.modules and "pytest" not in sys.argv[0]:
|
|
49
|
+
_early_reconfigure()
|
|
50
|
+
|
|
51
|
+
# Fetch version from installed package metadata to avoid manual updates
|
|
52
|
+
try:
|
|
53
|
+
if sys.version_info >= (3, 8):
|
|
54
|
+
from importlib.metadata import version, PackageNotFoundError
|
|
55
|
+
else:
|
|
56
|
+
from importlib_metadata import version, PackageNotFoundError
|
|
57
|
+
|
|
58
|
+
try:
|
|
59
|
+
__version__ = version("pytron-kit")
|
|
60
|
+
except PackageNotFoundError:
|
|
61
|
+
__version__ = "0.0.0-dev"
|
|
62
|
+
except ImportError:
|
|
63
|
+
__version__ = "0.0.0-dev"
|
|
64
|
+
|
|
65
|
+
# --- Plugin Configuration Namespace ---
|
|
66
|
+
import types
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class PluginsNamespace(types.ModuleType):
|
|
70
|
+
def __init__(self):
|
|
71
|
+
super().__init__("plugins")
|
|
72
|
+
self._registered_configs = {}
|
|
73
|
+
|
|
74
|
+
def __getattr__(self, name):
|
|
75
|
+
# Return a configurator for the requested plugin
|
|
76
|
+
return PluginConfigurator(name, self._registered_configs)
|
|
77
|
+
|
|
78
|
+
def get_registered_config(self, plugin_name):
|
|
79
|
+
return self._registered_configs.get(plugin_name, {})
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class PluginConfigurator:
|
|
83
|
+
def __init__(self, plugin_name, registry):
|
|
84
|
+
self.plugin_name = plugin_name
|
|
85
|
+
self.registry = registry
|
|
86
|
+
|
|
87
|
+
def __call__(self, **kwargs):
|
|
88
|
+
self.registry[self.plugin_name] = kwargs
|
|
89
|
+
return self
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
# Create the instance and inject it into sys.modules so 'import plugins' works
|
|
93
|
+
plugins = PluginsNamespace()
|
|
94
|
+
sys.modules["plugins"] = plugins
|
|
95
|
+
# print(f"[Pytron] Injected plugins namespace into sys.modules: {sys.modules['plugins']}")
|
|
96
|
+
# --------------------------------------
|
|
97
|
+
|
|
98
|
+
from .core import App, Webview, get_resource_path, Menu, MenuBar
|
|
99
|
+
from .plugin import Plugin
|
|
100
|
+
from .updater import Updater
|
|
101
|
+
|
|
102
|
+
__all__ = [
|
|
103
|
+
"App",
|
|
104
|
+
"Webview",
|
|
105
|
+
"get_resource_path",
|
|
106
|
+
"Menu",
|
|
107
|
+
"MenuBar",
|
|
108
|
+
"Plugin",
|
|
109
|
+
"Updater",
|
|
110
|
+
"plugins",
|
|
111
|
+
"PluginConfigurator",
|
|
112
|
+
]
|
pytron/application.py
ADDED
|
@@ -0,0 +1,562 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
from typing import Any
|
|
4
|
+
from .state import ReactiveState
|
|
5
|
+
from .router import Router
|
|
6
|
+
|
|
7
|
+
from .plugin import Plugin
|
|
8
|
+
|
|
9
|
+
from .shortcuts import ShortcutManager
|
|
10
|
+
from .apputils.codegen import CodegenMixin
|
|
11
|
+
from .apputils.native import NativeMixin
|
|
12
|
+
from .apputils.config import ConfigMixin
|
|
13
|
+
from .apputils.windows import WindowMixin
|
|
14
|
+
from .apputils.extras import ExtrasMixin
|
|
15
|
+
from .apputils.shell import Shell
|
|
16
|
+
from .inspector import Inspector
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class App(ConfigMixin, WindowMixin, ExtrasMixin, CodegenMixin, NativeMixin, Shell):
|
|
20
|
+
def __init__(self, config_file="settings.json"):
|
|
21
|
+
# PERFORMANCE: Shared thread pool for all internal window operations
|
|
22
|
+
self.thread_pool = __import__("concurrent.futures").futures.ThreadPoolExecutor(
|
|
23
|
+
max_workers=10
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
# Init State
|
|
27
|
+
self.windows = []
|
|
28
|
+
self.is_running = False
|
|
29
|
+
self._exposed_functions = {}
|
|
30
|
+
self._exposed_ts_defs = {}
|
|
31
|
+
self._pydantic_models = {}
|
|
32
|
+
self.shortcuts = {}
|
|
33
|
+
self.plugins = []
|
|
34
|
+
self._on_exit_callbacks = []
|
|
35
|
+
self.tray = None
|
|
36
|
+
self.shortcut_manager = ShortcutManager()
|
|
37
|
+
self._on_file_drop_callback = None
|
|
38
|
+
self.plugin_statuses = [] # Track load status for inspector
|
|
39
|
+
|
|
40
|
+
# Router Init
|
|
41
|
+
self.router = Router()
|
|
42
|
+
|
|
43
|
+
# ConfigMixin setup
|
|
44
|
+
self._setup_logging()
|
|
45
|
+
self.router.logger = self.logger # Share logger
|
|
46
|
+
self.state = ReactiveState(self)
|
|
47
|
+
self._check_deep_link()
|
|
48
|
+
self._load_config(config_file)
|
|
49
|
+
_, safe_title = self._setup_identity()
|
|
50
|
+
self._setup_storage(safe_title)
|
|
51
|
+
self._resolve_resources()
|
|
52
|
+
self._register_core_apis()
|
|
53
|
+
|
|
54
|
+
# Engine Selection (PRO FEATURES)
|
|
55
|
+
self.engine = os.environ.get(
|
|
56
|
+
"PYTRON_ENGINE", self.config.get("engine", "native")
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
# Override via CLI flags if present
|
|
60
|
+
if "--web" in sys.argv:
|
|
61
|
+
self.engine = "chrome"
|
|
62
|
+
|
|
63
|
+
# Check if --engine X was passed directly to the script
|
|
64
|
+
for i, arg in enumerate(sys.argv):
|
|
65
|
+
if arg == "--engine" and i + 1 < len(sys.argv):
|
|
66
|
+
self.engine = sys.argv[i + 1]
|
|
67
|
+
|
|
68
|
+
if self.engine == "chrome":
|
|
69
|
+
self.logger.info("Using Chrome Shell Engine (Mojo IPC)")
|
|
70
|
+
|
|
71
|
+
# Initialize Inspector
|
|
72
|
+
self.inspector = Inspector(self)
|
|
73
|
+
|
|
74
|
+
if self.config.get("single_instance", False):
|
|
75
|
+
# ConfigMixin already handles this via _setup_identity -> _setup_single_instance
|
|
76
|
+
pass
|
|
77
|
+
|
|
78
|
+
self._setup_key_value_store()
|
|
79
|
+
|
|
80
|
+
# Register automatic cleanup for thread pool
|
|
81
|
+
# Register automatic cleanup for thread pool
|
|
82
|
+
@self.on_exit
|
|
83
|
+
def _cleanup_pool():
|
|
84
|
+
if self.thread_pool:
|
|
85
|
+
self.logger.debug("Shutting down thread pool...")
|
|
86
|
+
try:
|
|
87
|
+
self.thread_pool.shutdown(wait=False, cancel_futures=True)
|
|
88
|
+
except Exception as e:
|
|
89
|
+
self.logger.debug(f"Error shutting down thread pool: {e}")
|
|
90
|
+
self.thread_pool = None
|
|
91
|
+
|
|
92
|
+
# AUTO-CODEGEN: Generate TypeScript definitions in debug mode
|
|
93
|
+
if self.config.get("debug", False):
|
|
94
|
+
# We use a small delay via the event loop or just run it before start
|
|
95
|
+
# To ensure all plugins/modules have had a chance to .expose()
|
|
96
|
+
# But usually they do it during __init__ or before app.run()
|
|
97
|
+
# We'll attach it to a pre-run hook or just before the loop starts in WindowMixin.run
|
|
98
|
+
pass
|
|
99
|
+
|
|
100
|
+
# Actually, let's trigger it once here for early feedback
|
|
101
|
+
if self.config.get("debug", False):
|
|
102
|
+
try:
|
|
103
|
+
self.generate_types()
|
|
104
|
+
except Exception as e:
|
|
105
|
+
self.logger.debug(f"Initial codegen skipped: {e}")
|
|
106
|
+
|
|
107
|
+
# Load Plugins
|
|
108
|
+
# We must use the script/exe directory (sys.path[0]), NOT cwd, because cwd changes to AppData
|
|
109
|
+
if getattr(sys, "frozen", False):
|
|
110
|
+
# Senior Fix: Use sys._MEIPASS for internal assets/plugins in frozen builds.
|
|
111
|
+
# Fallback to sys.executable dir if _MEIPASS is somehow missing.
|
|
112
|
+
base_dir = getattr(
|
|
113
|
+
sys, "_MEIPASS", os.path.dirname(os.path.abspath(sys.executable))
|
|
114
|
+
)
|
|
115
|
+
else:
|
|
116
|
+
# Prefer the directory of the actual main script if possible
|
|
117
|
+
main_script = (
|
|
118
|
+
sys.modules.get("__main__", {}).__file__
|
|
119
|
+
if "__main__" in sys.modules
|
|
120
|
+
else None
|
|
121
|
+
)
|
|
122
|
+
if main_script:
|
|
123
|
+
base_dir = os.path.dirname(os.path.abspath(main_script))
|
|
124
|
+
elif sys.path[0]:
|
|
125
|
+
base_dir = os.path.abspath(sys.path[0])
|
|
126
|
+
else:
|
|
127
|
+
base_dir = os.getcwd()
|
|
128
|
+
|
|
129
|
+
self.logger.debug(f"Plugin Base Dir resolved to: {base_dir}")
|
|
130
|
+
|
|
131
|
+
self.app_root = base_dir
|
|
132
|
+
|
|
133
|
+
# Plugin Discovery: Check both bundled (internal) and drop-in (external) paths
|
|
134
|
+
candidate_dirs = []
|
|
135
|
+
if getattr(sys, "frozen", False):
|
|
136
|
+
# 1. Bundled plugins inside _internal
|
|
137
|
+
if hasattr(sys, "_MEIPASS"):
|
|
138
|
+
candidate_dirs.append(os.path.join(sys._MEIPASS, "plugins"))
|
|
139
|
+
# 2. Drop-in plugins next to the EXE
|
|
140
|
+
exe_dir = os.path.dirname(os.path.abspath(sys.executable))
|
|
141
|
+
candidate_dirs.append(os.path.join(exe_dir, "plugins"))
|
|
142
|
+
else:
|
|
143
|
+
# Local dev plugins next to the script
|
|
144
|
+
candidate_dirs.append(os.path.join(base_dir, "plugins"))
|
|
145
|
+
|
|
146
|
+
custom_plugins_dir = self.config.get("plugins_dir")
|
|
147
|
+
if custom_plugins_dir:
|
|
148
|
+
if not os.path.isabs(custom_plugins_dir):
|
|
149
|
+
custom_plugins_dir = os.path.join(base_dir, custom_plugins_dir)
|
|
150
|
+
candidate_dirs.append(custom_plugins_dir)
|
|
151
|
+
|
|
152
|
+
# Remove duplicates and resolve
|
|
153
|
+
seen = set()
|
|
154
|
+
for p_dir in candidate_dirs:
|
|
155
|
+
p_dir = os.path.abspath(p_dir)
|
|
156
|
+
if p_dir not in seen and os.path.exists(p_dir):
|
|
157
|
+
self.logger.info(f"Scanning for plugins in: {p_dir}")
|
|
158
|
+
self.load_plugins(p_dir)
|
|
159
|
+
seen.add(p_dir)
|
|
160
|
+
|
|
161
|
+
def on_exit(self, func):
|
|
162
|
+
"""
|
|
163
|
+
Register a function to run when the application is exiting.
|
|
164
|
+
Can be used as a decorator: @app.on_exit
|
|
165
|
+
"""
|
|
166
|
+
self._on_exit_callbacks.append(func)
|
|
167
|
+
return func
|
|
168
|
+
|
|
169
|
+
# Expose function to all windows
|
|
170
|
+
def expose(self, func=None, name=None, secure=False, run_in_thread=True):
|
|
171
|
+
"""
|
|
172
|
+
Expose a function to ALL windows created by this App.
|
|
173
|
+
Can be used as a decorator: @app.expose or @app.expose(secure=True)
|
|
174
|
+
"""
|
|
175
|
+
# Case 1: Used as @app.expose(secure=True) - func is None
|
|
176
|
+
if func is None:
|
|
177
|
+
|
|
178
|
+
def decorator(f):
|
|
179
|
+
self.expose(f, name=name, secure=secure, run_in_thread=run_in_thread)
|
|
180
|
+
return f
|
|
181
|
+
|
|
182
|
+
return decorator
|
|
183
|
+
|
|
184
|
+
# Case 2: Used as @app.expose or app.expose(func)
|
|
185
|
+
# If the user passed a class or an object (bridge), expose its public callables
|
|
186
|
+
if isinstance(func, type) or (not callable(func) and hasattr(func, "__dict__")):
|
|
187
|
+
# Try to instantiate the class if a class was provided, otherwise use the instance
|
|
188
|
+
bridge = None
|
|
189
|
+
if isinstance(func, type):
|
|
190
|
+
try:
|
|
191
|
+
bridge = func()
|
|
192
|
+
except Exception:
|
|
193
|
+
# Could not instantiate; fall back to using the class object itself
|
|
194
|
+
bridge = func
|
|
195
|
+
else:
|
|
196
|
+
bridge = func
|
|
197
|
+
|
|
198
|
+
for attr_name in dir(bridge):
|
|
199
|
+
if attr_name.startswith("_"):
|
|
200
|
+
continue
|
|
201
|
+
try:
|
|
202
|
+
attr = getattr(bridge, attr_name)
|
|
203
|
+
except Exception:
|
|
204
|
+
continue
|
|
205
|
+
if callable(attr):
|
|
206
|
+
try:
|
|
207
|
+
# For classes, we assume default security unless specified?
|
|
208
|
+
# Or maybe we shouldn't support granular security on class-based expose yet for simplicity
|
|
209
|
+
# just pass 'secure' to all methods.
|
|
210
|
+
self._exposed_functions[attr_name] = {
|
|
211
|
+
"func": attr,
|
|
212
|
+
"secure": secure,
|
|
213
|
+
"run_in_thread": run_in_thread,
|
|
214
|
+
}
|
|
215
|
+
self._exposed_ts_defs[attr_name] = self._get_ts_definition(
|
|
216
|
+
attr_name, attr
|
|
217
|
+
)
|
|
218
|
+
except Exception:
|
|
219
|
+
pass
|
|
220
|
+
return func
|
|
221
|
+
|
|
222
|
+
if name is None:
|
|
223
|
+
name = func.__name__
|
|
224
|
+
|
|
225
|
+
self._exposed_functions[name] = {
|
|
226
|
+
"func": func,
|
|
227
|
+
"secure": secure,
|
|
228
|
+
"run_in_thread": run_in_thread,
|
|
229
|
+
}
|
|
230
|
+
self._exposed_ts_defs[name] = self._get_ts_definition(name, func)
|
|
231
|
+
return func
|
|
232
|
+
|
|
233
|
+
def shortcut(self, key_combo, func=None):
|
|
234
|
+
"""
|
|
235
|
+
Register a global keyboard shortcut for all windows.
|
|
236
|
+
Example: @app.shortcut('Ctrl+Q')
|
|
237
|
+
"""
|
|
238
|
+
if func is None:
|
|
239
|
+
|
|
240
|
+
def decorator(f):
|
|
241
|
+
self.shortcut(key_combo, f)
|
|
242
|
+
return f
|
|
243
|
+
|
|
244
|
+
return decorator
|
|
245
|
+
self.shortcuts[key_combo] = func
|
|
246
|
+
return func
|
|
247
|
+
|
|
248
|
+
def on_deep_link(self, pattern: str):
|
|
249
|
+
"""
|
|
250
|
+
Decorator to register a handler for deep links.
|
|
251
|
+
Pattern examples: "project/{id}", "settings", "oauth/callback"
|
|
252
|
+
|
|
253
|
+
@app.on_deep_link("project/{id}")
|
|
254
|
+
def open_project(id, link):
|
|
255
|
+
print(f"Opening project {id} from {link.raw_url}")
|
|
256
|
+
"""
|
|
257
|
+
return self.router.route(pattern)
|
|
258
|
+
|
|
259
|
+
def on_file_drop(self, func):
|
|
260
|
+
"""
|
|
261
|
+
Decorator to register a handler for file drop events.
|
|
262
|
+
|
|
263
|
+
@app.on_file_drop
|
|
264
|
+
def handle_drop(window, files):
|
|
265
|
+
print(f"Dropped files on window {window.id}: {files}")
|
|
266
|
+
"""
|
|
267
|
+
self._on_file_drop_callback = func
|
|
268
|
+
return func
|
|
269
|
+
|
|
270
|
+
def _register_core_apis(self):
|
|
271
|
+
"""Automatically exposes built-in system APIs to the frontend."""
|
|
272
|
+
# Shell APIs
|
|
273
|
+
self.expose(self.open_external, name="shell_open_external")
|
|
274
|
+
self.expose(self.show_item_in_folder, name="shell_show_item_in_folder")
|
|
275
|
+
|
|
276
|
+
# Clipboard APIs
|
|
277
|
+
self.expose(self.copy_to_clipboard, name="clipboard_write_text")
|
|
278
|
+
self.expose(self.get_clipboard_text, name="clipboard_read_text")
|
|
279
|
+
|
|
280
|
+
# System Info
|
|
281
|
+
self.expose(self.get_system_info, name="system_get_info")
|
|
282
|
+
|
|
283
|
+
# Store APIs
|
|
284
|
+
self.expose(self.store_set, name="store_set")
|
|
285
|
+
self.expose(self.store_get, name="store_get")
|
|
286
|
+
self.expose(self.store_delete, name="store_delete")
|
|
287
|
+
|
|
288
|
+
# App Lifecycle
|
|
289
|
+
self.expose(self.quit, name="app_quit", run_in_thread=False)
|
|
290
|
+
self.expose(self.show, name="app_show", run_in_thread=False)
|
|
291
|
+
self.expose(self.hide, name="app_hide", run_in_thread=False)
|
|
292
|
+
self.expose(lambda: self.is_visible, name="app_is_visible", run_in_thread=False)
|
|
293
|
+
|
|
294
|
+
# Event Bus
|
|
295
|
+
self.expose(self.publish, name="app_publish")
|
|
296
|
+
|
|
297
|
+
# Updater APIs
|
|
298
|
+
self.expose(self.check_updates, name="app_check_updates")
|
|
299
|
+
self.expose(self.install_update, name="app_install_update")
|
|
300
|
+
|
|
301
|
+
# Inspector APIs
|
|
302
|
+
self.expose(
|
|
303
|
+
self.toggle_inspector, name="app_toggle_inspector", run_in_thread=False
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
def check_updates(self, url: str):
|
|
307
|
+
"""
|
|
308
|
+
Checks for application updates.
|
|
309
|
+
Returns update info if available, else None.
|
|
310
|
+
"""
|
|
311
|
+
from .updater import Updater
|
|
312
|
+
|
|
313
|
+
upd = Updater(current_version=self.config.get("version"))
|
|
314
|
+
return upd.check(url)
|
|
315
|
+
|
|
316
|
+
def install_update(self, update_info: dict):
|
|
317
|
+
"""
|
|
318
|
+
Downloads and installs an update.
|
|
319
|
+
Emits 'pytron:update-progress' events.
|
|
320
|
+
"""
|
|
321
|
+
from .updater import Updater
|
|
322
|
+
|
|
323
|
+
upd = Updater(current_version=self.config.get("version"))
|
|
324
|
+
|
|
325
|
+
def _on_progress(pct):
|
|
326
|
+
self.broadcast("pytron:update-progress", {"percent": pct})
|
|
327
|
+
|
|
328
|
+
# Run install in thread pool to avoid blocking IPC
|
|
329
|
+
self.thread_pool.submit(upd.download_and_install, update_info, _on_progress)
|
|
330
|
+
return True
|
|
331
|
+
|
|
332
|
+
def publish(self, event_name: str, data: Any = None):
|
|
333
|
+
"""
|
|
334
|
+
Broadcasts an event to all open windows.
|
|
335
|
+
This enables simple cross-window communication.
|
|
336
|
+
"""
|
|
337
|
+
self.broadcast(event_name, data)
|
|
338
|
+
return True
|
|
339
|
+
|
|
340
|
+
def dispatch(self, event_name: str, payload: Any = None):
|
|
341
|
+
"""
|
|
342
|
+
Dispatches an event to the frontend Event Bus in ALL active windows.
|
|
343
|
+
Usage: app.dispatch('navigate', {'route': '/settings'})
|
|
344
|
+
"""
|
|
345
|
+
# We iterate over windows and call their individual dispatch method
|
|
346
|
+
# This ensures they use the strictly defined event bus protocol we implemented in Webview
|
|
347
|
+
for window in self.windows:
|
|
348
|
+
if hasattr(window, "dispatch"):
|
|
349
|
+
window.dispatch(event_name, payload)
|
|
350
|
+
return True
|
|
351
|
+
|
|
352
|
+
def toggle_inspector(self):
|
|
353
|
+
"""
|
|
354
|
+
Toggles the Pytron Inspector window.
|
|
355
|
+
"""
|
|
356
|
+
if self.inspector:
|
|
357
|
+
self.inspector.toggle()
|
|
358
|
+
return True
|
|
359
|
+
|
|
360
|
+
def load_plugins(self, plugins_dir: str):
|
|
361
|
+
"""
|
|
362
|
+
Discovers and loads plugins from the specified directory.
|
|
363
|
+
Each subdirectory with a manifest.json is considered a plugin.
|
|
364
|
+
"""
|
|
365
|
+
if not os.path.exists(plugins_dir):
|
|
366
|
+
self.logger.warning(f"Plugins directory not found: {plugins_dir}")
|
|
367
|
+
return
|
|
368
|
+
|
|
369
|
+
# Initialize plugin list in state if not present
|
|
370
|
+
if not hasattr(self.state, "plugins"):
|
|
371
|
+
self.state.plugins = []
|
|
372
|
+
|
|
373
|
+
# Resolve frontend dir for NPM dependency installation
|
|
374
|
+
frontend_dir = os.path.join(self.app_root, "frontend")
|
|
375
|
+
if not os.path.exists(frontend_dir):
|
|
376
|
+
# Try to find it by looking for package.json
|
|
377
|
+
potential = os.path.join(
|
|
378
|
+
self.app_root, self.config.get("url", "").split("/")[0]
|
|
379
|
+
)
|
|
380
|
+
if os.path.exists(os.path.join(potential, "package.json")):
|
|
381
|
+
frontend_dir = potential
|
|
382
|
+
|
|
383
|
+
# Filter and order by 'plugins' config list if present
|
|
384
|
+
allowed_plugins = self.config.get("plugins", [])
|
|
385
|
+
scan_items = []
|
|
386
|
+
|
|
387
|
+
if (
|
|
388
|
+
allowed_plugins
|
|
389
|
+
and isinstance(allowed_plugins, list)
|
|
390
|
+
and len(allowed_plugins) > 0
|
|
391
|
+
):
|
|
392
|
+
scan_items = allowed_plugins
|
|
393
|
+
else:
|
|
394
|
+
# Fallback to scanning directory
|
|
395
|
+
if os.path.exists(plugins_dir):
|
|
396
|
+
scan_items = sorted(os.listdir(plugins_dir))
|
|
397
|
+
|
|
398
|
+
for item in scan_items:
|
|
399
|
+
plugin_path = os.path.join(plugins_dir, item)
|
|
400
|
+
manifest_path = os.path.join(plugin_path, "manifest.json")
|
|
401
|
+
|
|
402
|
+
if os.path.isdir(plugin_path) and os.path.exists(manifest_path):
|
|
403
|
+
try:
|
|
404
|
+
self.logger.info(f"Loading plugin from {plugin_path}...")
|
|
405
|
+
plugin = Plugin(manifest_path)
|
|
406
|
+
|
|
407
|
+
# Dependency Check & Install
|
|
408
|
+
# For NPM, we usually want to install if there are any listed to be safe,
|
|
409
|
+
# as check_dependencies currently only verifies Python modules.
|
|
410
|
+
if not plugin.check_dependencies() or (
|
|
411
|
+
plugin.npm_dependencies and not plugin.check_js_dependencies()
|
|
412
|
+
):
|
|
413
|
+
self.logger.info(
|
|
414
|
+
f"Checking/Installing dependencies for {plugin.name}..."
|
|
415
|
+
)
|
|
416
|
+
# Pass the configured provider to ensure consistency
|
|
417
|
+
provider = self.config.get("frontend_provider", "npm")
|
|
418
|
+
plugin.install_dependencies(
|
|
419
|
+
frontend_dir=frontend_dir, provider=provider
|
|
420
|
+
)
|
|
421
|
+
|
|
422
|
+
plugin.load(self)
|
|
423
|
+
self.plugins.append(plugin)
|
|
424
|
+
|
|
425
|
+
# Update state with plugin metadata for the frontend
|
|
426
|
+
plugins_list = list(self.state.plugins or [])
|
|
427
|
+
plugin_meta = {
|
|
428
|
+
"name": plugin.name,
|
|
429
|
+
"version": plugin.version,
|
|
430
|
+
"ui_entry": (
|
|
431
|
+
f"pytron://app/plugins/{item}/{plugin.ui_entry}"
|
|
432
|
+
if plugin.ui_entry
|
|
433
|
+
else None
|
|
434
|
+
),
|
|
435
|
+
"slot": plugin.manifest.get(
|
|
436
|
+
"slot"
|
|
437
|
+
), # NEW: Support slot mapping
|
|
438
|
+
}
|
|
439
|
+
plugins_list.append(plugin_meta)
|
|
440
|
+
self.state.plugins = plugins_list
|
|
441
|
+
|
|
442
|
+
self.plugin_statuses.append(
|
|
443
|
+
{
|
|
444
|
+
"name": plugin.name,
|
|
445
|
+
"status": "loaded",
|
|
446
|
+
"version": plugin.version,
|
|
447
|
+
"path": plugin_path,
|
|
448
|
+
}
|
|
449
|
+
)
|
|
450
|
+
self.logger.info(
|
|
451
|
+
f"Plugin '{plugin.name}' (v{plugin.version}) loaded successfully."
|
|
452
|
+
)
|
|
453
|
+
|
|
454
|
+
self.publish("pytron:plugin-loaded", plugin_meta)
|
|
455
|
+
|
|
456
|
+
except Exception as e:
|
|
457
|
+
self.plugin_statuses.append(
|
|
458
|
+
{
|
|
459
|
+
"name": item,
|
|
460
|
+
"status": "error",
|
|
461
|
+
"error": str(e),
|
|
462
|
+
"path": plugin_path,
|
|
463
|
+
}
|
|
464
|
+
)
|
|
465
|
+
self.logger.error(f"Failed to load plugin at {plugin_path}: {e}")
|
|
466
|
+
|
|
467
|
+
def unload_plugins(self):
|
|
468
|
+
"""
|
|
469
|
+
Unloads all loaded plugins.
|
|
470
|
+
"""
|
|
471
|
+
for plugin in self.plugins:
|
|
472
|
+
try:
|
|
473
|
+
plugin.unload()
|
|
474
|
+
except Exception as e:
|
|
475
|
+
self.logger.error(f"Error unloading plugin {plugin.name}: {e}")
|
|
476
|
+
self.plugins.clear()
|
|
477
|
+
|
|
478
|
+
def audit_dependencies(self):
|
|
479
|
+
"""
|
|
480
|
+
Packaging Heuristic:
|
|
481
|
+
Traverses all exposed functions to find hidden dependencies (imports inside functions).
|
|
482
|
+
Triggers sys.audit('import') events for found modules so packaging tools can capture them.
|
|
483
|
+
"""
|
|
484
|
+
import inspect
|
|
485
|
+
import dis
|
|
486
|
+
import sys
|
|
487
|
+
|
|
488
|
+
visited = set()
|
|
489
|
+
|
|
490
|
+
def _report(name, file=None):
|
|
491
|
+
if name:
|
|
492
|
+
sys.audit("import", name, file, None, None, None)
|
|
493
|
+
|
|
494
|
+
def _inspect(func, depth=0):
|
|
495
|
+
if depth > 5:
|
|
496
|
+
return
|
|
497
|
+
try:
|
|
498
|
+
if func in visited:
|
|
499
|
+
return
|
|
500
|
+
visited.add(func)
|
|
501
|
+
except:
|
|
502
|
+
return
|
|
503
|
+
|
|
504
|
+
try:
|
|
505
|
+
# 1. Handle Classes/Instances (if stored directly)
|
|
506
|
+
if inspect.isclass(func) or (
|
|
507
|
+
not callable(func) and hasattr(func, "__dict__")
|
|
508
|
+
):
|
|
509
|
+
if hasattr(func, "__module__") and func.__module__:
|
|
510
|
+
_report(func.__module__)
|
|
511
|
+
for attr_name in dir(func):
|
|
512
|
+
if attr_name.startswith("_"):
|
|
513
|
+
continue
|
|
514
|
+
try:
|
|
515
|
+
val = getattr(func, attr_name)
|
|
516
|
+
if inspect.isfunction(val) or inspect.ismethod(val):
|
|
517
|
+
_inspect(val, depth + 1)
|
|
518
|
+
except:
|
|
519
|
+
pass
|
|
520
|
+
return
|
|
521
|
+
|
|
522
|
+
# Report the module of the function itself
|
|
523
|
+
if hasattr(func, "__module__") and func.__module__:
|
|
524
|
+
_report(func.__module__)
|
|
525
|
+
|
|
526
|
+
# Check method self if applicable
|
|
527
|
+
if inspect.ismethod(func) and hasattr(func, "__self__"):
|
|
528
|
+
if hasattr(func.__self__, "__module__"):
|
|
529
|
+
_report(func.__self__.__module__)
|
|
530
|
+
|
|
531
|
+
# 2. Inspect closures and globals
|
|
532
|
+
closures = inspect.getclosurevars(func)
|
|
533
|
+
|
|
534
|
+
for name, value in closures.globals.items():
|
|
535
|
+
if inspect.ismodule(value):
|
|
536
|
+
_report(value.__name__, getattr(value, "__file__", None))
|
|
537
|
+
elif hasattr(value, "__module__") and value.__module__:
|
|
538
|
+
_report(value.__module__)
|
|
539
|
+
if inspect.isfunction(value) or inspect.isclass(value):
|
|
540
|
+
_inspect(value, depth + 1)
|
|
541
|
+
|
|
542
|
+
for name, value in closures.nonlocals.items():
|
|
543
|
+
if hasattr(value, "__module__") and value.__module__:
|
|
544
|
+
_report(value.__module__)
|
|
545
|
+
if inspect.isfunction(value):
|
|
546
|
+
_inspect(value, depth + 1)
|
|
547
|
+
|
|
548
|
+
# 3. Bytecode Analysis
|
|
549
|
+
if hasattr(func, "__code__"):
|
|
550
|
+
for instr in dis.get_instructions(func):
|
|
551
|
+
if instr.opname == "IMPORT_NAME":
|
|
552
|
+
_report(instr.argval)
|
|
553
|
+
|
|
554
|
+
except Exception:
|
|
555
|
+
pass
|
|
556
|
+
|
|
557
|
+
# Trigger inspection for all registered entry points
|
|
558
|
+
self.logger.info("Running Packaging Heuristic on exposed functions...")
|
|
559
|
+
for info in self._exposed_functions.values():
|
|
560
|
+
func = info.get("func")
|
|
561
|
+
if func:
|
|
562
|
+
_inspect(func)
|
|
File without changes
|