class Purgatory: """ ------------------------------------------------------------------------------ [1.5] A simple fixed-length queue of 'numsouls' objects. Part of program PC-Phone USB Sync, with same terms of use. Used to temporarily retain Python objects sent back to Java via pyjnius on Android, per a theory that they might be garbage collected on the Python side before used by Java and thus trigger crashes. Referencing objects in the queue postpones their Python garbage collection. This could explain a Java exception that occurred for an insets object, which is passed from Java to the Python pyjnius edge-to-edge callback onApplyWindowInsets and then returned as the callback's result to Java. In some cases (e.g., screen switches on a Fold7), there are three such callbacks in rapid succession, so simply saving a single object in self is not enough. The Java info: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.view.WindowInsets.isConsumed()' on a null object reference" [in java.lang.reflect.Method.invoke(Native Method)] This also may be entirely moot. Two such crashes were observed in the logcat within 9 minutes of each other and the app did seem to vanish during a screen switch, but the history on this is impossible to reconstruct. There was also unrelated prototyping in the same timeframe that crashed in the insets callback for known unrelated coding errors, and inadvertently pressing Android Back twice while juggling the device to switch screens can also exit the app. Moreover, the crashes could not be recreated, and no others have been seen or reported, even though insets callbacks have been used for 6 months since 1.4.0. In addition, pyjnius' docs state that the callback function itself must have a retained reference but say nothing about function return values, and pyjnius' return-value code seems sound on first survey. A general web search was ambiguous, and an AI result advised saves - perhaps stupidly. But race conditions are sporadic by nature, threads may happen on either side of the Python/Java fence, and the new Splitter max_size update on insets callbacks could conceivably aggravate a looming threat. Hence, this queue is used as a just-in-case safety measure. It's harmless and trivial if it's unnecessary, but vanishing apps are a Bad Thing. Update: it's now nearly certain that the crashes this module addresses were due to unrelated errors or inadvertent Back taps during screen changes, not garbage collection. A later app vanish yielded a normal exit for Back tap in the logcat. Another 1.5 mod now pauses the app on Android Back instead of closing it, so the app will be suspended in Recents if (when) this recurs. ------------------------------------------------------------------------------ """ def __init__(self, numsouls=6): self.holding = [0] * numsouls def retain(self, object, trace=False): self.holding.pop(0) # may garbage collect now self.holding.append(object) # stage next soul in queue if trace: print(f'Purgatory: {self.holding}') if __name__ == '__main__': retainer = Purgatory() for object in 'Race Condition!': retainer.retain(object, True)