Improve logical block spacing

Signed-off-by: Loren Eteval <loren.eteval@proton.me>
This commit is contained in:
Loren Eteval
2026-09-19 12:21:16 +08:00
parent 7c04feafe3
commit 28807cdf81
12 changed files with 103 additions and 0 deletions
+4
View File
@@ -135,9 +135,11 @@ class MultiprocessingRuntime(CoreRuntime):
raise RuntimeStartError('Runtime is already running')
self._closeProcess()
self._stopRequested = False
self._exitPublished = False
self._lastExit = None
self.setState(RuntimeState.Starting)
try:
@@ -229,6 +231,7 @@ class MultiprocessingRuntime(CoreRuntime):
def stop(self):
"""Idempotently terminate execution without disposing this object."""
self._stopRequested = True
self._monitor.stop()
self._output.stopTimer()
@@ -237,6 +240,7 @@ class MultiprocessingRuntime(CoreRuntime):
if process is None:
if self.state not in (RuntimeState.Created, RuntimeState.Disposed):
self.setState(RuntimeState.Exited)
return
self.setState(RuntimeState.Stopping)
+4
View File
@@ -193,17 +193,21 @@ class ProcessOutputRedirector:
or SystemRuntime.isPythonw()
):
entrypoint()
return
temporaryFile = ProcessOutputRedirector.TemporaryDir.filePath(str(uuid.uuid4()))
tmpFileStream = open(temporaryFile, 'w+b')
stdoutFileno = sys.stdout.fileno()
stderrFileno = sys.stderr.fileno()
sys.stdout.close()
sys.stderr.close()
os.dup2(tmpFileStream.fileno(), stdoutFileno)
os.dup2(tmpFileStream.fileno(), stderrFileno)
sys.stdout = tmpFileStream
sys.stderr = tmpFileStream
+2
View File
@@ -1817,6 +1817,7 @@ class AppQMessageBox(AppQTransientDialog):
baseSurfaceWidth = self.MultipleActionBaseWidth
baseSurfaceWidth = min(baseSurfaceWidth, maximumSurfaceWidth)
hasIcon = not self.iconLabel.isHidden()
iconSpace = 58 if hasIcon else 0
horizontalChrome = 56 + iconSpace
@@ -1843,6 +1844,7 @@ class AppQMessageBox(AppQTransientDialog):
naturalTextWidth,
)
textWidth = min(maximumTextWidth, preferredTextWidth)
textHeight = self._textContentHeight(textWidth)
maximumTextHeight = max(
72,
+2
View File
@@ -1523,6 +1523,7 @@ class ServerTableView(
"""Apply one repository reorder and preserve active and selected identities."""
selectedProfileIds = self._selectedProfileIds()
currentProfileId = self._currentProfileId()
activatedIndex = Storage.UserActivatedItemIndex()
profiles = Storage.UserServers()
activatedProfileId = (
@@ -1621,6 +1622,7 @@ class ServerTableView(
for profile in Storage.UserServers()
if profile.metadata.profileId in selected
}
destinations = [(_('No subscription'), '')]
destinations.extend(
(
+18
View File
@@ -350,6 +350,7 @@ def runNetworkProbe(iterations=100):
def runButtonOwnershipProbe(iterations=100):
"""Exercise button detach/reuse, native removal, and owner-first callbacks."""
application()
references = []
destroyed = []
@@ -358,37 +359,47 @@ def runButtonOwnershipProbe(iterations=100):
button = QPushButton('Fixture')
results = []
box.finished.connect(results.append)
for item in (box, button):
references.append(weakref.ref(item))
item.destroyed.connect(lambda *_args: destroyed.append(True))
del item
for _detach in range(3):
box.addButton(button, box.ButtonRole.AcceptRole)
box.setDefaultButton(button)
box.setEscapeButton(button)
box.removeButton(button)
button.click()
assert not results
assert box.defaultButton() is None and box.escapeButton() is None
assert button.receivers(QtCore.SIGNAL('clicked()')) == 0
box.addButton(button, box.ButtonRole.AcceptRole)
box.addButton(button, box.ButtonRole.AcceptRole)
box.open()
button.click()
processQtEvents()
assert results == [int(AppQDialog.DialogCode.Accepted)]
assert not isValid(box) and not isValid(button)
del box, button
box = AppQMessageBox()
button = box.addButton(box.StandardButton.Yes)
box.setDefaultButton(button)
box.setEscapeButton(button)
deleteQObject(button)
assert not box.buttons()
assert box.defaultButton() is None and box.escapeButton() is None
deleteQObject(box)
del box, button
@@ -396,14 +407,19 @@ def runButtonOwnershipProbe(iterations=100):
box = AppQMessageBox(parent=owner)
button = box.addButton(box.StandardButton.Yes)
box.buttonClicked.connect(lambda *_args: deleteQObject(owner))
button.click()
assert not isValid(box) and not isValid(button)
del box, button, owner
processQtEvents()
assert len(destroyed) == iterations * 2
assert all(reference() is None for reference in references)
assert not AppQDialog._openDialogs
return {
'buttonDetachReuse': iterations,
'nativeButtonRemoval': iterations,
@@ -677,6 +693,7 @@ def main():
'--pattern', choices=tuple(PROTOCOL_PATTERNS), default='alternating'
)
parser.add_argument('--close-method', choices=CLOSE_METHODS, default='reject')
arguments = parser.parse_args()
callbackErrors = []
@@ -684,6 +701,7 @@ def main():
sys.excepthook = lambda kind, value, traceback: callbackErrors.append(
(kind.__name__, str(value))
)
try:
print(json.dumps(runButtonOwnershipProbe(arguments.iterations), sort_keys=True))
print(json.dumps(runConfirmationProbe(arguments.iterations), sort_keys=True))
+12
View File
@@ -923,6 +923,7 @@ class GenerationLogManagerContractTest(unittest.TestCase):
autoClearEnabled=False,
)
manager.appendMany(tuple(f'initial {index}' for index in range(200)))
fullReads = []
suffixReads = []
originalFullRead = manager._entriesLocked
@@ -938,9 +939,11 @@ class GenerationLogManagerContractTest(unittest.TestCase):
manager._entriesLocked = fullRead
manager._entriesAfterLocked = suffixRead
page = LogPage(manager=manager)
page.resize(900, 420)
page.show()
self.assertTrue(waitFor(lambda: not page._entriesDirty))
self.assertEqual(len(fullReads), 1)
@@ -954,6 +957,7 @@ class GenerationLogManagerContractTest(unittest.TestCase):
page.plainText().splitlines(),
[entry.message for entry in manager.entries()],
)
page.close()
page.deleteLater()
collectAtBoundary()
@@ -1208,8 +1212,10 @@ class GenerationLogManagerContractTest(unittest.TestCase):
def onAdded(entry):
added.append(entry.sequence)
manager.snapshot()
manager.entryCount()
if not lockWasFreeDuringSignal:
completed = threading.Event()
@@ -1221,21 +1227,27 @@ class GenerationLogManagerContractTest(unittest.TestCase):
worker.start()
lockWasFreeDuringSignal.append(completed.wait(2))
worker.join(2)
if entry.categoryId == CORE_LOG_CATEGORY:
manager.clear(runtimeOnly=True)
manager.entryAdded.connect(onAdded)
manager.entriesCleared.connect(cleared.append)
manager.entriesChanged.connect(changed.append)
manager.append('core', CORE_LOG_CATEGORY)
for index in range(20):
manager.append(f'application {index}')
processQtEvents()
self.assertEqual(len(added), 21)
self.assertEqual(cleared, [manager._runtimeCategoryIds])
self.assertEqual(changed, [21])
self.assertEqual(lockWasFreeDuringSignal, [True])
self.assertEqual(manager.entryCount(CORE_LOG_CATEGORY), 0)
_assertManagerInvariants(self, manager)
def testAppendAndClearCannotSplitOneAtomicMutation(self):
+3
View File
@@ -697,10 +697,12 @@ class ProfileTestServiceTest(unittest.TestCase):
self.assertTrue(
server.listen(QtNetwork.QHostAddress.SpecialAddress.LocalHost, 0)
)
first = self._profile('first', '127.0.0.1', server.serverPort())
second = self._profile('second', '127.0.0.1', server.serverPort())
manager = self._manager((first, second))
scheduler = manager._latencyScheduler
guiEventDelivered = threading.Event()
try:
@@ -714,6 +716,7 @@ class ProfileTestServiceTest(unittest.TestCase):
)
self.assertIs(scheduler.tcpingEngine.thread(), scheduler.tcpingThread)
self.assertIsNot(scheduler.tcpingThread, application().thread())
self.assertTrue(waitFor(lambda: not scheduler.tcpingRequests, timeout=2000))
self.assertTrue(guiEventDelivered.is_set())
self.assertRegex(first.metadata.latency, r'^\d+ms$')
+8
View File
@@ -249,24 +249,32 @@ class ServerTableQtInteractionTest(unittest.TestCase):
"""The fast row projection retains regex, literal and live-cell semantics."""
with isolatedSettings():
table = self._table(('alpha[1]', 'beta'))
try:
table.search('alpha[1]', regex=False)
self.assertEqual(table.proxyModel.rowCount(), 1)
table.search('ALPHA', caseSensitive=True)
self.assertEqual(table.proxyModel.rowCount(), 0)
table.search('ALPHA')
self.assertEqual(table.proxyModel.rowCount(), 1)
table.search('23 ms')
self.assertEqual(table.proxyModel.rowCount(), 0)
profile = Storage.UserServers()[1]
profile.metadata.latency = '23 ms'
table.sourceModel.emitRowChanged(1)
self.assertEqual(table.proxyModel.rowCount(), 1)
self.assertEqual(
table.sourceRowFromProxyIndex(table.proxyModel.index(0, 0)), 1
)
profile.metadata.latency = '42 ms'
table.sourceModel.emitRowChanged(1)
self.assertEqual(table.proxyModel.rowCount(), 0)
finally:
self._destroyTable(table)
+22
View File
@@ -152,20 +152,25 @@ class QtLifetimeTest(unittest.TestCase):
def testRemovedMessageBoxButtonDisconnectsAndCanBeReused(self):
"""Detaching a button ends only the box-owned signal and role lifetime."""
application()
with isolatedSettings():
box = AppQMessageBox()
button = QPushButton('Reusable button')
finished = []
externalClicks = []
box.finished.connect(finished.append)
button.clicked.connect(lambda: externalClicks.append(True))
try:
for _ in range(30):
box.addButton(button, box.ButtonRole.AcceptRole)
box.setDefaultButton(button)
box.setEscapeButton(button)
box.removeButton(button)
button.click()
self.assertEqual(finished, [])
self.assertIsNone(box.defaultButton())
self.assertIsNone(box.escapeButton())
@@ -173,27 +178,34 @@ class QtLifetimeTest(unittest.TestCase):
self.assertEqual(button.receivers(QtCore.SIGNAL('clicked()')), 1)
self.assertEqual(len(externalClicks), 30)
box.addButton(button, box.ButtonRole.AcceptRole)
box.addButton(button, box.ButtonRole.AcceptRole)
box.open()
button.click()
processQtEvents()
self.assertEqual(finished, [int(AppQDialog.DialogCode.Accepted)])
self.assertFalse(isValid(box))
self.assertFalse(isValid(button))
finally:
if isValid(box):
deleteQObject(box)
if isValid(button):
deleteQObject(button)
processQtEvents()
def testReplacingMessageBoxButtonsReleasesOldDefaultAndEscape(self):
"""A retained dialog must not retain removed standard-button wrappers."""
application()
with isolatedSettings():
box = AppQMessageBox()
references = []
try:
for _ in range(30):
box.setStandardButtons(box.StandardButton.Yes)
@@ -201,11 +213,14 @@ class QtLifetimeTest(unittest.TestCase):
references.append(weakref.ref(button))
box.setDefaultButton(button)
box.setEscapeButton(button)
box.setStandardButtons(box.StandardButton.No)
del button
processQtEvents()
self.assertIsNone(box.defaultButton())
self.assertIsNone(box.escapeButton())
self.assertTrue(all(reference() is None for reference in references))
finally:
deleteQObject(box)
@@ -214,14 +229,18 @@ class QtLifetimeTest(unittest.TestCase):
def testNativeButtonDestructionRemovesMessageBoxRegistrations(self):
"""Deleting an attached button cannot leave invalid wrapper roles behind."""
application()
with isolatedSettings():
box = AppQMessageBox()
try:
for _ in range(30):
button = box.addButton(box.StandardButton.Yes)
box.setDefaultButton(button)
box.setEscapeButton(button)
deleteQObject(button)
self.assertEqual(box.buttons(), [])
self.assertIsNone(box.defaultButton())
self.assertIsNone(box.escapeButton())
@@ -233,14 +252,17 @@ class QtLifetimeTest(unittest.TestCase):
def testMessageBoxCallbackMayDestroyItsOwner(self):
"""Button activation cannot finish a box destroyed by its own listener."""
application()
with isolatedSettings():
owner = QWidget()
box = AppQMessageBox(parent=owner)
button = box.addButton(box.StandardButton.Yes)
box.buttonClicked.connect(lambda *_args: deleteQObject(owner))
with mock.patch('sys.excepthook') as exceptionHook:
button.click()
processQtEvents()
exceptionHook.assert_not_called()
self.assertFalse(isValid(box))
self.assertFalse(isValid(button))
+10
View File
@@ -165,6 +165,7 @@ class HttpGetManagerLifetimeTest(unittest.TestCase):
for _ in range(20):
manager = managerType()
reply = _ManagedReply(manager)
destroyed = []
reply.destroyed.connect(lambda *_a: destroyed.append(True))
completion = []
@@ -178,21 +179,25 @@ class HttpGetManagerLifetimeTest(unittest.TestCase):
manager.webGET(
'https://invalid.test', logActionMessage=False
)
manager.successCallback = destroyFromCallback
manager.completionCallback = (
lambda **_k: completion.append(True)
)
else:
manager.request('https://invalid.test', 'fixture')
manager.completed.connect(destroyFromCallback)
with patch('sys.excepthook') as exceptionHook:
reply.finished.emit()
processQtEvents()
exceptionHook.assert_not_called()
self.assertEqual(destroyed, [True])
self.assertFalse(isValid(reply))
self.assertFalse(getattr(manager, contextAttribute))
if isinstance(manager, HttpGetManager):
self.assertEqual(
completion, [] if deleteManager else [True]
@@ -200,17 +205,22 @@ class HttpGetManagerLifetimeTest(unittest.TestCase):
finally:
if isValid(manager):
deleteQObject(manager)
processQtEvents()
def testEndpointCancellationToleratesOwnerDestructionDuringAbort(self):
"""An abort listener may delete the manager and its other pending replies."""
manager = ProxyEndpointHttpClient()
replies = [_ManagedReply(manager), _ManagedReply(manager)]
for index, reply in enumerate(replies):
with patch.object(manager, 'get', lambda _request: reply):
manager.request('https://invalid.test', index)
replies[0].abort = lambda: deleteQObject(manager)
manager.cancelAll()
self.assertFalse(isValid(manager))
self.assertTrue(all(not isValid(reply) for reply in replies))
self.assertEqual(manager._pendingRequests, {})
+12
View File
@@ -1380,12 +1380,15 @@ class SubscriptionManagerTest(TestCase):
manager = self._manager()
started = threading.Event()
release = threading.Event()
context = {'unique': 'group-a', 'batchId': 1, 'requestVersion': 1}
subscriptions = {'group-a': self._subscription()}
manager._requestVersions['group-a'] = 1
context['webURL'] = subscriptions['group-a']['webURL']
manager._batches[1] = _SubscriptionBatchState({('group-a', 1)}, True, [], [])
manager._handleImportedResult = mock.Mock()
completed = []
manager.updateCompleted.connect(completed.append)
@@ -1402,6 +1405,7 @@ class SubscriptionManagerTest(TestCase):
try:
manager._startPreparationJob('import', context, work)
self.assertTrue(started.wait(2))
manager.stopUpdates()
self.assertEqual(manager._batches, {})
@@ -1410,6 +1414,7 @@ class SubscriptionManagerTest(TestCase):
release.set()
self.assertTrue(waitFor(lambda: not manager._preparationJobs))
manager._handleImportedResult.assert_not_called()
self.assertEqual(completed, [])
finally:
@@ -1649,6 +1654,7 @@ class SubscriptionManagerTest(TestCase):
manager = self._manager({})
manager.ShutdownWarningMilliseconds = 1
manager._preparationPool.setMaxThreadCount(1)
started = threading.Event()
release = threading.Event()
queuedStarted = threading.Event()
@@ -1666,21 +1672,26 @@ class SubscriptionManagerTest(TestCase):
self.assertTrue(
all(job.cancelled.is_set() for job in manager._preparationJobs.values())
)
release.set()
try:
manager._startPreparationJob('import', {}, work)
self.assertTrue(started.wait(2))
manager._startPreparationJob('import', {}, lambda _: queuedStarted.set())
with mock.patch(
'Furious.Service.SubscriptionManager.logger.warning',
side_effect=afterWarning,
) as warning:
manager.shutdown()
manager.shutdown()
warning.assert_called_once()
processQtEvents()
self.assertFalse(queuedStarted.is_set())
self.assertEqual(manager._preparationPool.activeThreadCount(), 0)
self.assertEqual(manager._preparationJobs, {})
@@ -1690,6 +1701,7 @@ class SubscriptionManagerTest(TestCase):
release.set()
manager.shutdown()
manager.deleteLater()
processQtEvents()
def testShutdownRejectsNewWorkAndVersionlessCompletions(self):
+6
View File
@@ -1627,14 +1627,17 @@ class UnifiedLogPageTest(unittest.TestCase):
page = LogPage(manager=manager)
self.addCleanup(self.disposePage, page)
self.addCleanup(QTest.keyRelease, page.textBrowser, QtCore.Qt.Key_Control)
manager.append('alpha log', APPLICATION_LOG_CATEGORY)
page.show()
page.activateWindow()
self.assertRendered(page)
page.textBrowser.setFocus()
processQtEvents()
QTest.keyClick(page.textBrowser, QtCore.Qt.Key_F, QtCore.Qt.ControlModifier)
self.assertTrue(waitFor(page.searchLineEdit.hasFocus))
QTest.keyClicks(page.searchLineEdit, 'alpha')
QTest.keyClick(
page.searchLineEdit, QtCore.Qt.Key_A, QtCore.Qt.ControlModifier
@@ -1642,12 +1645,15 @@ class UnifiedLogPageTest(unittest.TestCase):
QTest.keyClick(
page.searchLineEdit, QtCore.Qt.Key_C, QtCore.Qt.ControlModifier
)
self.assertEqual(application().clipboard().text(), 'alpha')
self.assertFalse(page.textBrowser.textCursor().hasSelection())
self.assertRendered(page)
page.textBrowser.setFocus()
QTest.keyClick(page.textBrowser, QtCore.Qt.Key_A, QtCore.Qt.ControlModifier)
QTest.keyClick(page.textBrowser, QtCore.Qt.Key_C, QtCore.Qt.ControlModifier)
self.assertEqual(application().clipboard().text(), 'alpha log')
def testFindShortcutFollowsTheVisiblePage(self):