Esempio n. 1
0
    def reset_namespace(self, warning=False, message=False):
        """Reset the namespace by removing all names defined by the user."""
        # Don't show the warning when running our tests.
        if running_under_pytest():
            warning = False

        if warning:
            reset_str = _("Remove all variables")
            warn_str = _("All user-defined variables will be removed. "
                         "Are you sure you want to proceed?")
            box = MessageCheckBox(icon=QMessageBox.Warning, parent=self)
            box.setWindowTitle(reset_str)
            box.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
            box.setDefaultButton(QMessageBox.Yes)

            box.set_checkbox_text(_("Don't show again."))
            box.set_checked(False)
            box.set_check_visible(True)
            box.setText(warn_str)

            box.buttonClicked.connect(
                lambda button: self.handle_reset_message_answer(
                    box, button, message))
            box.show()
        else:
            self._perform_reset(message)
Esempio n. 2
0
    def _create_project(self,
                        root_path,
                        project_type=EmptyProject.ID,
                        packages=None):
        """Create a new project."""
        project_types = self.get_project_types()
        if project_type in project_types:
            project_type_class = project_types[project_type]
            project = project_type_class(root_path,
                                         project_type_class._PARENT_PLUGIN)

            created_succesfully, message = project.create_project()
            if not created_succesfully:
                QMessageBox.warning(self, "Project creation", message)
                shutil.rmtree(root_path, ignore_errors=True)
                return

            # TODO: In a subsequent PR return a value and emit based on that
            self.sig_project_created.emit(root_path, project_type, packages)
            self.open_project(path=root_path, project=project)
        else:
            if not running_under_pytest():
                QMessageBox.critical(
                    self, _('Error'),
                    _("<b>{}</b> is not a registered Spyder project "
                      "type!").format(project_type))
Esempio n. 3
0
    def start_client(self, language):
        """Start an LSP client for a given language."""
        # To keep track if the client was started.
        started = False

        if language in self.clients:
            language_client = self.clients[language]

            queue = self.register_queue[language]

            # Don't start LSP services when testing unless we demand
            # them.
            if running_under_pytest():
                if not os.environ.get('SPY_TEST_USE_INTROSPECTION'):
                    return started

            started = language_client['status'] == self.RUNNING

            # Start client heartbeat
            timer = QTimer(self)
            self.clients_hearbeat[language] = timer
            timer.setInterval(self.TIME_HEARTBEAT)
            timer.timeout.connect(lambda: self.check_heartbeat(language))
            timer.start()

            if language_client['status'] == self.STOPPED:
                config = language_client['config']

                # If we're trying to connect to an external server,
                # verify that it's listening before creating a
                # client for it.
                if config['external']:
                    host = config['host']
                    port = config['port']
                    response = check_connection_port(host, port)
                    if not response:
                        if self.show_no_external_server_warning:
                            self.report_no_external_server(
                                host, port, language)
                        self.set_status(language, _("down"))
                        return False

                language_client['instance'] = LSPClient(
                    parent=self,
                    server_settings=config,
                    folder=self.get_root_path(language),
                    language=language)

                self.register_client_instance(language_client['instance'])

                # Register that a client was started.
                logger.info("Starting LSP client for {}...".format(language))
                language_client['instance'].start()
                language_client['status'] = self.RUNNING
                started = True
                for entry in queue:
                    language_client['instance'].register_file(*entry)
                self.register_queue[language] = []

        return started
Esempio n. 4
0
    def start_client(self, language):
        """Start an LSP client for a given language."""
        started = False
        if language in self.clients:
            language_client = self.clients[language]
            queue = self.register_queue[language]

            # Don't start LSP services when testing unless we demand
            # them.
            if running_under_pytest():
                if not os.environ.get('SPY_TEST_USE_INTROSPECTION'):
                    return started

            # Start client
            started = language_client['status'] == self.RUNNING
            if language_client['status'] == self.STOPPED:
                config = language_client['config']

                language_client['instance'] = LSPClient(
                    parent=self,
                    server_settings=config,
                    folder=self.get_root_path(language),
                    language=language)

                self.register_client_instance(language_client['instance'])

                logger.info("Starting LSP client for {}...".format(language))
                language_client['instance'].start()
                language_client['status'] = self.RUNNING
                for entry in queue:
                    language_client.register_file(*entry)
                self.register_queue[language] = []
        return started
Esempio n. 5
0
    def get_user_credentials(self):
        """Get user credentials with the login dialog."""
        token = None
        remember_token = self._get_credentials_from_settings()
        valid_py_os = not (PY2 and sys.platform.startswith('linux'))
        if remember_token and valid_py_os:
            # Get token from keyring
            try:
                token = keyring.get_password('github', 'token')
            except Exception:
                # No safe keyring backend
                if self._show_msgbox:
                    QMessageBox.warning(
                        self.parent_widget, _('Failed to retrieve token'),
                        _('It was not possible to retrieve '
                          'your token. Please introduce it '
                          'again.'))

        if not running_under_pytest():
            credentials = DlgGitHubLogin.login(self.parent_widget, token,
                                               remember_token)

            if credentials['token'] and valid_py_os:
                self._store_token(credentials['token'],
                                  credentials['remember_token'])
                CONF.set('main', 'report_error/remember_token',
                         credentials['remember_token'])
        else:
            return dict(token=token, remember_token=remember_token)

        return credentials
