Exemple #1
0
def get_git_revision(repopath):
    """
    Return Git revision for the repository located at repopath
    
    Result is a tuple (latest commit hash, branch), with None values on
    error
    """
    try:
        git = programs.find_program('git')
        assert git is not None and osp.isdir(osp.join(repopath, '.git'))
        commit = programs.run_program(git, ['rev-parse', '--short', 'HEAD'],
                                      cwd=repopath).communicate()
        commit = commit[0].strip()
        if PY3:
            commit = commit.decode(sys.getdefaultencoding())

        # Branch
        branches = programs.run_program(git, ['branch'],
                                        cwd=repopath).communicate()
        branches = branches[0]
        if PY3:
            branches = branches.decode(sys.getdefaultencoding())
        branches = branches.split('\n')
        active_branch = [b for b in branches if b.startswith('*')]
        if len(active_branch) != 1:
            branch = None
        else:
            branch = active_branch[0].split(None, 1)[1]

        return commit, branch
    except (subprocess.CalledProcessError, AssertionError, AttributeError):
        return None, None
Exemple #2
0
def get_git_refs(repopath):
    """
    Return Git active branch, state, branches (plus tags).
    """
    tags = []
    branches = []
    branch = ''
    files_modifed = []

    if os.path.isfile(repopath):
        repopath = os.path.dirname(repopath)

    try:

        git = programs.find_program('git')

        # Files modified
        out, err = programs.run_program(
            git, ['status', '-s'],
            cwd=repopath,
        ).communicate()

        if PY3:
            out = out.decode(sys.getdefaultencoding())
        files_modifed = [line.strip() for line in out.split('\n') if line]

        # Tags
        out, err = programs.run_program(
            git, ['tag'],
            cwd=repopath,
        ).communicate()

        if PY3:
            out = out.decode(sys.getdefaultencoding())
        tags = [line.strip() for line in out.split('\n') if line]

        # Branches
        out, err = programs.run_program(
            git, ['branch', '-a'],
            cwd=repopath,
        ).communicate()

        if PY3:
            out = out.decode(sys.getdefaultencoding())

        lines = [line.strip() for line in out.split('\n') if line]
        for line in lines:
            if line.startswith('*'):
                line = line.replace('*', '').strip()
                branch = line

            branches.append(line)

    except (subprocess.CalledProcessError, AttributeError, OSError):
        pass

    return branches + tags, branch, files_modifed
Exemple #3
0
def create_program_action(parent, text, name, icon=None, nt_name=None):
    """Create action to run a program"""
    if is_text_string(icon):
        icon = get_icon(icon)
    if os.name == 'nt' and nt_name is not None:
        name = nt_name
    path = programs.find_program(name)
    if path is not None:
        return create_action(parent, text, icon=icon,
                             triggered=lambda: programs.run_program(name))
Exemple #4
0
def create_program_action(parent, text, name, icon=None, nt_name=None):
    """Create action to run a program"""
    if is_text_string(icon):
        icon = ima.get_icon(icon)
    if os.name == 'nt' and nt_name is not None:
        name = nt_name
    path = programs.find_program(name)
    if path is not None:
        return create_action(parent,
                             text,
                             icon=icon,
                             triggered=lambda: programs.run_program(name))
Exemple #5
0
    def validate(self):
        host_text = self.host_input.text()
        cmd_text = self.cmd_input.text()

        if not self.HOST_REGEX.match(host_text):
            self.button_ok.setEnabled(False)
            self.host_input.setStyleSheet(self.INVALID_CSS)
            if bool(host_text):
                self.host_input.setToolTip(_('Hostname must be valid'))
            else:
                self.host_input.setToolTip(
                    _('Hostname or IP address of the host on which the server '
                      'is running. Must be non empty.'))
        else:
            self.host_input.setStyleSheet(self.VALID_CSS)
            self.host_input.setToolTip(_('Hostname is valid'))
            self.button_ok.setEnabled(True)

        if not self.external:
            if not self.NON_EMPTY_REGEX.match(cmd_text):
                self.button_ok.setEnabled(False)
                self.cmd_input.setStyleSheet(self.INVALID_CSS)
                self.cmd_input.setToolTip(
                    _('Command used to start the LSP server locally. Must be '
                      'non empty'))
                return

            if find_program(cmd_text) is None:
                self.button_ok.setEnabled(False)
                self.cmd_input.setStyleSheet(self.INVALID_CSS)
                self.cmd_input.setToolTip(
                    _('Program was not found '
                      'on your system'))
            else:
                self.cmd_input.setStyleSheet(self.VALID_CSS)
                self.cmd_input.setToolTip(
                    _('Program was found on your '
                      'system'))
                self.button_ok.setEnabled(True)

        try:
            json.loads(self.conf_input.toPlainText())
            try:
                self.json_label.setText(self.JSON_VALID)
            except Exception:
                pass
        except ValueError:
            try:
                self.json_label.setText(self.JSON_INVALID)
                self.button_ok.setEnabled(False)
            except Exception:
                pass
