mirror of
https://github.com/LorenEteval/Furious.git
synced 2026-10-10 08:18:15 +03:00
6.9 KiB
6.9 KiB
Platform and compatibility guidance
Inherit the nearest parent guide.
This scope owns settings registration, compatibility primitives, resource lookup and host integration.
Preferences, helper results and observed OS state are distinct.
Read Furious/Frozenlib/AppSettings.py with tests/test_frozenlib.py; paths are relative to this source tree's root.
Frozenlibis the low-level settings, platform, compatibility, and broad export surface. Keep imports cheap, cross-platform, and free of application/UI construction; preserve curated wildcard exports until consumers and public-import tests migrate together.PythonCompatibilitycentralizes the supported standard-library differences in string affixes, installed metadata/entry points, and executor shutdown. Select implementations once at module import, using interpreter version or metadata API capability as appropriate; calls do not repeat those decisions. Fetch installed metadata on demand rather than scanning distributions during import. Its implementation uses only the standard library; Frozenlib still has its existing Qt bootstrap. Executor callers close their own submission path and supply all uncancelled pending futures for the Python 3.8 fallback. Cancelling those futures does not stop an already-running call; retain that distinction in ownership tests.tests/test_python_compatibility.pyexercises strict legacy API shapes and real blocked/queued workers.Globalsexposes only deliberate application-lifetime owners. Accessors may be absent during partial startup, isolated tests, or teardown; do not add fallback global owners that create competing lifecycles.Mixins.qObjectIsValidchecks native QObject validity and deliberately accepts non-QObjects, includingNone. Check required presence and plain resource state separately; a Python editor binding needs checks of its Qt fields. Neither one-object nor grouped validity checks provide ownership, thread affinity, or generation freshness. Use the Qt scope's boundary rule before adding checks to a caller. This helper supplies a predicate, not a reason to check every method; pure reads and computations do not invalidate an already-valid receiver.AppSettingskeys include preferences and encoded repository blobs. Preserve names, defaults, string/binary encodings, migrations, and import-time registration.AppSettings.get()can persist a default or repair an invalid preference; it is not an observational reader like a copied customization projection. Distinguish desired preferences, helper-reported success, and independently observed host state; a Boolean success is not an OS read-back guarantee. Startup-registration success is persisted only after its helper reports success. Settings storage and cached repository objects are distinct lifetimes: changing a QSettings identity does not reconstructStoragebackends. Tests that replace settings must isolate both boundaries before exercising cleanup or restoration. Application-engine identifiers are shared constants, selection/default policy belongs to SettingsController, and each engine's customization belongs to its own repository. SOCKS endpoint helpers format/validate transit addresses without selecting an engine, launching a runtime, or applying host networking.- Keep proxy, DNS, routing, TUN, startup registration, session callbacks, external commands, and platform detection here or behind a runtime boundary so tests can replace them completely. Windows, macOS, Linux, Flatpak, AppImage, and older platform paths are distinct capabilities; never generalize from the current host.
- Check each helper's real result contract. System Proxy set/off/pac return True for reported host success, False for
failure, and None when policy deliberately leaves host settings unchanged. Startup registration and some routing
helpers return Booleans; script-mode startup registration intentionally does nothing. Preserve these distinctions
at callers instead of treating absence of an exception as confirmed host state. A skipped (
None) operation must not be presented as either a failed mutation or verified host configuration. Check every native command result, including each enabled macOS network service, and bound host-command waits at this boundary. A per-command timeout is not a deadline for a loop over services or routes. Multi-step host mutation may be partial when a later command fails; a False result does not establish that earlier effects were rolled back. - Prefer argument vectors over shell strings. Require host helpers to bound individual external calls; workflow callers also account for the number of calls, retries, privilege interactions, and rollback. A helper timeout and a total operation deadline answer different questions; build-time commands and GUI-time mutation have different budgets.
- Windows proxy calls, Linux desktop settings/host bridging, and macOS network-service operations are distinct paths. Application tun2socks host routing differs from backend-native TUN; preserve privilege, DNS restoration, and managed route cleanup for the selected path. Some helpers block synchronously and need caller-level responsiveness review.
- Own exact native threads/processes/handles and clear stale daemon references. Externally keyed caches are bounded and no cache/weak pool captures QObject instances or bound methods accidentally.
CleanupOnExitand translation/theme/connection pools are weak registries, not owners. Native destruction must remove membership even while another Python reference retains an invalid wrapper. Cleanup normally de-duplicates by type; repeated instances with separate resources require per-instance registration or a containing cleanup stage. Membership neither keeps active objects alive nor proves every instance drained. When a callback keeps resources after failure, inspect the containing shutdown caller as well as the registry; registry iteration is not an automatic retry scheduler. Notification/cleanup snapshots must recheck each recipient's native validity immediately before delivery: an earlier callback can destroy a later recipient after the initial pool prune. The peer-destruction cases intests/test_frozenlib.pycover connection, theme, translation, and cleanup dispatch. Removing native-dead pool members does not cancel an operation or invalidate a still-live generation; those decisions remain with the controller/service that owns the work.AppResources.pyis generated fromResources.qrcand referenced assets. Change the manifest/input files and regenerate with the compatible PySide6 resource compiler; never hand-edit generated resource code.- Verify every affected OS branch with mocked host calls, plus persistence-on-failure, bounded cleanup, import-time
side effects, sensitive logging, stale handles/daemons, and cache growth. Use
tests/test_frozenlib.pyand the mocked platform cases intests/test_connection_startup_async.py.