Esempio n. 6
0
 def __init__(self,
              block,
              text=None,
              fold_level=None,
              def_type=None,
              def_name=None,
              color=None):
     """
     Args:
         text (str)
         fold_level (int)
         def_type (int): [CLASS, FUNCTION, STATEMENT, COMMENT, CELL]
         def_name (str)
         color (PyQt.QtGui.QTextCharFormat)
     """
     super(OutlineExplorerData, self).__init__()
     self.text = text
     self.fold_level = fold_level
     self.def_type = def_type
     self.def_name = def_name
     self.color = color
     if running_under_pytest():
         # block might be a dummy
         self.block = block
     else:
         # Copy the text block to make sure it is not deleted
         self.block = QTextBlock(block)
Esempio n. 7
0
    def on_code_snippets_changed(self, value):
        if running_under_pytest():
            if not os.environ.get('SPY_TEST_USE_INTROSPECTION'):
                return

        self.client.enable_code_snippets = self.get_conf(
            'enable_code_snippets', section='completions')
Esempio n. 8
0
def is_spyder_process(pid):
    """
    Test whether given PID belongs to a Spyder process.

    This is checked by testing the first three command line arguments. This
    function returns a bool. If there is no process with this PID or its
    command line cannot be accessed (perhaps because the process is owned by
    another user), then the function returns False.
    """
    try:
        p = psutil.Process(int(pid))

        # Valid names for main script
        names = set([
            'spyder', 'spyder3', 'spyder.exe', 'spyder3.exe', 'bootstrap.py',
            'spyder-script.py', 'Spyder.launch.pyw'
        ])
        if running_under_pytest():
            names.add('runtests.py')

        # Check the first three command line arguments
        arguments = set(os.path.basename(arg) for arg in p.cmdline()[:3])
        conditions = [names & arguments]
        return any(conditions)
    except (psutil.NoSuchProcess, psutil.AccessDenied):
        return False
Esempio n. 9
0
    def register(self):
        """Start all available completion providers."""
        preferences = self.get_plugin(Plugins.Preferences)
        preferences.register_plugin_preferences(self)

        container = self.get_container()
        statusbar = self.get_plugin(Plugins.StatusBar)
        if statusbar:
            for sb in container.all_statusbar_widgets():
                statusbar.add_status_widget(sb)

        if self.main:
            self.main.sig_pythonpath_changed.connect(
                self.sig_pythonpath_changed)

        # Do not start providers on tests unless necessary
        if running_under_pytest():
            if not os.environ.get('SPY_TEST_USE_INTROSPECTION'):
                # Prevent providers from receiving configuration updates
                for provider_name in self.providers:
                    provider_info = self.providers[provider_name]
                    CONF.unobserve_configuration(provider_info['instance'])
                return

        self.start_all_providers()
Esempio n. 10
0
 def _show_installation_dialog(self):
     """Show installation dialog."""
     kite_installation_enabled = self.get_option('show_installation_dialog')
     installed, path = check_if_kite_installed()
     if (not installed and kite_installation_enabled
             and not running_under_pytest()):
         self.kite_installer.show()
         self.kite_installer.center()
Esempio n. 11
0
    def get_user_credentials(self):
        """Get user credentials with the login dialog."""
        password = None
        token = None
        (username, remember_me,
         remember_token) = self._get_credentials_from_settings()
        valid_py_os = not (PY2 and sys.platform.startswith('linux'))
        if username and remember_me and valid_py_os:
            # Get password from keyring
            try:
                password = keyring.get_password('github', username)
            except Exception:
                # No safe keyring backend
                if self._show_msgbox:
                    QMessageBox.warning(self.parent_widget,
                                        _('Failed to retrieve password'),
                                        _('It was not possible to retrieve '
                                          'your password. Please introduce '
                                          'it again.'))
        if remember_token and valid_py_os:
            # Get token from keyring
            try:
                token = keyring.get_password('github', 'token')
            except Exception:
                # No safe keyring backend
                if self._show_msgbox:
                    QMessageBox.warning(self.parent_widget,
                                        _('Failed to retrieve token'),
                                        _('It was not possible to retrieve '
                                          'your token. Please introduce it '
                                          'again.'))

        if not running_under_pytest():
            credentials = DlgGitHubLogin.login(self.parent_widget, username,
                                            password, token, remember_me,
                                            remember_token)

            if (credentials['username'] and credentials['password'] and
                    valid_py_os):
                self._store_credentials(credentials['username'],
                                        credentials['password'],
                                        credentials['remember'])
                CONF.set('main', 'report_error/remember_me',
                         credentials['remember'])

            if credentials['token'] and valid_py_os:
                self._store_token(credentials['token'],
                                  credentials['remember_token'])
                CONF.set('main', 'report_error/remember_token',
                         credentials['remember_token'])
        else:
            return dict(username=username,
                        password=password,
                        token='',
                        remember=remember_me,
                        remember_token=remember_token)

        return credentials