Exemple #6
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):
            programs.run_program(tool, args, cwd=path)
            return
    else:
        cmdnames = [name for name, args in tools]
        raise ActionToolNotFound(info['name'], action, cmdnames)
Exemple #7
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):
            programs.run_program(tool, args, cwd=path)
            return
    else:
        cmdnames = [name for name, args in tools]
        raise ActionToolNotFound(info['name'], action, cmdnames)
Exemple #8
0
    def validate(self):
        host_text = self.host_input.text()
        cmd_text = self.cmd_input.text()
        if not self.HOST_REGEX.match(host_text):
            self.button_ok.setEnabled(False)
            self.host_input.setStyleSheet("QLineEdit{border: 1px solid red;}")
            self.host_input.setToolTip('Hostname must be valid')
            return
        else:
            self.host_input.setStyleSheet(
                "QLineEdit{border: 1px solid green;}")
            self.host_input.setToolTip('Hostname is valid')
            self.button_ok.setEnabled(True)

        if not self.external:
            if not self.NON_EMPTY_REGEX.match(cmd_text):
                self.button_ok.setEnabled(False)
                self.cmd_input.setStyleSheet(
                    "QLineEdit{border: 1px solid red;}")
                self.cmd_input.setToolTip('Command must be non empty')
                return

            if find_program(cmd_text) is None:
                self.button_ok.setEnabled(False)
                self.cmd_input.setStyleSheet(
                    "QLineEdit{border: 1px solid red;}")
                self.cmd_input.setToolTip('Program was not found '
                                          'on your system')
                return
            else:
                self.cmd_input.setStyleSheet(
                    "QLineEdit{border: 1px solid green;}")
                self.cmd_input.setToolTip('Program was found on your system')
                self.button_ok.setEnabled(True)
        try:
            json.loads(self.conf_input.toPlainText())
            try:
                self.json_label.setText(self.JSON_VALID)
            except:
                pass
        except (ValueError, json.decoder.JSONDecodeError):
            try:
                self.json_label.setText(self.JSON_INVALID)
                self.button_ok.setEnabled(False)
            except:
                pass
Exemple #9
0
    def validate(self):
        host_text = self.host_input.text()
        cmd_text = self.cmd_input.text()
        if not self.HOST_REGEX.match(host_text):
            self.button_ok.setEnabled(False)
            self.host_input.setStyleSheet("QLineEdit{border: 1px solid red;}")
            self.host_input.setToolTip('Hostname must be valid')
            return
        else:
            self.host_input.setStyleSheet(
                "QLineEdit{border: 1px solid green;}")
            self.host_input.setToolTip('Hostname is valid')
            self.button_ok.setEnabled(True)

        if not self.external:
            if not self.NON_EMPTY_REGEX.match(cmd_text):
                self.button_ok.setEnabled(False)
                self.cmd_input.setStyleSheet(
                    "QLineEdit{border: 1px solid red;}")
                self.cmd_input.setToolTip('Command must be non empty')
                return

            if find_program(cmd_text) is None:
                self.button_ok.setEnabled(False)
                self.cmd_input.setStyleSheet(
                    "QLineEdit{border: 1px solid red;}")
                self.cmd_input.setToolTip('Program was not found '
                                          'on your system')
                return
            else:
                self.cmd_input.setStyleSheet(
                    "QLineEdit{border: 1px solid green;}")
                self.cmd_input.setToolTip('Program was found on your system')
                self.button_ok.setEnabled(True)
        try:
            json.loads(self.conf_input.toPlainText())
            try:
                self.json_label.setText(self.JSON_VALID)
            except:
                pass
        except (ValueError, json.decoder.JSONDecodeError):
            try:
                self.json_label.setText(self.JSON_INVALID)
                self.button_ok.setEnabled(False)
            except:
                pass
