diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c3c2e73ab..d9ba31f5a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -60,7 +60,7 @@ repos: - id: rm-unneeded-f-str - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.0.278 + rev: v0.0.280 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] diff --git a/angrmanagement/data/analysis_options.py b/angrmanagement/data/analysis_options.py index 6cd060050..15f7b0c29 100644 --- a/angrmanagement/data/analysis_options.py +++ b/angrmanagement/data/analysis_options.py @@ -38,7 +38,7 @@ class AnalysesConfiguration: def __init__(self, analyses: Sequence["AnalysisConfiguration"], instance): self.instance = instance - self.analyses: Sequence["AnalysisConfiguration"] = analyses + self.analyses: Sequence[AnalysisConfiguration] = analyses def __len__(self): return len(self.analyses) diff --git a/angrmanagement/data/instance.py b/angrmanagement/data/instance.py index cb1b01870..4dcb23e7d 100644 --- a/angrmanagement/data/instance.py +++ b/angrmanagement/data/instance.py @@ -49,7 +49,7 @@ def __init__(self): ) self._live = False - self.variable_recovery_job: Optional["VariableRecoveryJob"] = None + self.variable_recovery_job: Optional[VariableRecoveryJob] = None self._analysis_configuration = None self.jobs = [] diff --git a/angrmanagement/data/jobs/variable_recovery.py b/angrmanagement/data/jobs/variable_recovery.py index 42f0f4f32..a43b9500e 100644 --- a/angrmanagement/data/jobs/variable_recovery.py +++ b/angrmanagement/data/jobs/variable_recovery.py @@ -29,7 +29,7 @@ def __init__( self.on_variable_recovered = on_variable_recovered self.workers = workers self.ccc = None - self.instance: Optional["Instance"] = None + self.instance: Optional[Instance] = None self.started = False self.auto_start = auto_start self.func_addr = func_addr diff --git a/angrmanagement/data/trace.py b/angrmanagement/data/trace.py index 3428648e1..6d3ea0166 100644 --- a/angrmanagement/data/trace.py +++ b/angrmanagement/data/trace.py @@ -29,7 +29,7 @@ class BintraceTrace(Trace): def __init__(self, trace: "bintrace.Trace"): assert BintraceTrace.trace_backend_enabled() - self.trace: "bintrace.Trace" = trace + self.trace: bintrace.Trace = trace @property def source(self) -> str: diff --git a/angrmanagement/logic/commands/command.py b/angrmanagement/logic/commands/command.py index 2bcf7b4db..eda6de85b 100644 --- a/angrmanagement/logic/commands/command.py +++ b/angrmanagement/logic/commands/command.py @@ -63,8 +63,8 @@ def __init__(self, name: str, caption: str, action: Callable, view_class: Type[" self._name = name self._caption = caption self._action: Callable = action - self._view_class: Type["BaseView"] = view_class - self._workspace: "Workspace" = workspace + self._view_class: Type[BaseView] = view_class + self._workspace: Workspace = workspace @property def is_visible(self) -> bool: diff --git a/angrmanagement/logic/commands/command_manager.py b/angrmanagement/logic/commands/command_manager.py index f05f73c80..96a98d70c 100644 --- a/angrmanagement/logic/commands/command_manager.py +++ b/angrmanagement/logic/commands/command_manager.py @@ -10,7 +10,7 @@ class CommandManager: """ def __init__(self): - self._commands: Dict[str, "Command"] = {} + self._commands: Dict[str, Command] = {} def register_command(self, command: "Command"): assert command.name not in self._commands, "Command by this name already registered" diff --git a/angrmanagement/plugins/base_plugin.py b/angrmanagement/plugins/base_plugin.py index 2a82070cc..8494296f1 100644 --- a/angrmanagement/plugins/base_plugin.py +++ b/angrmanagement/plugins/base_plugin.py @@ -31,7 +31,7 @@ class BasePlugin: __i_hold_this_abstraction_token = True def __init__(self, workspace): - self.workspace: Optional["Workspace"] = workspace + self.workspace: Optional[Workspace] = workspace _l.info("Loaded plugin %s", self.__class__.__name__) # valid things that we want you do be able to do in __init__: diff --git a/angrmanagement/ui/dialogs/analysis_options.py b/angrmanagement/ui/dialogs/analysis_options.py index 665c46d4b..3fa5df1fe 100644 --- a/angrmanagement/ui/dialogs/analysis_options.py +++ b/angrmanagement/ui/dialogs/analysis_options.py @@ -207,7 +207,7 @@ class AnalysisOptionsDialog(QDialog): def __init__(self, analyses: AnalysesConfiguration, workspace: "Workspace", parent=None): super().__init__(parent) - self._workspace: "Workspace" = workspace + self._workspace: Workspace = workspace self._analyses: AnalysesConfiguration = analyses self._mappers: Sequence[AnalysisOptionWidgetMapper] = [] self.setWindowTitle("Run Analysis") diff --git a/angrmanagement/ui/dialogs/assemble_patch.py b/angrmanagement/ui/dialogs/assemble_patch.py index 8368c95c4..e900a76e3 100644 --- a/angrmanagement/ui/dialogs/assemble_patch.py +++ b/angrmanagement/ui/dialogs/assemble_patch.py @@ -40,7 +40,7 @@ class AssemblePatchDialog(QDialog): def __init__(self, address: int, instance: "Instance", parent=None): super().__init__(parent) - self.instance: "Instance" = instance + self.instance: Instance = instance self._patch_addr: int = address block = self.instance.project.factory.block(self._patch_addr) diff --git a/angrmanagement/ui/dialogs/command_palette.py b/angrmanagement/ui/dialogs/command_palette.py index c771ad640..cff848725 100644 --- a/angrmanagement/ui/dialogs/command_palette.py +++ b/angrmanagement/ui/dialogs/command_palette.py @@ -22,7 +22,7 @@ class PaletteModel(QAbstractItemModel): def __init__(self, workspace: "Workspace"): super().__init__() - self.workspace: "Workspace" = workspace + self.workspace: Workspace = workspace self._available_items: List[Any] = self.get_items() self._item_to_caption: Dict[Any, str] = { item: self.get_caption_for_item(item) for item in self._available_items diff --git a/angrmanagement/ui/dialogs/data_dep_graph_search.py b/angrmanagement/ui/dialogs/data_dep_graph_search.py index fe8ee3cc1..95d4f806a 100644 --- a/angrmanagement/ui/dialogs/data_dep_graph_search.py +++ b/angrmanagement/ui/dialogs/data_dep_graph_search.py @@ -20,7 +20,7 @@ def __init__(self, parent: QtWidgets.QWidget, data_dep_graph): self._curr_value_text = "" self._curr_addr_text = "" self._curr_name_text = "" - self._rel_nodes: List["QDataDepGraphBlock"] = [] + self._rel_nodes: List[QDataDepGraphBlock] = [] self._curr_search_idx = -1 self._name_line_edit = QtWidgets.QLineEdit(self) @@ -99,7 +99,7 @@ def _node_predicate(node: "BaseDepNode"): curr_search_node.selected = False self._curr_search_idx = (self._curr_search_idx + 1) % len(self._rel_nodes) - search_node: "QDataDepGraphBlock" = self._rel_nodes[self._curr_search_idx] + search_node: QDataDepGraphBlock = self._rel_nodes[self._curr_search_idx] search_node.selected = True self._data_dep_graph.zoom(reset=True) diff --git a/angrmanagement/ui/dialogs/load_plugins.py b/angrmanagement/ui/dialogs/load_plugins.py index 9505433b6..091b9850e 100644 --- a/angrmanagement/ui/dialogs/load_plugins.py +++ b/angrmanagement/ui/dialogs/load_plugins.py @@ -32,7 +32,7 @@ class QPluginListWidgetItem(QListWidgetItem): def __init__(self, plugin_desc, **kwargs): super().__init__(**kwargs) - self.plugin_desc: "PluginDescription" = plugin_desc + self.plugin_desc: PluginDescription = plugin_desc self.setText(plugin_desc.name) @@ -47,7 +47,7 @@ class LoadPlugins(QDialog): def __init__(self, plugin_mgr, parent=None): super().__init__(parent) - self._pm: "PluginManager" = plugin_mgr + self._pm: PluginManager = plugin_mgr self._installed_plugin_list: QListWidget self.setWindowTitle("Installed Plugins") diff --git a/angrmanagement/ui/dialogs/rename_node.py b/angrmanagement/ui/dialogs/rename_node.py index 4e496abad..e5ca696d8 100644 --- a/angrmanagement/ui/dialogs/rename_node.py +++ b/angrmanagement/ui/dialogs/rename_node.py @@ -63,7 +63,7 @@ def __init__( self._code_view = code_view self._node = node - self._func: Optional["Function"] = func + self._func: Optional[Function] = func self._name_box: NodeNameBox = None self._status_label = None diff --git a/angrmanagement/ui/main_window.py b/angrmanagement/ui/main_window.py index 5ac38df97..787f87b91 100644 --- a/angrmanagement/ui/main_window.py +++ b/angrmanagement/ui/main_window.py @@ -77,7 +77,7 @@ class DockShortcutEventFilter(QObject): def __init__(self, main_window: "MainWindow"): super().__init__() - self._main_window: "MainWindow" = main_window + self._main_window: MainWindow = main_window def eventFilter(self, qobject, event): if event.type() == QEvent.KeyPress and QKeySequence(event.keyCombination()) == QKeySequence("Ctrl+Shift+P"): @@ -97,7 +97,7 @@ class ShiftShiftEventFilter(QObject): def __init__(self, main_window: "MainWindow"): super().__init__() - self._main_window: "MainWindow" = main_window + self._main_window: MainWindow = main_window self._press_count: int = 0 self._last_press_time: float = 0 self._did_process_qwindow_event: bool = False @@ -151,7 +151,7 @@ def __init__(self, app: Optional["QApplication"] = None, parent=None, show=True, # initialization self.setMinimumSize(QSize(400, 400)) - self.app: Optional["QApplication"] = app + self.app: Optional[QApplication] = app self.workspace: Workspace = None self.dock_manager: QtAds.CDockManager self._dock_shortcut_event_filter = DockShortcutEventFilter(self) diff --git a/angrmanagement/ui/toolbars/debug_toolbar.py b/angrmanagement/ui/toolbars/debug_toolbar.py index 571f2b0ec..bd7a9dcf9 100644 --- a/angrmanagement/ui/toolbars/debug_toolbar.py +++ b/angrmanagement/ui/toolbars/debug_toolbar.py @@ -62,8 +62,8 @@ class DebugToolbar(Toolbar): def __init__(self, main_window: "MainWindow"): super().__init__(main_window, "DebugToolbar") - self.workspace: "Workspace" = main_window.workspace - self.instance: "Instance" = self.workspace.main_instance + self.workspace: Workspace = main_window.workspace + self.instance: Instance = self.workspace.main_instance self._cont_backward_act = ToolbarAction( qta.icon("fa5s.fast-backward", color=Conf.palette_buttontext), diff --git a/angrmanagement/ui/views/call_explorer_view.py b/angrmanagement/ui/views/call_explorer_view.py index a87531d3e..249f1810a 100644 --- a/angrmanagement/ui/views/call_explorer_view.py +++ b/angrmanagement/ui/views/call_explorer_view.py @@ -27,7 +27,7 @@ class CallTreeModel(QStandardItemModel): Headers = ["Function"] def hasChildren(self, index): - item: Optional["CallTreeItem"] = self.itemFromIndex(index) + item: Optional[CallTreeItem] = self.itemFromIndex(index) if isinstance(item, CallTreeItem): return item.expandable return super().hasChildren(index) diff --git a/angrmanagement/ui/views/data_dep_view.py b/angrmanagement/ui/views/data_dep_view.py index 5b6f022a7..0ef6f707b 100644 --- a/angrmanagement/ui/views/data_dep_view.py +++ b/angrmanagement/ui/views/data_dep_view.py @@ -38,7 +38,7 @@ def __init__(self, workspace, instance, default_docking_position, *args, **kwarg self.base_caption = "Data Dependency" # Get all instructions in the program - self._instructions: Dict[int, "CsInsn"] = {} + self._instructions: Dict[int, CsInsn] = {} inst = self.instance for _, func in inst.kb.functions.items(): for block in func.blocks: @@ -46,7 +46,7 @@ def __init__(self, workspace, instance, default_docking_position, *args, **kwarg for ins in disass.insns: self._instructions[ins.address] = ins - self._end_state: Optional["SimState"] = None + self._end_state: Optional[SimState] = None self._start_addr: Optional[int] = None self._end_addr: Optional[int] = None self._block_addrs: Optional[List[int]] = None @@ -55,9 +55,9 @@ def __init__(self, workspace, instance, default_docking_position, *args, **kwarg self._graph_widget: Optional[QDataDepGraph] = None # Data - self._data_dep: Optional["DataDependencyGraphAnalysis"] = None - self._ddg: Optional["DiGraph"] = None # Derived from analysis, can be full, simplified, or subgraph - self._graph: Optional["DiGraph"] = None + self._data_dep: Optional[DataDependencyGraphAnalysis] = None + self._ddg: Optional[DiGraph] = None # Derived from analysis, can be full, simplified, or subgraph + self._graph: Optional[DiGraph] = None self._traced_ancestors: Set[QDataDepGraphBlock] = set() self._traced_descendants: Set[QDataDepGraphBlock] = set() @@ -125,7 +125,7 @@ def analysis_params(self, new_params: dict): def run_analysis(self): inst = self.instance - data_dep: "DataDependencyGraphAnalysis" = inst.project.analyses.DataDep( + data_dep: DataDependencyGraphAnalysis = inst.project.analyses.DataDep( self._end_state, self._start_addr, self._end_addr, diff --git a/angrmanagement/ui/views/disassembly_view.py b/angrmanagement/ui/views/disassembly_view.py index afb9eb588..2216d3855 100644 --- a/angrmanagement/ui/views/disassembly_view.py +++ b/angrmanagement/ui/views/disassembly_view.py @@ -981,7 +981,7 @@ def _address_in_selection(self) -> Optional[Tuple[str, int]]: if self._insn_addr_on_context_menu is not None: return "insn", self._insn_addr_on_context_menu if len(self.infodock.selected_operands) == 1: - selected_operand: "OperandDescriptor" = next(iter(self.infodock.selected_operands.values())) + selected_operand: OperandDescriptor = next(iter(self.infodock.selected_operands.values())) if selected_operand.num_value is not None: return "operand", selected_operand.num_value if len(self.infodock.selected_insns) == 1: diff --git a/angrmanagement/ui/views/hex_view.py b/angrmanagement/ui/views/hex_view.py index 1b5610889..ed943fab5 100644 --- a/angrmanagement/ui/views/hex_view.py +++ b/angrmanagement/ui/views/hex_view.py @@ -91,7 +91,7 @@ class BreakpointHighlightRegion(HexHighlightRegion): def __init__(self, bp: Breakpoint, view: "HexView"): super().__init__(Qt.cyan, bp.addr, bp.size) self.bp: Breakpoint = bp - self.view: "HexView" = view + self.view: HexView = view def gen_context_menu_actions(self) -> Optional[QMenu]: """ @@ -134,7 +134,7 @@ class PatchHighlightRegion(HexHighlightRegion): def __init__(self, patch: Patch, view: "HexView"): super().__init__(Qt.yellow, patch.addr, len(patch)) self.patch: Patch = patch - self.view: "HexView" = view + self.view: HexView = view def get_tooltip(self) -> Optional[str]: """ diff --git a/angrmanagement/ui/views/interaction_view.py b/angrmanagement/ui/views/interaction_view.py index a71af32f6..bca07b499 100644 --- a/angrmanagement/ui/views/interaction_view.py +++ b/angrmanagement/ui/views/interaction_view.py @@ -37,7 +37,7 @@ def __init__(self, name, protocol, log): class ProtocolInteractor: def __init__(self, view, sock): self.view: InteractionView = view - self.sock: Optional["nclib.Netcat"] = sock + self.sock: Optional[nclib.Netcat] = sock def consume_data(self, data): # try to decode it @@ -76,7 +76,7 @@ def __init__(self, workspace, instance, *args, **kwargs): ) # for now each entry is a dict. each entry has {"dir": "in"/"out", "data": bytes} and then whatever # "in" here means it's input to the program self.log_controls = [] - self.sock: Optional["nclib.Netcat"] = None + self.sock: Optional[nclib.Netcat] = None self._state = None self._last_img_name: Optional[str] = None diff --git a/angrmanagement/ui/views/proximity_view.py b/angrmanagement/ui/views/proximity_view.py index f701a19ce..c517b199e 100644 --- a/angrmanagement/ui/views/proximity_view.py +++ b/angrmanagement/ui/views/proximity_view.py @@ -34,7 +34,7 @@ def __init__(self, workspace, instance, default_docking_position, *args, **kwarg self.base_caption = "Proximity" - self._function: Optional["Function"] = None + self._function: Optional[Function] = None self._expand_function_addrs: Set[int] = set() # UI widgets diff --git a/angrmanagement/ui/views/types_view.py b/angrmanagement/ui/views/types_view.py index ca2b4c61f..ae5c74d79 100644 --- a/angrmanagement/ui/views/types_view.py +++ b/angrmanagement/ui/views/types_view.py @@ -53,7 +53,7 @@ def function(self, v): def current_typestore(self) -> "TypesStore": if self._function.am_none: return self.instance.kb.types - var_manager: "VariableManagerInternal" = self.instance.pseudocode_variable_kb.variables[self._function.addr] + var_manager: VariableManagerInternal = self.instance.pseudocode_variable_kb.variables[self._function.addr] return var_manager.types # diff --git a/angrmanagement/ui/widgets/qccode_edit.py b/angrmanagement/ui/widgets/qccode_edit.py index 6da2d5820..f214dd611 100644 --- a/angrmanagement/ui/widgets/qccode_edit.py +++ b/angrmanagement/ui/widgets/qccode_edit.py @@ -59,7 +59,7 @@ class QCCodeEdit(api.CodeEdit): def __init__(self, code_view): super().__init__(create_default_actions=True) - self._code_view: "CodeView" = code_view + self._code_view: CodeView = code_view self.panels.append(panels.LineNumberPanel()) self.panels.append(panels.FoldingPanel()) @@ -92,7 +92,7 @@ def __init__(self, code_view): self.remove_action(self.action_swap_line_down) def node_under_cursor(self): - doc: "QTextDocument" = self.document() + doc: QTextDocument = self.document() if not isinstance(doc, QCodeDocument): # this is not the qcodedocument that the decompiler generates. this means the pseudocode view is empty return None @@ -203,7 +203,7 @@ def get_src_to_inst(self) -> int: """ # get the Qt document - doc: "QCodeDocument" = self.document() + doc: QCodeDocument = self.document() # get the current position of the cursor cursor = self.textCursor() @@ -507,7 +507,7 @@ def _find_loads(expr) -> list: if not isinstance(node, (CVariable, CIndexedVariable, CVariableField, CStructField)): return - doc: "QCodeDocument" = self.document() + doc: QCodeDocument = self.document() cursor = self.textCursor() pos = cursor.position() current_node = doc.get_stmt_node_at_position(pos) diff --git a/angrmanagement/ui/widgets/qdatadep_graph.py b/angrmanagement/ui/widgets/qdatadep_graph.py index d1366798a..b8d01b760 100644 --- a/angrmanagement/ui/widgets/qdatadep_graph.py +++ b/angrmanagement/ui/widgets/qdatadep_graph.py @@ -25,7 +25,7 @@ class QDataDepPreviewGraph(QZoomableDraggableGraphicsView): def __init__(self, parent: QtWidgets.QWidget): super().__init__(parent) - self._display_node: Optional["QDataDepGraphBlock"] = None + self._display_node: Optional[QDataDepGraphBlock] = None @property def node(self) -> Optional["QDataDepGraphBlock"]: @@ -107,8 +107,8 @@ def __init__(self, workspace: "Workspace", data_dep_view: "DataDepView", parent: self._node_preview.preview_graph._reset_scene() self._node_preview.hide() - self._graph: Optional["DiGraph"] = None # Graph to render - self._reference_data_dep_graph: Optional["DiGraph"] = None # Graph from analysis, used to check edge data + self._graph: Optional[DiGraph] = None # Graph to render + self._reference_data_dep_graph: Optional[DiGraph] = None # Graph from analysis, used to check edge data self.nodes = set() self._edges: List[Edge] = [] self._arrows_by_src: Dict[Any, List[QDataDepGraphArrow]] = defaultdict(list) diff --git a/angrmanagement/ui/widgets/qdatadepgraph_block.py b/angrmanagement/ui/widgets/qdatadepgraph_block.py index b0c5f84b0..67e8b30f9 100644 --- a/angrmanagement/ui/widgets/qdatadepgraph_block.py +++ b/angrmanagement/ui/widgets/qdatadepgraph_block.py @@ -35,7 +35,7 @@ def __init__(self, is_selected: bool, data_dep_view: "DataDepView", node: "BaseD self._selected = is_selected self._data_dep_view = data_dep_view self._workspace = self._data_dep_view.workspace - self._node: "BaseDepNode" = node + self._node: BaseDepNode = node self._instr = instr self._header_text: Optional[str] = None diff --git a/angrmanagement/ui/widgets/qdisasm_base_control.py b/angrmanagement/ui/widgets/qdisasm_base_control.py index 28d918fff..5817c6e1a 100644 --- a/angrmanagement/ui/widgets/qdisasm_base_control.py +++ b/angrmanagement/ui/widgets/qdisasm_base_control.py @@ -23,7 +23,7 @@ class QDisassemblyBaseControl: def __init__(self, instance, disasm_view, base_cls): self.instance = instance - self.disasm_view: "DisassemblyView" = disasm_view + self.disasm_view: DisassemblyView = disasm_view self._base_cls = base_cls self._insaddr_to_block = {} self._disassembly_level = disasm_view.disassembly_level diff --git a/angrmanagement/ui/widgets/qfeature_map.py b/angrmanagement/ui/widgets/qfeature_map.py index 787ae26ec..a8bf3e41d 100644 --- a/angrmanagement/ui/widgets/qfeature_map.py +++ b/angrmanagement/ui/widgets/qfeature_map.py @@ -122,13 +122,13 @@ def __init__(self, instance, *args, **kwargs): self._min_cfb_time_between_refresh: float = 1 / 30 self._addr_to_region: SortedDict = SortedDict() # SortedDict[int, "MemoryRegion"] - self._region_to_position: Mapping["MemoryRegion", float] = {} - self._region_to_width: Mapping["MemoryRegion", float] = {} + self._region_to_position: Mapping[MemoryRegion, float] = {} + self._region_to_width: Mapping[MemoryRegion, float] = {} self._position_to_region: SortedDict = SortedDict() # SortedDict[int, "MemoryRegion"] self._cursor_addrs: List[int] = [] self._cursor_items: List[QGraphicsItem] = [] - self._hover_region: Optional["MemoryRegion"] = None + self._hover_region: Optional[MemoryRegion] = None self._hover_region_item: Optional[QGraphicsItem] = None self._feature_palette: FeatureMapPalette diff --git a/angrmanagement/ui/widgets/qfunction_table.py b/angrmanagement/ui/widgets/qfunction_table.py index e18c01d90..ef449c96d 100644 --- a/angrmanagement/ui/widgets/qfunction_table.py +++ b/angrmanagement/ui/widgets/qfunction_table.py @@ -395,7 +395,7 @@ def __init__(self, parent, instance, selection_callback=None): super().__init__(parent) self.instance = instance - self._view: "FunctionsView" = parent + self._view: FunctionsView = parent self._table_view: QFunctionTableView self._filter_box: QFunctionTableFilterBox self._toolbar: FunctionTableToolbar diff --git a/angrmanagement/ui/workspace.py b/angrmanagement/ui/workspace.py index d72a7fcbb..580a85202 100644 --- a/angrmanagement/ui/workspace.py +++ b/angrmanagement/ui/workspace.py @@ -83,7 +83,7 @@ class Workspace: """ def __init__(self, main_window, instance): - self.main_window: "MainWindow" = main_window + self.main_window: MainWindow = main_window self._main_instance = instance instance.workspace = self diff --git a/tests/test_rename_variables.py b/tests/test_rename_variables.py index f9c78867f..289cfae72 100644 --- a/tests/test_rename_variables.py +++ b/tests/test_rename_variables.py @@ -38,7 +38,7 @@ def setUp(self) -> None: gui_thread_schedule(disasm_view.display_function, args=(self.func,)) disasm_view.decompile_current_function() self.main.workspace.main_instance.join_all_jobs() - self.code_view: "CodeView" = self.main.workspace.view_manager.first_view_in_category("pseudocode") + self.code_view: CodeView = self.main.workspace.view_manager.first_view_in_category("pseudocode") def tearDown(self) -> None: self.main = None