Esempio n. 12
0
    def restart_kernel(self):
        """
        Restart the associated kernel.

        Took this code from the qtconsole project
        Licensed under the BSD license
        """
        sw = self.shellwidget

        if not running_under_pytest() and self.ask_before_restart:
            message = _('Are you sure you want to restart the kernel?')
            buttons = QMessageBox.Yes | QMessageBox.No
            result = QMessageBox.question(self, _('Restart kernel?'), message,
                                          buttons)
        else:
            result = None

        if (result == QMessageBox.Yes or running_under_pytest()
                or not self.ask_before_restart):
            if sw.kernel_manager:
                if self.infowidget.isVisible():
                    self.infowidget.hide()
                    sw.show()
                try:
                    # Close comm
                    sw.spyder_kernel_comm.close()
                    sw.kernel_manager.restart_kernel(stderr=self.stderr_handle)
                    # Reopen comm
                    sw.spyder_kernel_comm.open_comm(sw.kernel_client)

                except RuntimeError as e:
                    sw._append_plain_text(_('Error restarting kernel: %s\n') %
                                          e,
                                          before_prompt=True)
                else:
                    # For spyder-ide/spyder#6235, IPython was changing the
                    # setting of %colors on windows by assuming it was using a
                    # dark background. This corrects it based on the scheme.
                    self.set_color_scheme(sw.syntax_style)
                    sw._append_html(_("<br>Restarting kernel...\n<hr><br>"),
                                    before_prompt=False)
            else:
                sw._append_plain_text(
                    _('Cannot restart a kernel not started by Spyder\n'),
                    before_prompt=True)
Esempio n. 13
0
    def restart_kernel(self):
        """
        Restart the associated kernel.

        Took this code from the qtconsole project
        Licensed under the BSD license
        """
        sw = self.shellwidget

        if not running_under_pytest() and self.ask_before_restart:
            message = _('Are you sure you want to restart the kernel?')
            buttons = QMessageBox.Yes | QMessageBox.No
            result = QMessageBox.question(self, _('Restart kernel?'),
                                          message, buttons)
        else:
            result = None

        if (result == QMessageBox.Yes or
                running_under_pytest() or
                not self.ask_before_restart):
            if sw.kernel_manager:
                if self.infowidget.isVisible():
                    self.infowidget.hide()
                    sw.show()
                try:
                    sw.kernel_manager.restart_kernel(
                        stderr=self.stderr_handle)
                except RuntimeError as e:
                    sw._append_plain_text(
                        _('Error restarting kernel: %s\n') % e,
                        before_prompt=True
                    )
                else:
                    # For issue 6235.  IPython was changing the setting of
                    # %colors on windows by assuming it was using a dark
                    # background.  This corrects it based on the scheme.
                    self.set_color_scheme(sw.syntax_style)
                    sw._append_html(_("<br>Restarting kernel...\n<hr><br>"),
                                    before_prompt=False)
            else:
                sw._append_plain_text(
                    _('Cannot restart a kernel not started by Spyder\n'),
                    before_prompt=True
                )
Esempio n. 14
0
 def shutdown(self):
     """Shutdown kernel"""
     if self.get_kernel() is not None and not self.slave:
         now = True
         # This avoids some flakyness with our Cython tests
         if running_under_pytest():
             now = False
         self.shellwidget.kernel_manager.shutdown_kernel(now=now)
     if self.shellwidget.kernel_client is not None:
         background(self.shellwidget.kernel_client.stop_channels)
Esempio n. 15
0
    def update_snippets(self, snippets):
        if running_under_pytest():
            if not os.environ.get('SPY_TEST_USE_INTROSPECTION'):
                return

        self.config = snippets
        snippet_info = {}
        for language in SUPPORTED_LANGUAGES_PY:
            snippet_info[language] = snippets.get(language, {})
        self.snippets_actor.sig_update_snippets.emit(snippet_info)
Esempio n. 16
0
    def start_server(self):
        """Start server."""
        # This is not necessary if we're trying to connect to an
        # external server
        if self.external_server or self.stdio:
            return

        logger.info('Starting server: {0}'.format(' '.join(self.server_args)))

        # Create server process
        self.server = QProcess(self)
        env = self.server.processEnvironment()

        # Use local PyLS instead of site-packages one.
        if DEV or running_under_pytest():
            running_in_ci = bool(os.environ.get('CI'))
            if os.name != 'nt' or os.name == 'nt' and not running_in_ci:
                env.insert('PYTHONPATH', os.pathsep.join(sys.path)[:])

        # Adjustments for the Python language server.
        if self.language == 'python':
            # Set the PyLS current working to an empty dir inside
            # our config one. This avoids the server to pick up user
            # files such as random.py or string.py instead of the
            # standard library modules named the same.
            cwd = osp.join(get_conf_path(), 'lsp_paths', 'cwd')
            if not osp.exists(cwd):
                os.makedirs(cwd)

            # On Windows, some modules (notably Matplotlib)
            # cause exceptions if they cannot get the user home.
            # So, we need to pass the USERPROFILE env variable to
            # the PyLS.
            if os.name == "nt" and "USERPROFILE" in os.environ:
                env.insert("USERPROFILE", os.environ["USERPROFILE"])
        else:
            # There's no need to define a cwd for other servers.
            cwd = None

            # Most LSP servers spawn other processes, which may require
            # some environment variables.
            for var in os.environ:
                env.insert(var, os.environ[var])
            logger.info('Server process env variables: {0}'.format(env.keys()))

        # Setup server
        self.server.setProcessEnvironment(env)
        self.server.errorOccurred.connect(self.handle_process_errors)
        self.server.setWorkingDirectory(cwd)
        self.server.setProcessChannelMode(QProcess.MergedChannels)
        if self.server_log_file is not None:
            self.server.setStandardOutputFile(self.server_log_file)

        # Start server
        self.server.start(self.server_args[0], self.server_args[1:])