Exemple #10
0
docs_dest = osp.join(app_python_lib, 'spyder', 'doc')
shutil.copytree(docs_orig, docs_dest)

# Create a minimal library inside Resources to add it to PYTHONPATH instead of
# app_python_lib. This must be done when the user changes to an interpreter
# that's not the one that comes with the app, to forbid importing modules
# inside the app.
minimal_lib = osp.join(app_python_lib, 'minimal-lib')
os.mkdir(minimal_lib)
minlib_pkgs = ['spyder', 'spyderplugins']
for p in minlib_pkgs:
    shutil.copytree(osp.join(app_python_lib, p), osp.join(minimal_lib, p))

# Add necessary Python programs to the app
PROGRAMS = ['pylint', 'pep8']
system_progs = [find_program(p) for p in PROGRAMS]
progs_dest = [resources + osp.sep + p for p in PROGRAMS]
for i in range(len(PROGRAMS)):
    shutil.copy2(system_progs[i], progs_dest[i])

# Add deps needed for PROGRAMS to the app
deps = []
for package in os.listdir(system_python_lib):
    for d in DEPS:
        if package.startswith(d):
            deps.append(package)

for i in deps:
    if osp.isdir(osp.join(system_python_lib, i)):
        shutil.copytree(osp.join(system_python_lib, i),
                        osp.join(app_python_lib, i))
Exemple #11
0
    def setup_page(self):
        """Create configuration page."""
        options_layout = QGridLayout()
        # Custom shell options
        shell_group = QGroupBox(_("Terminal shell"))
        shell_layout = QVBoxLayout()
        if WINDOWS:
            self.shells = WINDOWS_SHELLS
        else:
            self.shells = UNIX_SHELLS

        valid_shells = []
        for shell in self.shells:
            if find_program(shell) is not None:
                valid_shells.append(shell)
        valid_shells = zip(valid_shells, valid_shells)
        if WINDOWS:
            default_option = 'cmd'
        elif sys.platform.startswith('linux'):
            default_option = 'bash'
        else:
            mac_ver = LooseVersion(platform.mac_ver()[0])
            if mac_ver >= LooseVersion('10.15.0'):
                # Catalina changed the default shell to zsh
                default_option = 'zsh'
            else:
                default_option = 'bash'
        shell_combo = self.create_combobox(_("Select the shell interpreter:"),
                                           valid_shells,
                                           'shell',
                                           restart=True,
                                           default=default_option)
        shell_combo.combobox.setMinimumContentsLength(15)
        shell_layout.addWidget(shell_combo)
        shell_group.setLayout(shell_layout)
        shell_layout.addStretch(1)
        options_layout.addWidget(shell_group)

        # Display preferences
        display_group = QGroupBox(_("Terminal display preferences"))
        display_layout = QVBoxLayout()
        # Custom buffer limit
        self.buffer_sb = self.create_spinbox(_("Buffer limit: "),
                                             "",
                                             'buffer_limit',
                                             min_=100,
                                             default=1000,
                                             max_=1000000,
                                             step=1)
        display_layout.addWidget(self.buffer_sb)
        display_group.setLayout(display_layout)
        display_layout.addStretch(1)
        options_layout.addWidget(display_group)

        # Style preferences
        terminal_group = QGroupBox(_("Terminal style preferences"))
        # Custom bar option
        cursor_choices = [(_("Block"), 0), (_("Underline"), 1), (_("Bar"), 2)]
        self.cursor_combo = self.create_combobox(_("Type of cursor:"),
                                                 cursor_choices, 'cursor_type')
        self.cursor_combo.combobox.setMinimumContentsLength(15)
        options_layout.addWidget(self.cursor_combo)

        # Custom sound option
        self.sound_cb = self.create_checkbox(
            _("Enable bell sound"),
            'sound',
            tip=_("Enable bell sound on terminal"))
        options_layout.addWidget(self.sound_cb)

        # Visual bell option
        self.cursor_blink_cb = self.create_checkbox(
            _("Enable cursor blink"),
            'cursor_blink',
            tip=_("_Enable cursor blink on terminal"))
        options_layout.addWidget(self.cursor_blink_cb)

        terminal_group.setLayout(options_layout)

        layout = QVBoxLayout()
        layout.addWidget(shell_group)
        layout.addWidget(display_group)
        layout.addWidget(terminal_group)
        layout.addStretch(1)

        self.setLayout(layout)
