Best Python code snippet using slash
main_widget.py
Source:main_widget.py
1# -*- coding: utf-8 -*-2#3# Copyright © Spyder Project Contributors4# Licensed under the terms of the MIT License5# (see spyder/__init__.py for details)6"""7Main Console widget.8"""9# pylint: disable=C010310# pylint: disable=R090311# pylint: disable=R091112# pylint: disable=R020113# Standard library imports14import logging15import os16import os.path as osp17import sys18# Third party imports19from qtpy.compat import getopenfilename20from qtpy.QtCore import Qt, Signal, Slot21from qtpy.QtWidgets import QAction, QInputDialog, QLineEdit, QVBoxLayout22# Local imports23from spyder.api.exceptions import SpyderAPIError24from spyder.api.plugin_registration.registry import PLUGIN_REGISTRY25from spyder.api.translations import get_translation26from spyder.api.widgets.main_widget import PluginMainWidget27from spyder.api.config.decorators import on_conf_change28from spyder.app.find_plugins import find_internal_plugins29from spyder.config.base import DEV, get_debug_level30from spyder.plugins.console.widgets.internalshell import InternalShell31from spyder.py3compat import to_text_string32from spyder.utils.environ import EnvDialog33from spyder.utils.misc import (get_error_match, getcwd_or_home,34 remove_backslashes)35from spyder.utils.qthelpers import DialogManager, mimedata2url36from spyder.widgets.collectionseditor import CollectionsEditor37from spyder.widgets.findreplace import FindReplace38from spyder.widgets.reporterror import SpyderErrorDialog39# Localization40_ = get_translation('spyder')41logger = logging.getLogger(__name__)42# --- Constants43# ----------------------------------------------------------------------------44class ConsoleWidgetActions:45 # Triggers46 Environment = 'environment_action'47 ExternalEditor = 'external_editor_action'48 MaxLineCount = 'max_line_count_action'49 # The name of the action needs to match name of the shortcut50 # so 'Quit' is used instead of something like 'quit_action'51 Quit = 'Quit'52 Run = 'run_action'53 SysPath = 'sys_path_action'54 # Toggles55 ToggleCodeCompletion = 'toggle_code_completion_action'56 ToggleWrap = 'toggle_wrap_action'57class ConsoleWidgetMenus:58 InternalSettings = 'internal_settings_submenu'59class ConsoleWidgetOptionsMenuSections:60 Run = 'run_section'61 Quit = 'quit_section'62class ConsoleWidgetInternalSettingsSubMenuSections:63 Main = 'main'64# --- Widgets65# ----------------------------------------------------------------------------66class ConsoleWidget(PluginMainWidget):67 # --- Signals68 # This signal emits a parsed error traceback text so we can then69 # request opening the file that traceback comes from in the Editor.70 sig_edit_goto_requested = Signal(str, int, str)71 # TODO: I do not think we use this?72 sig_focus_changed = Signal()73 # Emit this when the interpreter buffer is flushed74 sig_refreshed = Signal()75 # Request to show a status message on the main window76 sig_show_status_requested = Signal(str)77 # Request the main application to quit.78 sig_quit_requested = Signal()79 sig_help_requested = Signal(dict)80 """81 This signal is emitted to request help on a given object `name`.82 Parameters83 ----------84 help_data: dict85 Example `{'name': str, 'ignore_unknown': bool}`.86 """87 def __init__(self, name, plugin, parent=None):88 super().__init__(name, plugin, parent)89 logger.info("Initializing...")90 # Traceback MessageBox91 self.error_traceback = ''92 self.dismiss_error = False93 # Widgets94 self.dialog_manager = DialogManager()95 self.error_dlg = None96 self.shell = InternalShell( # TODO: Move to use SpyderWidgetMixin?97 parent=parent,98 namespace=self.get_conf('namespace', {}),99 commands=self.get_conf('commands', []),100 message=self.get_conf('message', ''),101 max_line_count=self.get_conf('max_line_count'),102 profile=self.get_conf('profile', False),103 multithreaded=self.get_conf('multithreaded', False),104 )105 self.find_widget = FindReplace(self)106 # Setup107 self.setAcceptDrops(True)108 self.find_widget.set_editor(self.shell)109 self.find_widget.hide()110 self.shell.toggle_wrap_mode(self.get_conf('wrap'))111 # Layout112 layout = QVBoxLayout()113 layout.addWidget(self.shell)114 layout.addWidget(self.find_widget)115 self.setLayout(layout)116 # Signals117 self.shell.sig_help_requested.connect(self.sig_help_requested)118 self.shell.sig_exception_occurred.connect(self.handle_exception)119 self.shell.sig_focus_changed.connect(self.sig_focus_changed)120 self.shell.sig_go_to_error_requested.connect(self.go_to_error)121 self.shell.sig_redirect_stdio_requested.connect(122 self.sig_redirect_stdio_requested)123 self.shell.sig_refreshed.connect(self.sig_refreshed)124 self.shell.sig_show_status_requested.connect(125 lambda msg: self.sig_show_status_message.emit(msg, 0))126 # --- PluginMainWidget API127 # ------------------------------------------------------------------------128 def get_title(self):129 return _('Internal console')130 def setup(self):131 # TODO: Move this to the shell132 self.quit_action = self.create_action(133 ConsoleWidgetActions.Quit,134 text=_("&Quit"),135 tip=_("Quit"),136 icon=self.create_icon('exit'),137 triggered=self.sig_quit_requested,138 context=Qt.ApplicationShortcut,139 shortcut_context="_",140 register_shortcut=True,141 menurole=QAction.QuitRole142 )143 run_action = self.create_action(144 ConsoleWidgetActions.Run,145 text=_("&Run..."),146 tip=_("Run a Python script"),147 icon=self.create_icon('run_small'),148 triggered=self.run_script,149 )150 environ_action = self.create_action(151 ConsoleWidgetActions.Environment,152 text=_("Environment variables..."),153 tip=_("Show and edit environment variables (for current "154 "session)"),155 icon=self.create_icon('environ'),156 triggered=self.show_env,157 )158 syspath_action = self.create_action(159 ConsoleWidgetActions.SysPath,160 text=_("Show sys.path contents..."),161 tip=_("Show (read-only) sys.path"),162 icon=self.create_icon('syspath'),163 triggered=self.show_syspath,164 )165 buffer_action = self.create_action(166 ConsoleWidgetActions.MaxLineCount,167 text=_("Buffer..."),168 tip=_("Set maximum line count"),169 triggered=self.change_max_line_count,170 )171 exteditor_action = self.create_action(172 ConsoleWidgetActions.ExternalEditor,173 text=_("External editor path..."),174 tip=_("Set external editor executable path"),175 triggered=self.change_exteditor,176 )177 wrap_action = self.create_action(178 ConsoleWidgetActions.ToggleWrap,179 text=_("Wrap lines"),180 toggled=lambda val: self.set_conf('wrap', val),181 initial=self.get_conf('wrap'),182 )183 codecompletion_action = self.create_action(184 ConsoleWidgetActions.ToggleCodeCompletion,185 text=_("Automatic code completion"),186 toggled=lambda val: self.set_conf('codecompletion/auto', val),187 initial=self.get_conf('codecompletion/auto'),188 )189 # Submenu190 internal_settings_menu = self.create_menu(191 ConsoleWidgetMenus.InternalSettings,192 _('Internal console settings'),193 icon=self.create_icon('tooloptions'),194 )195 for item in [buffer_action, wrap_action, codecompletion_action,196 exteditor_action]:197 self.add_item_to_menu(198 item,199 menu=internal_settings_menu,200 section=ConsoleWidgetInternalSettingsSubMenuSections.Main,201 )202 # Options menu203 options_menu = self.get_options_menu()204 for item in [run_action, environ_action, syspath_action,205 internal_settings_menu]:206 self.add_item_to_menu(207 item,208 menu=options_menu,209 section=ConsoleWidgetOptionsMenuSections.Run,210 )211 self.add_item_to_menu(212 self.quit_action,213 menu=options_menu,214 section=ConsoleWidgetOptionsMenuSections.Quit,215 )216 self.shell.set_external_editor(217 self.get_conf('external_editor/path'), '')218 @on_conf_change(option='max_line_count')219 def max_line_count_update(self, value):220 self.shell.setMaximumBlockCount(value)221 @on_conf_change(option='wrap')222 def wrap_mode_update(self, value):223 self.shell.toggle_wrap_mode(value)224 @on_conf_change(option='external_editor/path')225 def external_editor_update(self, value):226 self.shell.set_external_editor(value, '')227 def update_actions(self):228 pass229 def get_focus_widget(self):230 return self.shell231 # --- Qt overrides232 # ------------------------------------------------------------------------233 def dragEnterEvent(self, event):234 """235 Reimplement Qt method.236 Inform Qt about the types of data that the widget accepts.237 """238 source = event.mimeData()239 if source.hasUrls():240 if mimedata2url(source):241 event.acceptProposedAction()242 else:243 event.ignore()244 elif source.hasText():245 event.acceptProposedAction()246 def dropEvent(self, event):247 """248 Reimplement Qt method.249 Unpack dropped data and handle it.250 """251 source = event.mimeData()252 if source.hasUrls():253 pathlist = mimedata2url(source)254 self.shell.drop_pathlist(pathlist)255 elif source.hasText():256 lines = to_text_string(source.text())257 self.shell.set_cursor_position('eof')258 self.shell.execute_lines(lines)259 event.acceptProposedAction()260 # --- Public API261 # ------------------------------------------------------------------------262 def start_interpreter(self, namespace):263 """264 Start internal console interpreter.265 """266 self.shell.start_interpreter(namespace)267 def set_historylog(self, historylog):268 """269 Bind historylog instance to this console.270 Not used anymore since v2.0.271 """272 historylog.add_history(self.shell.history_filename)273 self.shell.sig_append_to_history_requested.connect(274 historylog.append_to_history)275 def set_help(self, help_plugin):276 """277 Bind help instance to this console.278 """279 self.shell.help = help_plugin280 def report_issue(self):281 """Report an issue with the SpyderErrorDialog."""282 self._report_dlg = SpyderErrorDialog(self, is_report=True)283 self._report_dlg.set_color_scheme(self.get_conf(284 'selected', section='appearance'))285 self._report_dlg.show()286 @Slot(dict)287 def handle_exception(self, error_data, sender=None):288 """289 Exception ocurred in the internal console.290 Show a QDialog or the internal console to warn the user.291 Handle any exception that occurs during Spyder usage.292 Parameters293 ----------294 error_data: dict295 The dictionary containing error data. The expected keys are:296 >>> error_data= {297 "text": str,298 "is_traceback": bool,299 "repo": str,300 "title": str,301 "label": str,302 "steps": str,303 }304 sender: spyder.api.plugins.SpyderPluginV2, optional305 The sender plugin. Default is None.306 Notes307 -----308 The `is_traceback` key indicates if `text` contains plain text or a309 Python error traceback.310 The `title` and `repo` keys indicate how the error data should311 customize the report dialog and Github error submission.312 The `label` and `steps` keys allow customizing the content of the313 error dialog.314 """315 text = error_data.get("text", None)316 is_traceback = error_data.get("is_traceback", False)317 title = error_data.get("title", "")318 label = error_data.get("label", "")319 steps = error_data.get("steps", "")320 # Skip errors without traceback (and no text) or dismiss321 if ((not text and not is_traceback and self.error_dlg is None)322 or self.dismiss_error):323 return324 # Retrieve internal plugins325 internal_plugins = PLUGIN_REGISTRY.internal_plugins326 # Get if sender is internal or not327 is_internal_plugin = True328 if sender is not None:329 sender_name = getattr(330 sender, 'NAME', getattr(sender, 'CONF_SECTION'))331 is_internal_plugin = sender_name in internal_plugins332 # Set repo333 repo = "spyder-ide/spyder"334 if not is_internal_plugin:335 repo = error_data.get("repo", None)336 if repo is None:337 raise SpyderAPIError(338 f"External plugin '{sender_name}' does not define 'repo' "339 "key in the 'error_data' dictionary in the form "340 "my-org/my-repo (only Github is supported)."341 )342 if repo == 'spyder-ide/spyder':343 raise SpyderAPIError(344 f"External plugin '{sender_name}' 'repo' key needs to be "345 "different from the main Spyder repo."346 )347 if self.get_conf('show_internal_errors', section='main'):348 if self.error_dlg is None:349 self.error_dlg = SpyderErrorDialog(self)350 self.error_dlg.set_color_scheme(351 self.get_conf('selected', section='appearance'))352 self.error_dlg.close_btn.clicked.connect(self.close_error_dlg)353 self.error_dlg.rejected.connect(self.remove_error_dlg)354 self.error_dlg.details.sig_go_to_error_requested.connect(355 self.go_to_error)356 # Set the report repository357 self.error_dlg.set_github_repo_org(repo)358 if title:359 self.error_dlg.set_title(title)360 self.error_dlg.title.setEnabled(False)361 if label:362 self.error_dlg.main_label.setText(label)363 self.error_dlg.submit_btn.setEnabled(True)364 if steps:365 self.error_dlg.steps_text.setText(steps)366 self.error_dlg.set_require_minimum_length(False)367 self.error_dlg.append_traceback(text)368 self.error_dlg.show()369 elif DEV or get_debug_level():370 self.change_visibility(True, True)371 def close_error_dlg(self):372 """373 Close error dialog.374 """375 if self.error_dlg.dismiss_box.isChecked():376 self.dismiss_error = True377 self.error_dlg.reject()378 def remove_error_dlg(self):379 """380 Remove error dialog.381 """382 self.error_dlg = None383 @Slot()384 def show_env(self):385 """386 Show environment variables.387 """388 self.dialog_manager.show(EnvDialog(parent=self))389 def get_sys_path(self):390 """391 Return the `sys.path`.392 """393 return sys.path394 @Slot()395 def show_syspath(self):396 """397 Show `sys.path`.398 """399 editor = CollectionsEditor(parent=self)400 editor.setup(401 sys.path,402 title="sys.path",403 readonly=True,404 icon=self.create_icon('syspath'),405 )406 self.dialog_manager.show(editor)407 @Slot()408 def run_script(self, filename=None, silent=False, set_focus=False,409 args=None):410 """411 Run a Python script.412 """413 if filename is None:414 self.shell.interpreter.restore_stds()415 filename, _selfilter = getopenfilename(416 self,417 _("Run Python script"),418 getcwd_or_home(),419 _("Python scripts") + " (*.py ; *.pyw ; *.ipy)",420 )421 self.shell.interpreter.redirect_stds()422 if filename:423 os.chdir(osp.dirname(filename))424 filename = osp.basename(filename)425 else:426 return427 logger.debug("Running script with %s", args)428 filename = osp.abspath(filename)429 rbs = remove_backslashes430 command = "runfile('%s', args='%s')" % (rbs(filename), rbs(args))431 if set_focus:432 self.shell.setFocus()433 self.change_visibility(True, True)434 self.shell.write(command+'\n')435 self.shell.run_command(command)436 def go_to_error(self, text):437 """438 Go to error if relevant.439 """440 match = get_error_match(to_text_string(text))441 if match:442 fname, lnb = match.groups()443 self.edit_script(fname, int(lnb))444 def edit_script(self, filename=None, goto=-1):445 """446 Edit script.447 """448 if filename is not None:449 # Called from InternalShell450 self.shell.external_editor(filename, goto)451 self.sig_edit_goto_requested.emit(osp.abspath(filename), goto, '')452 def execute_lines(self, lines):453 """454 Execute lines and give focus to shell.455 """456 self.shell.execute_lines(to_text_string(lines))457 self.shell.setFocus()458 @Slot()459 def change_max_line_count(self, value=None):460 """"461 Change maximum line count.462 """463 valid = True464 if value is None:465 value, valid = QInputDialog.getInt(466 self,467 _('Buffer'),468 _('Maximum line count'),469 self.get_conf('max_line_count'),470 0,471 1000000,472 )473 if valid:474 self.set_conf('max_line_count', value)475 @Slot()476 def change_exteditor(self, path=None):477 """478 Change external editor path.479 """480 valid = True481 if path is None:482 path, valid = QInputDialog.getText(483 self,484 _('External editor'),485 _('External editor executable path:'),486 QLineEdit.Normal,487 self.get_conf('external_editor/path'),488 )489 if valid:490 self.set_conf('external_editor/path', to_text_string(path))491 def set_exit_function(self, func):492 """493 Set the callback function to execute when the `exit_interpreter` is494 called.495 """496 self.shell.exitfunc = func497 def set_font(self, font):498 """499 Set font of the internal shell.500 """501 self.shell.set_font(font)502 def redirect_stds(self):503 """504 Redirect stdout and stderr when using open file dialogs.505 """506 self.shell.interpreter.redirect_stds()507 def restore_stds(self):508 """509 Restore stdout and stderr when using open file dialogs.510 """511 self.shell.interpreter.restore_stds()512 def set_namespace_item(self, name, item):513 """514 Add an object to the namespace dictionary of the internal console.515 """516 self.shell.interpreter.namespace[name] = item517 def exit_interpreter(self):518 """519 Exit the internal console interpreter.520 This is equivalent to requesting the main application to quit.521 """...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!