Esempio n. 17
0
    def start_transport(self):
        """Start transport layer."""
        logger.info('Starting transport for {1}: {0}'.format(
            ' '.join(self.transport_args), self.language))

        # Create transport process
        self.transport = QProcess(self)
        env = self.transport.processEnvironment()

        # Most LSP servers spawn other processes other than Python, which may
        # require some environment variables
        if self.language != 'python' and self.stdio:
            for var in os.environ:
                env.insert(var, os.environ[var])
            logger.info('Transport process env variables: {0}'.format(
                env.keys()))

        self.transport.setProcessEnvironment(env)

        # Modifying PYTHONPATH to run transport in development mode or
        # tests
        if (DEV or running_under_pytest()) and not running_in_ci():
            sys_path = self._clean_sys_path()
            if running_under_pytest():
                env.insert('PYTHONPATH', os.pathsep.join(sys_path)[:])
            else:
                env.insert('PYTHONPATH', os.pathsep.join(sys_path)[1:])
            self.transport.setProcessEnvironment(env)

        # Set up transport
        self.transport.errorOccurred.connect(self.handle_process_errors)
        if self.stdio:
            self.transport.setProcessChannelMode(QProcess.SeparateChannels)
            if self.transport_log_file is not None:
                self.transport.setStandardErrorFile(self.transport_log_file)
        else:
            self.transport.setProcessChannelMode(QProcess.MergedChannels)
            if self.transport_log_file is not None:
                self.transport.setStandardOutputFile(self.transport_log_file)

        # Start transport
        self.transport.start(self.transport_args[0], self.transport_args[1:])
Esempio n. 18
0
    def start_transport(self):
        """Start transport layer."""
        self.transport_args = list(map(str, self.transport_args))
        logger.info('Starting transport: {0}'.format(' '.join(
            self.transport_args)))

        self.transport = QProcess(self)
        self.transport.errorOccurred.connect(self.handle_process_errors)

        # Modifying PYTHONPATH to run transport in development mode or
        # tests
        if DEV or running_under_pytest():
            env = QProcessEnvironment()
            if running_under_pytest():
                env.insert('PYTHONPATH', os.pathsep.join(sys.path)[:])
            else:
                env.insert('PYTHONPATH', os.pathsep.join(sys.path)[1:])
            self.transport.setProcessEnvironment(env)

        # Set transport log file
        transport_log_file = None
        if get_debug_level() > 0:
            transport_log_fname = 'transport_{0}_{1}.log'.format(
                self.language, os.getpid())
            transport_log_file = get_conf_path(
                osp.join('lsp_logs', transport_log_fname))
            if not osp.exists(osp.dirname(transport_log_file)):
                os.makedirs(osp.dirname(transport_log_file))

        # Set channel properties
        if self.stdio:
            self.transport_args += self.server_args
            self.transport.setProcessChannelMode(QProcess.SeparateChannels)
            if transport_log_file is not None:
                self.transport.setStandardErrorFile(transport_log_file)
        else:
            self.transport.setProcessChannelMode(QProcess.MergedChannels)
            if transport_log_file is not None:
                self.transport.setStandardOutputFile(transport_log_file)

        # Start transport
        self.transport.start(self.transport_args[0], self.transport_args[1:])
Esempio n. 19
0
 def on_mainwindow_visible(self):
     """Actions after the mainwindow in visible."""
     # Show dialog with missing dependencies
     if not running_under_pytest():
         # This avoids computing missing deps before the window is fully up
         timer_report_deps = QTimer(self)
         timer_report_deps.setInterval(2000)
         timer_report_deps.setSingleShot(True)
         timer_report_deps.timeout.connect(
             self.get_container().report_missing_dependencies)
         timer_report_deps.start()
Esempio n. 20
0
def create_splash_screen():
    """Create splash screen."""
    if not running_under_pytest():
        splash = QSplashScreen(QPixmap(get_image_path('splash')))
        splash_font = splash.font()
        splash_font.setPixelSize(14)
        splash.setFont(splash_font)
    else:
        splash = None

    return splash
Esempio n. 21
0
 def shutdown(self):
     """Shutdown kernel"""
     if self.get_kernel() is not None and not self.slave:
         now = True
         # This avoids some flakyness with our Cython tests
         if running_under_pytest():
             now = False
         self.shellwidget.spyder_kernel_comm.close()
         self.shellwidget.kernel_manager.shutdown_kernel(now=now)
         self.shellwidget.pdb_history_file.save_thread.stop()
     if self.shellwidget.kernel_client is not None:
         self.shellwidget.kernel_client.stop_channels()
Esempio n. 22
0
    def on_mainwindow_visible(self):
        """Actions after the mainwindow in visible."""
        container = self.get_container()

        # Show dialog with missing dependencies
        if not running_under_pytest():
            container.compute_dependencies()

        # Check for updates
        if DEV is None and self.get_conf('check_updates_on_startup'):
            container.give_updates_feedback = False
            container.check_updates(startup=True)