Exemple #12
0
from spyder.utils.qthelpers import create_toolbutton
from spyder.widgets.comboboxes import (is_module_or_package,
                                       PythonModulesComboBox)
from spyder.widgets.onecolumntree import OneColumnTree
from spyder.widgets.variableexplorer.texteditor import TextEditor

# This is needed for testing this module as a stand alone script
try:
    _ = get_translation("pylint", "spyder_pylint")
except KeyError as error:
    import gettext
    _ = gettext.gettext

PYLINT = 'pylint'
if PY3:
    if programs.find_program('pylint3'):
        PYLINT = 'pylint3'
    elif programs.find_program('python3-pylint'):
        PYLINT = 'python3-pylint'

locale_codec = QTextCodec.codecForLocale()
PYLINT_PATH = programs.find_program(PYLINT)


def get_pylint_version():
    """Return pylint version"""
    if PYLINT_PATH is None:
        return
    cwd = osp.dirname(PYLINT_PATH)
    args = ['--version']
    if os.name == 'nt':
Exemple #13
0
def is_lineprofiler_installed():
    """
    Checks if the program and the library for line_profiler is installed.
    """
    return (programs.is_module_installed('line_profiler')
            and programs.find_program('kernprof') is not None)
Exemple #14
0
    def __init__(self, parent):
        """Widget constructor."""
        SpyderPluginWidget.__init__(self, parent)
        self.tab_widget = None
        self.menu_actions = None
        self.server_retries = 0
        self.server_ready = False
        self.port = select_port(default_port=8071)

        self.cmd = '/usr/bin/env bash'
        if WINDOWS:
            self.cmd = find_program('cmd.exe')

        self.server_stdout = subprocess.PIPE
        self.server_stderr = subprocess.PIPE
        self.stdout_file = osp.join(getcwd(), 'spyder_terminal_out.log')
        self.stderr_file = osp.join(getcwd(), 'spyder_terminal_err.log')
        if DEV:
            self.server_stdout = open(self.stdout_file, 'w')
            self.server_stderr = open(self.stderr_file, 'w')

        self.server = subprocess.Popen(
            [sys.executable, osp.join(LOCATION, 'server', 'main.py'),
             '--port', str(self.port), '--shell', self.cmd],
            stdout=self.server_stdout,
            stderr=self.server_stderr)

        self.main = parent

        self.terms = []
        self.untitled_num = 0

        self.project_path = None
        self.current_file_path = None
        self.current_cwd = getcwd()

        self.initialize_plugin()

        layout = QVBoxLayout()
        new_term_btn = create_toolbutton(self,
                                         icon=ima.icon('project_expanded'),
                                         tip=_('Open a new terminal'),
                                         triggered=self.create_new_term)
        menu_btn = create_toolbutton(self, icon=ima.icon('tooloptions'),
                                     tip=_('Options'))
        self.menu = QMenu(self)
        menu_btn.setMenu(self.menu)
        menu_btn.setPopupMode(menu_btn.InstantPopup)
        add_actions(self.menu, self.menu_actions)
        # if self.get_option('first_time', True):
        # self.setup_shortcuts()
        # self.shortcuts = self.create_shortcuts()
        corner_widgets = {Qt.TopRightCorner: [new_term_btn, menu_btn]}
        self.tabwidget = Tabs(self, menu=self.menu, actions=self.menu_actions,
                              corner_widgets=corner_widgets, rename_tabs=True)

        if hasattr(self.tabwidget, 'setDocumentMode') \
           and not sys.platform == 'darwin':
            # Don't set document mode to true on OSX because it generates
            # a crash when the console is detached from the main window
            # Fixes Issue 561
            self.tabwidget.setDocumentMode(True)
        self.tabwidget.currentChanged.connect(self.refresh_plugin)
        self.tabwidget.move_data.connect(self.move_tab)

        self.tabwidget.set_close_function(self.close_term)

        layout.addWidget(self.tabwidget)
        self.setLayout(layout)

        new_term_shortcut = QShortcut(QKeySequence("Ctrl+Alt+Shift+T"),
                                      self, self.create_new_term)
        new_term_shortcut.setContext(Qt.WidgetWithChildrenShortcut)

        self.__wait_server_to_start()
