from pathlib import Path import ast,hashlib,json folder=Path(__file__).resolve().parent;payload=folder/'payload';target=Path('C:/wechat_rpa') # A removed QScreen may already have lost its underlying Qt object. old=''' if previous is not None: for signal in (previous.availableGeometryChanged, previous.logicalDotsPerInchChanged): try: signal.disconnect(self._display_metrics_changed) except (RuntimeError, TypeError): pass''' new=''' if previous is not None: for name in ("availableGeometryChanged", "logicalDotsPerInchChanged"): try: getattr(previous, name).disconnect(self._display_metrics_changed) except (RuntimeError, TypeError): pass''' for root in [payload,target]: p=root/'wechat_gui_qt.py';s=p.read_text(encoding='utf-8');assert s.count(old)==1 s=s.replace(old,new);ast.parse(s);p.write_text(s,encoding='utf-8',newline='\n') p=root/'test_ui_display.py';s=p.read_text(encoding='utf-8') s+=''' def test_monitor_removal_tolerates_a_deleted_screen_object(self): class DeletedScreen: def __getattr__(self, name): raise RuntimeError("Internal C++ object already deleted") host=DisplayHost(QRect(0,0,960,540));host._watched_screen=DeletedScreen() with mock.patch.object(ui.QTimer,'singleShot'): host._screen_changed(host.screen()) self.assertIs(host._watched_screen,host.screen()) host.deleteLater() ''' ast.parse(s);p.write_text(s,encoding='utf-8',newline='\n') p=root/'assets/ui/console-responsive.css';s=p.read_text(encoding='utf-8') s=s.replace('#stage .anomaly, #stage .anomaly-card { flex-wrap: wrap; }\n','').replace('#stage .anomaly-action { max-width: 100%; }\n','') p.write_text(s,encoding='utf-8',newline='\n') print('Screen-removal guard and regression added')