Esempio n. 23
0
def find_internal_plugins():
    """
    Find available plugins based on setup.py entry points.

    In DEV mode we parse the `setup.py` file directly.
    """
    internal_plugins = {}
    # If DEV, look for entry points in setup.py file for internal plugins
    # and then look on the system for the rest
    if DEV is not None or running_under_pytest():
        HERE = os.path.abspath(os.path.dirname(__file__))
        base_path = os.path.dirname(os.path.dirname(HERE))
        setup_path = os.path.join(base_path, "setup.py")
        if not os.path.isfile(setup_path):
            raise Exception(
                'No "setup.py" file found and running in DEV mode!')

        with open(setup_path, "r") as fh:
            lines = fh.read().split("\n")

        start = None
        end = None
        for idx, line in enumerate(lines):
            if line.startswith("spyder_plugins_entry_points"):
                start = idx + 1
                continue

            if start is not None:
                if line.startswith("]"):
                    end = idx + 1
                    break

        internal_plugins = {}
        entry_points_list = "[" + "\n".join(lines[start:end])
        spyder_plugin_entry_points = ast.literal_eval(entry_points_list)
        for entry_point in spyder_plugin_entry_points:
            try:
                name, module = entry_point.split(" = ")
                name = name.strip()
                module = module.strip()
                module, class_name = module.split(":")
            except Exception:
                logger.error(
                    '"setup.py" entry point "{entry_point}" is malformed!'
                    "".format(entry_point=entry_point))

            try:
                mod = importlib.import_module(module)
                internal_plugins[name] = getattr(mod, class_name, None)
            except (ModuleNotFoundError, ImportError):
                pass

    return internal_plugins
Esempio n. 24
0
    def restart_kernel(self):
        """
        Restart the associated kernel.

        Took this code from the qtconsole project
        Licensed under the BSD license
        """
        sw = self.shellwidget

        if not running_under_pytest() and self.ask_before_restart:
            message = _('Are you sure you want to restart the kernel?')
            buttons = QMessageBox.Yes | QMessageBox.No
            result = QMessageBox.question(self, _('Restart kernel?'),
                                          message, buttons)
        else:
            result = None

        if (result == QMessageBox.Yes or
                running_under_pytest() or
                not self.ask_before_restart):
            if sw.kernel_manager:
                if self.infowidget.isVisible():
                    self.infowidget.hide()
                self._show_loading_page()

                # Close comm
                sw.spyder_kernel_comm.close()
                self.restart_thread = QThread()
                self.restart_thread.run = self._restart_thread_main
                self.restart_thread.error = None
                self.restart_thread.finished.connect(
                    lambda: self._finalise_restart(True))
                self.restart_thread.start()

            else:
                sw._append_plain_text(
                    _('Cannot restart a kernel not started by Spyder\n'),
                    before_prompt=True
                )
                self._hide_loading_page()
Esempio n. 25
0
    def show_tour_message(self, force=False):
        """
        Show message about starting the tour the first time Spyder starts.

        Parameters
        ----------
        force: bool
            Force the display of the tour message.
        """
        should_show_tour = self.get_conf('show_tour_message')
        if force or (should_show_tour and not running_under_pytest()
                     and not get_safe_mode()):
            self.set_conf('show_tour_message', False)
            self.get_container().show_tour_message()
Esempio n. 26
0
    def send(self, method, params, kind):
        """Send message to transport."""
        if self.is_down():
            return

        if ClientConstants.CANCEL in params:
            return
        _id = self.request_seq
        if kind == MessageKind.REQUEST:
            msg = {
                'id': self.request_seq,
                'method': method,
                'params': params
            }
            self.req_status[self.request_seq] = method
        elif kind == MessageKind.RESPONSE:
            msg = {
                'id': self.request_seq,
                'result': params
            }
        elif kind == MessageKind.NOTIFICATION:
            msg = {
                'method': method,
                'params': params
            }

        logger.debug('Perform request {0} with id {1}'.format(method, _id))

        # Save requests to check their ordering.
        if running_under_pytest():
            self._requests.append((_id, method))

        # Try sending a message. If the send queue is full, keep trying for a
        # a second before giving up.
        timeout = 1
        start_time = time.time()
        timeout_time = start_time + timeout
        while True:
            try:
                self.zmq_out_socket.send_pyobj(msg, flags=zmq.NOBLOCK)
                self.request_seq += 1
                return int(_id)
            except zmq.error.Again:
                if time.time() > timeout_time:
                    self.sig_went_down.emit(self.language)
                    return
                # The send queue is full! wait 0.1 seconds before retrying.
                if self.initialized:
                    logger.warning("The send queue is full! Retrying...")
                time.sleep(.1)
Esempio n. 27
0
    def check_heartbeat(self, language):
        """
        Check if client or server for a given language are down.
        """
        # This avoids an odd error when running our tests.
        if running_under_pytest():
            if not getattr(self, 'clients', None):
                return

        client = self.clients[language]
        status = client['status']
        instance = client.get('instance', None)
        if instance is not None:
            if instance.is_down() or status != self.RUNNING:
                instance.sig_went_down.emit(language)
Esempio n. 28
0
    def on_initialize(self):
        if self.main:
            self.main.sig_pythonpath_changed.connect(
                self.sig_pythonpath_changed)

        # Do not start providers on tests unless necessary
        if running_under_pytest():
            if not os.environ.get('SPY_TEST_USE_INTROSPECTION'):
                # Prevent providers from receiving configuration updates
                for provider_name in self.providers:
                    provider_info = self.providers[provider_name]
                    CONF.unobserve_configuration(provider_info['instance'])
                return

        self.start_all_providers()