Exemple #15
0
    def setup(self):
        """Perform the setup of plugin's main menu and signals."""
        self.cmd = find_program(self.get_conf('shell'))
        server_args = [
            sys.executable, '-m', 'spyder_terminal.server',
             '--port', str(self.port), '--shell', self.cmd]
        self.server = QProcess(self)
        env = self.server.processEnvironment()
        for var in os.environ:
            env.insert(var, os.environ[var])
        self.server.setProcessEnvironment(env)
        self.server.errorOccurred.connect(self.handle_process_errors)
        self.server.setProcessChannelMode(QProcess.SeparateChannels)
        if self.stdout_file and self.stderr_file:
            self.server.setStandardOutputFile(self.stdout_file)
            self.server.setStandardErrorFile(self.stderr_file)
        self.server.start(server_args[0], server_args[1:])
        self.color_scheme = self.get_conf('appearance', 'ui_theme')
        self.theme = self.get_conf('appearance', 'selected')

        # Menu
        menu = self.get_options_menu()

        # Actions
        new_terminal_toolbar_action = self.create_toolbutton(
            TerminalMainWidgetToolbarSections.New,
            text=_("Open a new terminal"),
            icon=self.create_icon('expand_selection'),
            triggered=lambda: self.create_new_term(),
        )

        self.add_corner_widget(
            TerminalMainWidgetCornerToolbar.NewTerm,
            new_terminal_toolbar_action)

        new_terminal_cwd = self.create_action(
            TerminalMainWidgetActions.NewTerminalForCWD,
            text=_("New terminal in current working directory"),
            tip=_("Sets the pwd at the current working directory"),
            triggered=lambda: self.create_new_term(),
            shortcut_context='terminal',
            register_shortcut=True)

        self.new_terminal_project = self.create_action(
            TerminalMainWidgetActions.NewTerminalForProject,
            text=_("New terminal in current project"),
            tip=_("Sets the pwd at the current project directory"),
            triggered=lambda: self.create_new_term(path=self.project_path))

        new_terminal_file = self.create_action(
            TerminalMainWidgetActions.NewTerminalForFile,
            text=_("New terminal in current Editor file"),
            tip=_("Sets the pwd at the directory that contains the current "
                  "opened file"),
            triggered=lambda: self.create_new_term(
                path=self.current_file_path))

        rename_tab_action = self.create_action(
            TerminalMainWidgetActions.RenameTab,
            text=_("Rename terminal"),
            triggered=lambda: self.tab_name_editor())

        # Context menu actions
        self.create_action(
            TerminalMainWidgetActions.Copy,
            text=_('Copy text'),
            icon=self.create_icon('editcopy'),
            shortcut_context='terminal',
            triggered=lambda: self.copy(),
            register_shortcut=True)

        self.create_action(
            TerminalMainWidgetActions.Paste,
            text=_('Paste text'),
            icon=self.create_icon('editpaste'),
            shortcut_context='terminal',
            triggered=lambda: self.paste(),
            register_shortcut=True)

        self.create_action(
            TerminalMainWidgetActions.Clear,
            text=_('Clear terminal'),
            shortcut_context='terminal',
            triggered=lambda: self.clear(),
            register_shortcut=True)

        self.create_action(
            TerminalMainWidgetActions.ZoomIn,
            text=_('Zoom in'),
            shortcut_context='terminal',
            triggered=lambda: self.increase_font(),
            register_shortcut=True)

        self.create_action(
            TerminalMainWidgetActions.ZoomOut,
            text=_('Zoom out'),
            shortcut_context='terminal',
            triggered=lambda: self.decrease_font(),
            register_shortcut=True)

        # Create context menu
        self.create_menu(TermViewMenus.Context)

        # Add actions to options menu
        for item in [new_terminal_cwd, self.new_terminal_project,
                     new_terminal_file]:
            self.add_item_to_menu(
                item, menu=menu,
                section=TerminalMainWidgetMenuSections.New)

        self.add_item_to_menu(
            rename_tab_action, menu=menu,
            section=TerminalMainWidgetMenuSections.TabActions)
