mirror of
https://github.com/LorenEteval/Furious.git
synced 2026-10-12 09:18:26 +03:00
71 lines
6.7 KiB
Markdown
71 lines
6.7 KiB
Markdown
# Platform and compatibility guidance
|
|
|
|
Inherit the [nearest parent guide](../AGENTS.md).
|
|
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.
|
|
|
|
- `Frozenlib` is 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.
|
|
- `PythonCompatibility` centralizes 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.py` exercises
|
|
strict legacy API shapes and real blocked/queued workers.
|
|
- `Globals` exposes 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.qObjectIsValid` checks native QObject validity and deliberately accepts non-QObjects, including `None`.
|
|
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.
|
|
- `AppSettings` keys 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 reconstruct `Storage` backends. 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.
|
|
- `CleanupOnExit` and 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
|
|
in `tests/test_frozenlib.py` cover 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.py` is generated from `Resources.qrc` and 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.py` and the
|
|
mocked platform cases in `tests/test_connection_startup_async.py`.
|