Esempio n. 29
0
def run_vcs_tool(path, action):
    """If path is a valid VCS repository, run the corresponding VCS tool
    Supported VCS actions: 'commit', 'browse'
    Return False if the VCS tool is not installed"""
    info = get_vcs_info(get_vcs_root(path))
    tools = info['actions'][action]
    for tool, args in tools:
        if programs.find_program(tool):
            if not running_under_pytest():
                programs.run_program(tool, args, cwd=path)
            else:
                return True
            return
    else:
        cmdnames = [name for name, args in tools]
        raise ActionToolNotFound(info['name'], action, cmdnames)
Esempio n. 30
0
def run_vcs_tool(path, action):
    """If path is a valid VCS repository, run the corresponding VCS tool
    Supported VCS actions: 'commit', 'browse'
    Return False if the VCS tool is not installed"""
    info = get_vcs_info(get_vcs_root(path))
    tools = info['actions'][action]
    for tool, args in tools:
        if programs.find_program(tool):
            if not running_under_pytest():
                programs.run_program(tool, args, cwd=path)
            else:
                return True
            return
    else:
        cmdnames = [name for name, args in tools]
        raise ActionToolNotFound(info['name'], action, cmdnames)
Esempio n. 31
0
    def _submit_to_github(self):
        """Action to take when pressing the submit button."""
        # Getting description and traceback
        title = self.title.text()
        description = self.input_description.toPlainText()
        traceback = self.error_traceback[:-1]  # Remove last EOL

        # Render issue
        if traceback:
            issue_text = self.render_issue(description=description,
                                           traceback=traceback)
        else:
            issue_text = description

        try:
            if running_under_pytest():
                org = 'ccordoba12'
            else:
                org = self._github_org

            repo = self._github_repo
            github_backend = GithubBackend(org, repo, parent_widget=self)
            github_report = github_backend.send_report(title, issue_text)

            if github_report:
                self.close()

        except Exception:
            ret = QMessageBox.question(
                self,
                _('Error'),
                _("An error occurred while trying to send the issue to "
                  "Github automatically. Would you like to open it "
                  "manually?<br><br>"
                  "If so, please make sure to paste your clipboard "
                  "into the issue report box that will appear in a new "
                  "browser tab before clicking <i>Submit</i> on that "
                  "page."),
            )

            if ret in [QMessageBox.Yes, QMessageBox.Ok]:
                QApplication.clipboard().setText(issue_text)
                issue_body = (
                    " \n<!---   *** BEFORE SUBMITTING: PASTE CLIPBOARD HERE "
                    "TO COMPLETE YOUR REPORT ***   ---!>\n")

                self.open_web_report(body=issue_body, title=title)
Esempio n. 32
0
    def try_recover_from_autosave(self):
        """
        Offer to recover files from autosave.

        Read pid files to get a list of files that can possibly be recovered,
        then ask the user what to do with these files, and finally remove
        the pid files.
        """
        files_to_recover, pidfiles = self.get_files_to_recover()
        parent = self.editor if running_under_pytest() else self.editor.main
        dialog = RecoveryDialog(files_to_recover, parent=parent)
        dialog.exec_if_nonempty()
        self.recover_files_to_open = dialog.files_to_open[:]
        for pidfile in pidfiles:
            try:
                os.remove(pidfile)
            except (IOError, OSError):
                pass
Esempio n. 33
0
 def perform_request(self, req_id, method, params):
     response = None
     if method in self.sender_registry:
         logger.debug('Perform request {0} with id {1}'.format(
             method, req_id))
         handler_name = self.sender_registry[method]
         handler = getattr(self, handler_name)
         response = handler(params)
         if method in self.handler_registry:
             converter_name = self.handler_registry[method]
             converter = getattr(self, converter_name)
             if response is not None:
                 response = converter(response)
     if not isinstance(response, (dict, type(None))):
         if not running_under_pytest():
             self.sig_client_wrong_response.emit(method, response)
     else:
         self.sig_response_ready.emit(req_id, response or {})
Esempio n. 34
0
    def start_client(self, language):
        """Start an LSP client for a given language."""
        started = False
        if language in self.clients:
            language_client = self.clients[language]
            queue = self.register_queue[language]

            # Don't start LSP services when testing unless we demand
            # them.
            if running_under_pytest():
                if not os.environ.get('SPY_TEST_USE_INTROSPECTION'):
                    return started

            # Start client
            started = language_client['status'] == self.RUNNING
            if language_client['status'] == self.STOPPED:
                config = language_client['config']

                if not config['external']:
                    port = select_port(default_port=config['port'])
                    config['port'] = port

                language_client['instance'] = LSPClient(
                    parent=self,
                    server_settings=config,
                    folder=self.get_root_path(language),
                    language=language
                )

                # Connect signals emitted by the client to the methods that
                # can handle them
                if self.main and self.main.editor:
                    language_client['instance'].sig_initialize.connect(
                        self.main.editor.register_lsp_server_settings)

                logger.info("Starting LSP client for {}...".format(language))
                language_client['instance'].start()
                language_client['status'] = self.RUNNING
                for entry in queue:
                    language_client.register_file(*entry)
                self.register_queue[language] = []
        return started