Exemple #16
0
def find_conda():
    """Find conda executable."""
    conda_exec = 'conda.bat' if WINDOWS else 'conda'
    conda = find_program(conda_exec)
    return conda
Exemple #17
0
def is_hg_installed():
    """Return True if Mercurial is installed"""
    return programs.find_program('hg') is not None
Exemple #18
0
                                       PythonModulesComboBox)
from spyder.widgets.onecolumntree import OneColumnTree
from spyder.widgets.variableexplorer.texteditor import TextEditor


# This is needed for testing this module as a stand alone script
try:
    _ = get_translation("pylint", "spyder_pylint")
except KeyError as error:
    import gettext
    _ = gettext.gettext


PYLINT = 'pylint'
if PY3:
    if programs.find_program('pylint3'):
        PYLINT = 'pylint3'
    elif programs.find_program('python3-pylint'):
        PYLINT = 'python3-pylint'


locale_codec = QTextCodec.codecForLocale()
PYLINT_PATH = programs.find_program(PYLINT)


def get_pylint_version():
    """Return pylint version"""
    if PYLINT_PATH is None:
        return
    cwd = osp.dirname(PYLINT_PATH)
    args = ['--version']
Exemple #19
0
shutil.copytree(docs_orig, docs_dest)

# Create a minimal library inside Resources to add it to PYTHONPATH instead of
# app_python_lib. This must be done when the user changes to an interpreter
# that's not the one that comes with the app, to forbid importing modules
# inside the app.
minimal_lib = osp.join(app_python_lib, 'minimal-lib')
os.mkdir(minimal_lib)
minlib_pkgs = ['spyder', 'spyder_breakpoints', 'spyder_io_dcm',
               'spyder_io_hdf5', 'spyder_profiler', 'spyder_pylint']
for p in minlib_pkgs:
    shutil.copytree(osp.join(app_python_lib, p), osp.join(minimal_lib, p))

# Add necessary Python programs to the app
PROGRAMS = ['pylint', 'pycodestyle']
system_progs = [find_program(p) for p in PROGRAMS]
progs_dest = [resources + osp.sep + p for p in PROGRAMS]
for i in range(len(PROGRAMS)):
    shutil.copy2(system_progs[i], progs_dest[i])

# Add deps needed for PROGRAMS to the app
deps = []
for package in os.listdir(system_python_lib):
    for d in DEPS:
        if package.startswith(d):
            deps.append(package)

for i in deps:
    if osp.isdir(osp.join(system_python_lib, i)):
        shutil.copytree(osp.join(system_python_lib, i),
                        osp.join(app_python_lib, i))
Exemple #20
0
def is_hg_installed():
    """Return True if Mercurial is installed"""
    return programs.find_program('hg') is not None
    def start(self, wdir=None, args=None, pythonpath=None):
        filename = to_text_string(self.filecombo.currentText())
        if wdir is None:
            wdir = self._last_wdir
            if wdir is None:
                wdir = osp.basename(filename)
        if args is None:
            args = self._last_args
            if args is None:
                args = []
        if pythonpath is None:
            pythonpath = self._last_pythonpath
        self._last_wdir = wdir
        self._last_args = args
        self._last_pythonpath = pythonpath

        self.datelabel.setText(_('Profiling, please wait...'))

        self.process = QProcess(self)
        self.process.setProcessChannelMode(QProcess.SeparateChannels)
        self.process.setWorkingDirectory(wdir)
        self.process.readyReadStandardOutput.connect(self.read_output)
        self.process.readyReadStandardError.connect(
            lambda: self.read_output(error=True))
        self.process.finished.connect(self.finished)
        self.stop_button.clicked.connect(self.process.kill)

        if pythonpath is not None:
            env = [to_text_string(_pth)
                   for _pth in self.process.systemEnvironment()]
            add_pathlist_to_PYTHONPATH(env, pythonpath)
            processEnvironment = QProcessEnvironment()
            for envItem in env:
                envName, separator, envValue = envItem.partition('=')
                processEnvironment.insert(envName, envValue)
            self.process.setProcessEnvironment(processEnvironment)

        self.output = ''
        self.error_output = ''

        if os.name == 'nt':
            # On Windows, one has to replace backslashes by slashes to avoid
            # confusion with escape characters (otherwise, for example, '\t'
            # will be interpreted as a tabulation):
            filename = osp.normpath(filename).replace(os.sep, '/')
            p_args = ['-lvb', '-o', '"' + self.DATAPATH + '"',
                      '"' + filename + '"']
            if args:
                p_args.extend(programs.shell_split(args))
            executable = '"' + programs.find_program('kernprof') + '"'
            executable += ' ' + ' '.join(p_args)
            executable = executable.replace(os.sep, '/')
            self.process.start(executable)
        else:
            p_args = ['-lvb', '-o', self.DATAPATH, filename]
            if args:
                p_args.extend(programs.shell_split(args))
            executable = 'kernprof'
            self.process.start(executable, p_args)

        running = self.process.waitForStarted()
        self.set_running_state(running)
        if not running:
            QMessageBox.critical(self, _("Error"),
                                 _("Process failed to start"))