Esempio n. 35
0
    def env(self):
        """Env vars for kernels"""
        # Add our PYTHONPATH to the kernel
        pathlist = CONF.get('main', 'spyder_pythonpath', default=[])

        default_interpreter = CONF.get('main_interpreter', 'default')
        pypath = add_pathlist_to_PYTHONPATH([], pathlist, ipyconsole=True,
                                            drop_env=False)

        # Environment variables that we need to pass to our sitecustomize
        umr_namelist = CONF.get('main_interpreter', 'umr/namelist')

        if PY2:
            original_list = umr_namelist[:]
            for umr_n in umr_namelist:
                try:
                    umr_n.encode('utf-8')
                except UnicodeDecodeError:
                    umr_namelist.remove(umr_n)
            if original_list != umr_namelist:
                CONF.set('main_interpreter', 'umr/namelist', umr_namelist)

        env_vars = {
            'SPY_EXTERNAL_INTERPRETER': not default_interpreter,
            'SPY_UMR_ENABLED': CONF.get('main_interpreter', 'umr/enabled'),
            'SPY_UMR_VERBOSE': CONF.get('main_interpreter', 'umr/verbose'),
            'SPY_UMR_NAMELIST': ','.join(umr_namelist),
            'SPY_RUN_LINES_O': CONF.get('ipython_console', 'startup/run_lines'),
            'SPY_PYLAB_O': CONF.get('ipython_console', 'pylab'),
            'SPY_BACKEND_O': CONF.get('ipython_console', 'pylab/backend'),
            'SPY_AUTOLOAD_PYLAB_O': CONF.get('ipython_console',
                                             'pylab/autoload'),
            'SPY_FORMAT_O': CONF.get('ipython_console',
                                     'pylab/inline/figure_format'),
            'SPY_BBOX_INCHES_O': CONF.get('ipython_console',
                                          'pylab/inline/bbox_inches'),
            'SPY_RESOLUTION_O': CONF.get('ipython_console',
                                         'pylab/inline/resolution'),
            'SPY_WIDTH_O': CONF.get('ipython_console', 'pylab/inline/width'),
            'SPY_HEIGHT_O': CONF.get('ipython_console', 'pylab/inline/height'),
            'SPY_USE_FILE_O': CONF.get('ipython_console',
                                       'startup/use_run_file'),
            'SPY_RUN_FILE_O': CONF.get('ipython_console', 'startup/run_file'),
            'SPY_AUTOCALL_O': CONF.get('ipython_console', 'autocall'),
            'SPY_GREEDY_O': CONF.get('ipython_console', 'greedy_completer'),
            'SPY_JEDI_O': CONF.get('ipython_console', 'jedi_completer'),
            'SPY_SYMPY_O': CONF.get('ipython_console', 'symbolic_math'),
            'SPY_TESTING': running_under_pytest() or SAFE_MODE,
            'SPY_HIDE_CMD': CONF.get('ipython_console', 'hide_cmd_windows')
        }

        if self.is_pylab is True:
            env_vars['SPY_AUTOLOAD_PYLAB_O'] = True
            env_vars['SPY_SYMPY_O'] = False
            env_vars['SPY_RUN_CYTHON'] = False
        if self.is_sympy is True:
            env_vars['SPY_AUTOLOAD_PYLAB_O'] = False
            env_vars['SPY_SYMPY_O'] = True
            env_vars['SPY_RUN_CYTHON'] = False
        if self.is_cython is True:
            env_vars['SPY_AUTOLOAD_PYLAB_O'] = False
            env_vars['SPY_SYMPY_O'] = False
            env_vars['SPY_RUN_CYTHON'] = True

        # Add our PYTHONPATH to env_vars
        env_vars.update(pypath)

        # Making all env_vars strings
        for key,var in iteritems(env_vars):
            if PY2:
                # Try to convert vars first to utf-8.
                try:
                    unicode_var = to_text_string(var)
                except UnicodeDecodeError:
                    # If that fails, try to use the file system
                    # encoding because one of our vars is our
                    # PYTHONPATH, and that contains file system
                    # directories
                    try:
                        unicode_var = to_unicode_from_fs(var)
                    except:
                        # If that also fails, make the var empty
                        # to be able to start Spyder.
                        # See https://stackoverflow.com/q/44506900/438386
                        # for details.
                        unicode_var = ''
                env_vars[key] = to_binary_string(unicode_var,
                                                 encoding='utf-8')
            else:
                env_vars[key] = to_text_string(var)
        return env_vars
Esempio n. 36
0
    def lock(self):
        """
        Acquire this lock.

        @rtype: C{bool}
        @return: True if the lock is acquired, false otherwise.

        @raise: Any exception os.symlink() may raise, other than
        EEXIST.
        """
        clean = True
        while True:
            try:
                symlink(str(os.getpid()), self.name)
            except OSError as e:
                if _windows and e.errno in (errno.EACCES, errno.EIO):
                    # The lock is in the middle of being deleted because we're
                    # on Windows where lock removal isn't atomic.  Give up, we
                    # don't know how long this is going to take.
                    return False
                if e.errno == errno.EEXIST:
                    try:
                        pid = readlink(self.name)
                    except OSError as e:
                        if e.errno == errno.ENOENT:
                            # The lock has vanished, try to claim it in the
                            # next iteration through the loop.
                            continue
                        raise
                    except IOError as e:
                        if _windows and e.errno == errno.EACCES:
                            # The lock is in the middle of being
                            # deleted because we're on Windows where
                            # lock removal isn't atomic.  Give up, we
                            # don't know how long this is going to
                            # take.
                            return False
                        raise
                    try:
                        if kill is not None:
                            kill(int(pid), 0)
                        # Verify that the running process corresponds to
                        # a Spyder one
                        p = psutil.Process(int(pid))

                        # Valid names for main script
                        names = set(['spyder', 'spyder3', 'spyder.exe',
                                     'spyder3.exe', 'bootstrap.py',
                                     'spyder-script.py'])
                        if running_under_pytest():
                            names.add('runtests.py')

                        # Check the first three command line arguments
                        arguments = set(os.path.basename(arg)
                                        for arg in p.cmdline()[:3])
                        conditions = [names & arguments]
                        if not any(conditions):
                            raise(OSError(errno.ESRCH, 'No such process'))
                    except OSError as e:
                        if e.errno == errno.ESRCH:
                            # The owner has vanished, try to claim it in the
                            # next iteration through the loop.
                            try:
                                rmlink(self.name)
                            except OSError as e:
                                if e.errno == errno.ENOENT:
                                    # Another process cleaned up the lock.
                                    # Race them to acquire it in the next
                                    # iteration through the loop.
                                    continue
                                raise
                            clean = False
                            continue
                        raise
                    return False
                raise
            self.locked = True
            self.clean = clean
            return True