Exemple #22
0
    def start(self, wdir=None, args=None, pythonpath=None):
        filename = to_text_string(self.filecombo.currentText())
        if wdir is None:
            wdir = self._last_wdir
            if wdir is None:
                wdir = osp.basename(filename)
        if args is None:
            args = self._last_args
            if args is None:
                args = []
        if pythonpath is None:
            pythonpath = self._last_pythonpath
        self._last_wdir = wdir
        self._last_args = args
        self._last_pythonpath = pythonpath

        self.datelabel.setText(_('Profiling, please wait...'))

        self.process = QProcess(self)
        self.process.setProcessChannelMode(QProcess.SeparateChannels)
        self.process.setWorkingDirectory(wdir)
        self.process.readyReadStandardOutput.connect(self.read_output)
        self.process.readyReadStandardError.connect(
            lambda: self.read_output(error=True))
        self.process.finished.connect(self.finished)
        self.stop_button.clicked.connect(self.process.kill)

        if pythonpath is not None:
            env = [to_text_string(_pth)
                   for _pth in self.process.systemEnvironment()]
            add_pathlist_to_PYTHONPATH(env, pythonpath)
            processEnvironment = QProcessEnvironment()
            for envItem in env:
                envName, separator, envValue = envItem.partition('=')
                processEnvironment.insert(envName, envValue)
            self.process.setProcessEnvironment(processEnvironment)

        self.output = ''
        self.error_output = ''

        if os.name == 'nt':
            # On Windows, one has to replace backslashes by slashes to avoid
            # confusion with escape characters (otherwise, for example, '\t'
            # will be interpreted as a tabulation):
            filename = osp.normpath(filename).replace(os.sep, '/')
            p_args = ['-lvb', '-o', '"' + self.DATAPATH + '"',
                      '"' + filename + '"']
            if args:
                p_args.extend(programs.shell_split(args))
            executable = '"' + programs.find_program('kernprof') + '"'
            executable += ' ' + ' '.join(p_args)
            executable = executable.replace(os.sep, '/')
            self.process.start(executable)
        else:
            p_args = ['-lvb', '-o', self.DATAPATH, filename]
            if args:
                p_args.extend(programs.shell_split(args))
            executable = 'kernprof'
            self.process.start(executable, p_args)

        running = self.process.waitForStarted()
        self.set_running_state(running)
        if not running:
            QMessageBox.critical(self, _("Error"),
                                 _("Process failed to start"))
def is_lineprofiler_installed():
    """
    Checks if the program and the library for line_profiler is installed.
    """
    return (programs.is_module_installed('line_profiler')
            and programs.find_program('kernprof') is not None)
Exemple #24
0
    def __init__(self, parent):
        """Widget constructor."""
        SpyderPluginWidget.__init__(self, parent)
        self.tab_widget = None
        self.menu_actions = None
        self.server_retries = 0
        self.server_ready = False
        self.port = select_port(default_port=8071)

        self.cmd = find_program(self.get_option('shell'))
        self.CONF = CONF
        self.server_stdout = subprocess.PIPE
        self.server_stderr = subprocess.PIPE
        self.stdout_file = osp.join(getcwd(), 'spyder_terminal_out.log')
        self.stderr_file = osp.join(getcwd(), 'spyder_terminal_err.log')
        if DEV:
            self.server_stdout = open(self.stdout_file, 'w')
            self.server_stderr = open(self.stderr_file, 'w')
        self.server = subprocess.Popen([
            sys.executable, '-m', 'spyder_terminal.server', '--port',
            str(self.port), '--shell', self.cmd
        ],
                                       stdout=self.server_stdout,
                                       stderr=self.server_stderr)

        self.main = parent

        self.terms = []
        self.untitled_num = 0

        self.project_path = None
        self.current_file_path = None
        self.current_cwd = getcwd()

        try:
            # Spyder 3
            self.initialize_plugin()
        except AttributeError:
            # Spyder 4
            pass

        layout = QVBoxLayout()
        new_term_btn = create_toolbutton(self,
                                         icon=ima.icon('expand_selection'),
                                         tip=_('Open a new terminal'),
                                         triggered=self.create_new_term)

        corner_widgets = {
            Qt.TopRightCorner: [new_term_btn, self.options_button]
        }
        self.tabwidget = Tabs(self,
                              menu=self._options_menu,
                              actions=self.menu_actions,
                              corner_widgets=corner_widgets,
                              rename_tabs=True)

        if hasattr(self.tabwidget, 'setDocumentMode') \
           and not sys.platform == 'darwin':
            # Don't set document mode to true on OSX because it generates
            # a crash when the console is detached from the main window
            # Fixes Issue 561
            self.tabwidget.setDocumentMode(True)
        self.tabwidget.currentChanged.connect(self.refresh_plugin)
        self.tabwidget.move_data.connect(self.move_tab)

        self.tabwidget.set_close_function(self.close_term)

        layout.addWidget(self.tabwidget)
        self.setLayout(layout)

        new_term_shortcut = QShortcut(
            CONF.get_shortcut(CONF_SECTION, 'new_term'), self,
            self.create_new_term)
        new_term_shortcut.setContext(Qt.WidgetWithChildrenShortcut)

        self.color_scheme = CONF.get('appearance', 'ui_theme')
        self.theme = CONF.get('appearance', 'selected')

        self.__wait_server_to_start()
Exemple #25
0
#
# Copyright © Spyder Project Contributors
# Licensed under the terms of the MIT License
#
"""Tests for pyenv.py"""

import sys
import time

import pytest

from spyder.config.base import running_in_ci
from spyder.utils.programs import find_program
from spyder.utils.pyenv import get_list_pyenv_envs, get_list_pyenv_envs_cache

if not find_program('pyenv'):
    pytest.skip("Requires pyenv to be installed", allow_module_level=True)


@pytest.mark.skipif(not running_in_ci(), reason="Only meant for CIs")
@pytest.mark.skipif(not sys.platform.startswith('linux'),
                    reason="Only runs on Linux")
def test_get_list_pyenv_envs():
    output = get_list_pyenv_envs()
    expected_envs = ['pyenv: 3.8.1']
    assert set(expected_envs) == set(output.keys())


@pytest.mark.skipif(not running_in_ci(), reason="Only meant for CIs")
@pytest.mark.skipif(not sys.platform.startswith('linux'),
                    reason="Only runs on Linux")
Exemple #26
0
def test_find_program():
    """Test if can find the program."""
    assert find_program('git')
Exemple #27
0
def test_find_program():
    """Test if can find the program."""
    assert find_program('git')
sys.path.append(osp.realpath(osp.dirname(__file__) + "/.."))

from main import create_app

LOCATION = os.path.realpath(
    os.path.join(os.getcwd(), os.path.dirname(__file__)))
LOCATION_SLASH = LOCATION.replace('\\', '/')

LINE_END = '\n'
SHELL = '/usr/bin/env bash'
WINDOWS = os.name == 'nt'

if WINDOWS:
    LINE_END = '\r\n'
    SHELL = find_program('cmd.exe')


class TerminalServerTests(testing.AsyncHTTPTestCase):
    """Main server tests."""
    def get_app(self):
        """Return HTTP/WS server."""
        self.close_future = Future()
        return create_app(SHELL, self.close_future)

    def _mk_connection(self, pid):
        return websocket.websocket_connect(
            'ws://127.0.0.1:{0}/terminals/{1}'.format(self.get_http_port(),
                                                      pid))

    @gen.coroutine