Esempio n. 37
0
def main():
    """
    Start Spyder application.

    If single instance mode is turned on (default behavior) and an instance of
    Spyder is already running, this will just parse and send command line
    options to the application.
    """
    # Parse command line options
    if running_under_pytest():
        try:
            from unittest.mock import Mock
        except ImportError:
            from mock import Mock # Python 2

        options = Mock()
        options.new_instance = False
        options.reset_config_files = False
        options.debug_info = None
        args = None
    else:
        options, args = get_options()

    # Store variable to be used in self.restart (restart spyder instance)
    os.environ['SPYDER_ARGS'] = str(sys.argv[1:])

    #==========================================================================
    # Proper high DPI scaling is available in Qt >= 5.6.0. This attibute must
    # be set before creating the application.
    #==========================================================================
    if CONF.get('main', 'high_dpi_custom_scale_factor'):
        factors = str(CONF.get('main', 'high_dpi_custom_scale_factors'))
        f = list(filter(None, factors.split(';')))
        if len(f) == 1:
            os.environ['QT_SCALE_FACTOR'] = f[0]
        else:
            os.environ['QT_SCREEN_SCALE_FACTORS'] = factors
    else:
        os.environ['QT_SCALE_FACTOR'] = ''
        os.environ['QT_SCREEN_SCALE_FACTORS'] = ''

    if sys.platform == 'darwin':
        # Prevent Spyder from crashing in macOS if locale is not defined
        LANG = os.environ.get('LANG')
        LC_ALL = os.environ.get('LC_ALL')
        if bool(LANG) and not bool(LC_ALL):
            LC_ALL = LANG
        elif not bool(LANG) and bool(LC_ALL):
            LANG = LC_ALL
        else:
            LANG = LC_ALL = 'en_US.UTF-8'

        os.environ['LANG'] = LANG
        os.environ['LC_ALL'] = LC_ALL

        # Don't show useless warning in the terminal where Spyder
        # was started
        # See issue 3730
        os.environ['EVENT_NOKQUEUE'] = '1'
    else:
        # Prevent our kernels to crash when Python fails to identify
        # the system locale.
        # Fixes issue 7051.
        try:
            from locale import getlocale
            getlocale()
        except ValueError:
            # This can fail on Windows. See issue 6886
            try:
                os.environ['LANG'] = 'C'
                os.environ['LC_ALL'] = 'C'
            except Exception:
                pass

    if options.debug_info:
        levels = {'minimal': '2', 'verbose': '3'}
        os.environ['SPYDER_DEBUG'] = levels[options.debug_info]

    if CONF.get('main', 'single_instance') and not options.new_instance \
      and not options.reset_config_files and not running_in_mac_app():
        # Minimal delay (0.1-0.2 secs) to avoid that several
        # instances started at the same time step in their
        # own foots while trying to create the lock file
        time.sleep(random.randrange(1000, 2000, 90)/10000.)

        # Lock file creation
        lock_file = get_conf_path('spyder.lock')
        lock = lockfile.FilesystemLock(lock_file)

        # Try to lock spyder.lock. If it's *possible* to do it, then
        # there is no previous instance running and we can start a
        # new one. If *not*, then there is an instance already
        # running, which is locking that file
        try:
            lock_created = lock.lock()
        except:
            # If locking fails because of errors in the lockfile
            # module, try to remove a possibly stale spyder.lock.
            # This is reported to solve all problems with
            # lockfile (See issue 2363)
            try:
                if os.name == 'nt':
                    if osp.isdir(lock_file):
                        import shutil
                        shutil.rmtree(lock_file, ignore_errors=True)
                else:
                    if osp.islink(lock_file):
                        os.unlink(lock_file)
            except:
                pass

            # Then start Spyder as usual and *don't* continue
            # executing this script because it doesn't make
            # sense
            from spyder.app import mainwindow
            if running_under_pytest():
                return mainwindow.main()
            else:
                mainwindow.main()
                return

        if lock_created:
            # Start a new instance
            from spyder.app import mainwindow
            if running_under_pytest():
                return mainwindow.main()
            else:
                mainwindow.main()
        else:
            # Pass args to Spyder or print an informative
            # message
            if args:
                send_args_to_spyder(args)
            else:
                print("Spyder is already running. If you want to open a new \n"
                      "instance, please pass to it the --new-instance option")
    else:
        from spyder.app import mainwindow
        if running_under_pytest():
            return mainwindow.main()
        else:
            mainwindow.main()