def test(): """Run dependency widget test""" from spyderlib import dependencies # Test sample dependencies.add("IPython", "Enhanced Python interpreter", ">=0.13") dependencies.add("matplotlib", "Interactive data plotting", ">=1.0") dependencies.add("sympy", "Symbolic Mathematics", ">=10.0") dependencies.add("foo", "Non-existent module", ">=1.0") from spyderlib.utils.qthelpers import qapplication app = qapplication() dlg = DependenciesDialog(None) dlg.set_data(dependencies.DEPENDENCIES) dlg.show() sys.exit(dlg.exec_())
# Numpy scalars all inherit from np.generic. # Numpy arrays all inherit from np.ndarray. # If we check that we are certain we have one of these # types then we are less likely to generate an exception below. try: return obj.dtype.type except (AttributeError, RuntimeError): # AttributeError: some NumPy objects have no dtype attribute # RuntimeError: happens with NetCDF objects (Issue 998) return #----Pandas support PANDAS_REQVER = '>=0.13.1' dependencies.add('pandas', _("View and edit DataFrames and Series in the " "Variable Explorer"), required_version=PANDAS_REQVER) if programs.is_module_installed('pandas', PANDAS_REQVER): from pandas import DataFrame, TimeSeries else: DataFrame = TimeSeries = FakeObject # analysis:ignore #----PIL Images support try: from spyderlib import pil_patch Image = pil_patch.Image.Image except ImportError: Image = FakeObject # analysis:ignore #----Misc.
if QTCONSOLE_INSTALLED: from spyderlib.widgets.ipython import IPythonControlWidget else: IPythonControlWidget = None # analysis:ignore # Check if we can import Sphinx to activate rich text mode try: from spyderlib.utils.help.sphinxify import (CSS_PATH, sphinxify, warning, generate_context, usage) sphinx_version = programs.get_module_version('sphinx') except (ImportError, TypeError): sphinxify = sphinx_version = None # analysis:ignore # To add sphinx dependency to the Dependencies dialog SPHINX_REQVER = '>=0.6.6' dependencies.add("sphinx", _("Rich text help"), required_version=SPHINX_REQVER) class ObjectComboBox(EditableComboBox): """ QComboBox handling object names """ # Signals valid = Signal(bool, bool) def __init__(self, parent): EditableComboBox.__init__(self, parent) self.help = parent self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.tips = {True: '', False: ''}
IntrospectionPlugin) try: try: from spyderlib import rope_patch rope_patch.apply() except ImportError: # rope 0.9.2/0.9.3 is not installed pass import rope.base.libutils import rope.contrib.codeassist except ImportError: pass ROPE_REQVER = '>=0.9.2' dependencies.add('rope', _("Editor's code completion, go-to-definition and help"), required_version=ROPE_REQVER) #TODO: The following preferences should be customizable in the future ROPE_PREFS = { 'ignore_syntax_errors': True, 'ignore_bad_imports': True, 'soa_followed_calls': 2, 'extension_modules': [], } class RopePlugin(IntrospectionPlugin): """ Rope based introspection plugin for jedi
import os # Third party imports from qtpy.QtCore import QTimer from qtpy.QtWidgets import QHBoxLayout, QLabel, QWidget # Local imports from spyderlib import dependencies from spyderlib.config.base import _ from spyderlib.config.gui import get_font from spyderlib.py3compat import to_text_string if not os.name == 'nt': PSUTIL_REQVER = '>=0.3' dependencies.add("psutil", _("CPU and memory usage info in the status bar"), required_version=PSUTIL_REQVER) class StatusBarWidget(QWidget): def __init__(self, parent, statusbar): QWidget.__init__(self, parent) self.label_font = font = get_font(option='rich_font') font.setPointSize(self.font().pointSize()) font.setBold(True) layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout)
# Local imports from spyderlib.py3compat import (NUMERIC_TYPES, TEXT_TYPES, to_text_string, is_text_string, is_binary_string, reprlib, PY2, to_binary_string) from spyderlib.utils import programs from spyderlib import dependencies from spyderlib.config.base import _ #============================================================================== # Dependencies #============================================================================== PANDAS_REQVER = '>=0.13.1' dependencies.add('pandas', _("View and edit DataFrames and Series in the " "Variable Explorer"), required_version=PANDAS_REQVER, optional=True) NUMPY_REQVER = '>=1.7' dependencies.add("numpy", _("View and edit two and three dimensional arrays " "in the Variable Explorer"), required_version=NUMPY_REQVER, optional=True) #============================================================================== # FakeObject #============================================================================== class FakeObject(object): """Fake class used in replacement of missing modules""" pass
from spyderlib.widgets.ipython import IPythonControlWidget else: IPythonControlWidget = None # analysis:ignore # Check for Sphinx presence to activate rich text mode if programs.is_module_installed('sphinx', '>=0.6.6'): sphinx_version = programs.get_module_version('sphinx') from spyderlib.utils.inspector.sphinxify import (CSS_PATH, sphinxify, warning, generate_context, usage) else: sphinxify = sphinx_version = None # analysis:ignore # To add sphinx dependency to the Dependencies dialog SPHINX_REQVER = '>=0.6.6' dependencies.add("sphinx", _("Rich text help on the Object Inspector"), required_version=SPHINX_REQVER) class ObjectComboBox(EditableComboBox): """ QComboBox handling object names """ def __init__(self, parent): EditableComboBox.__init__(self, parent) self.object_inspector = parent self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.tips = {True: '', False: ''} def is_valid(self, qstr=None): """Return True if string is valid""" if not self.object_inspector.source_is_console():
import os from spyderlib.qt.QtGui import QWidget, QHBoxLayout, QLabel from spyderlib.qt.QtCore import QTimer # Local import from spyderlib.baseconfig import _ from spyderlib.guiconfig import get_font from spyderlib.py3compat import to_text_string from spyderlib import dependencies if not os.name == 'nt': PSUTIL_REQVER = '>=0.3' dependencies.add("psutil", _("CPU and memory usage info in the status bar"), required_version=PSUTIL_REQVER) class StatusBarWidget(QWidget): def __init__(self, parent, statusbar): QWidget.__init__(self, parent) self.label_font = font = get_font('editor') font.setPointSize(self.font().pointSize()) font.setBold(True) layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) statusbar.addPermanentWidget(self)
from spyderlib.utils.help.sphinxify import (CSS_PATH, sphinxify, warning, generate_context, usage) from spyderlib.utils.qthelpers import (create_toolbutton, add_actions, create_action) from spyderlib.widgets.comboboxes import EditableComboBox from spyderlib.widgets.sourcecode import codeeditor from spyderlib.widgets.findreplace import FindReplace from spyderlib.widgets.browser import FrameWebView from spyderlib.widgets.externalshell.pythonshell import ExtPythonShellWidget from spyderlib.plugins import SpyderPluginWidget, PluginConfigPage from spyderlib.py3compat import to_text_string, get_meth_class_inst # Sphinx dependency dependencies.add("sphinx", _("Show help for objects in the Editor and " "Consoles in a dedicated pane"), required_version='>=0.6.6') #XXX: Hardcoded dependency on optional IPython plugin component # that requires the hack to make this work without IPython if QTCONSOLE_INSTALLED: from spyderlib.widgets.ipython import IPythonControlWidget else: IPythonControlWidget = None # analysis:ignore class ObjectComboBox(EditableComboBox): """ QComboBox handling object names """
IPython configuration variables needed by Spyder """ from spyderlib.utils import programs from spyderlib import dependencies from spyderlib.config.base import _ # Constants QTCONSOLE_REQVER = '>=4.0' ZMQ_REQVER = ">=13.0.0" NBCONVERT_REQVER = ">=4.0" # Dependencies dependencies.add("qtconsole", _("Jupyter Qtconsole integration"), required_version=QTCONSOLE_REQVER) dependencies.add("nbconvert", _("Manipulate Jupyter notebooks on the Editor"), required_version=NBCONVERT_REQVER) # Auxiliary functions def is_qtconsole_installed(): pyzmq_installed = programs.is_module_installed('zmq', version=ZMQ_REQVER) pygments_installed = programs.is_module_installed('pygments') qtconsole_installed = programs.is_module_installed('qtconsole', version=QTCONSOLE_REQVER) if pyzmq_installed and pygments_installed and qtconsole_installed: return True else: return False
""" IPython configuration variables needed by Spyder """ from spyderlib.utils import programs from spyderlib import dependencies from spyderlib.config.base import _ # Constants QTCONSOLE_REQVER = '>=4.0' ZMQ_REQVER = ">=13.0.0" NBCONVERT_REQVER = ">=4.0" # Dependencies dependencies.add("qtconsole", _("Jupyter Qtconsole integration"), required_version=QTCONSOLE_REQVER) dependencies.add("nbconvert", _("Manipulate Jupyter notebooks on the Editor"), required_version=NBCONVERT_REQVER) # Auxiliary functions def is_qtconsole_installed(): pyzmq_installed = programs.is_module_installed('zmq', version=ZMQ_REQVER) pygments_installed = programs.is_module_installed('pygments') qtconsole_installed = programs.is_module_installed( 'qtconsole', version=QTCONSOLE_REQVER) if pyzmq_installed and pygments_installed and qtconsole_installed: return True
# Licensed under the terms of the MIT License # (see spyderlib/__init__.py for details) """ IPython configuration variables needed by Spyder """ from spyderlib.utils import programs from spyderlib import dependencies from spyderlib.config.base import _ IPYTHON_REQVER = '>=3.0' ZMQ_REQVER = '>=13.0.0' dependencies.add("IPython", _("IPython Console integration"), required_version=IPYTHON_REQVER) dependencies.add("zmq", _("IPython Console integration"), required_version=ZMQ_REQVER) def is_qtconsole_installed(): ipython_installed = programs.is_module_installed('IPython.qt', version=IPYTHON_REQVER) pyzmq_installed = programs.is_module_installed('zmq', version=ZMQ_REQVER) pygments_installed = programs.is_module_installed('pygments') if ipython_installed and pyzmq_installed and pygments_installed: return True else: return False IPYTHON_QT_INSTALLED = is_qtconsole_installed()
return process = subprocess.Popen([PYLINT, '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=osp.dirname(PYLINT_PATH), shell=True if os.name == 'nt' else False) lines = to_unicode_from_fs(process.stdout.read()).splitlines() if lines: regex = '({0}*|pylint-script.py) ([0-9\.]*)'.format(PYLINT) match = re.match(regex, lines[0]) if match is not None: return match.groups()[1] PYLINT_REQVER = '>=0.25' PYLINT_VER = get_pylint_version() dependencies.add("pylint", _("Static code analysis"), required_version=PYLINT_REQVER, installed_version=PYLINT_VER) #TODO: display results on 3 columns instead of 1: msg_id, lineno, message class ResultsTree(OneColumnTree): def __init__(self, parent): OneColumnTree.__init__(self, parent) self.filename = None self.results = None self.data = None self.set_title('') def activated(self, item): """Double-click event""" data = self.data.get(id(item)) if data is not None:
results.append((warning.message % warning.message_args, warning.lineno)) except Exception: # Never return None to avoid lock in spyderlib/widgets/editor.py # See Issue 1547 results = [] if DEBUG_EDITOR: traceback.print_exc() # Print exception in internal console return results # Required version: # Why 0.5 (Python2)? Because it's based on _ast (thread-safe) PYFLAKES_REQVER = '>=0.6.0' if PY3 else '>=0.5.0' dependencies.add("pyflakes", _("Real-time code analysis on the Editor"), required_version=PYFLAKES_REQVER) PEP8_REQVER = '>=0.6' dependencies.add("pep8", _("Real-time code style analysis on the Editor"), required_version=PEP8_REQVER) def is_pyflakes_installed(): """Return True if pyflakes required version is installed""" return programs.is_module_installed('pyflakes', PYFLAKES_REQVER) def get_checker_executable(name): """Return checker executable in the form of a list of arguments
from spyderlib.config.base import _, DEBUG, debug_print, get_conf_path from spyderlib.utils import sourcecode from spyderlib.utils.introspection.plugin_client import PluginClient from spyderlib.utils.introspection.utils import CodeInfo PLUGINS = ['rope', 'jedi', 'fallback'] LOG_FILENAME = get_conf_path('introspection.log') DEBUG_EDITOR = DEBUG >= 3 LEAD_TIME_SEC = 0.25 ROPE_REQVER = '>=0.9.4' dependencies.add('rope', _("Editor's code completion, go-to-definition and help"), required_version=ROPE_REQVER) JEDI_REQVER = '>=0.8.1' dependencies.add('jedi', _("Editor's code completion, go-to-definition and help"), required_version=JEDI_REQVER) class PluginManager(QObject): introspection_complete = Signal(object) def __init__(self, executable): super(PluginManager, self).__init__() plugins = OrderedDict()
if PYLINT_PATH is None: return process = subprocess.Popen(['pylint', '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=osp.dirname(PYLINT_PATH), shell=True if os.name == 'nt' else False) lines = to_unicode_from_fs(process.stdout.read()).splitlines() if lines: match = re.match('(pylint|pylint-script.py) ([0-9\.]*)', lines[0]) if match is not None: return match.groups()[1] PYLINT_REQVER = '>=0.25' PYLINT_VER = get_pylint_version() dependencies.add("pylint", _("Static code analysis"), required_version=PYLINT_REQVER, installed_version=PYLINT_VER) #TODO: display results on 3 columns instead of 1: msg_id, lineno, message class ResultsTree(OneColumnTree): def __init__(self, parent): OneColumnTree.__init__(self, parent) self.filename = None self.results = None self.data = None self.set_title('') def activated(self, item): """Double-click event""" data = self.data.get(id(item)) if data is not None:
from spyderlib.baseconfig import _, debug_print from spyderlib.utils import programs from spyderlib.utils.debug import log_last_error, log_dt from spyderlib.utils.dochelpers import getsignaturefromtext from spyderlib.utils.introspection.plugin_manager import ( DEBUG_EDITOR, LOG_FILENAME, IntrospectionPlugin) try: import jedi except ImportError: jedi = None JEDI_REQVER = '>=0.8.1' dependencies.add('jedi', _("(Experimental) Editor's code completion," " go-to-definition and help"), required_version=JEDI_REQVER) class JediPlugin(IntrospectionPlugin): """ Jedi based introspection plugin for jedi Experimental Editor's code completion, go-to-definition and help """ # ---- IntrospectionPlugin API -------------------------------------------- name = 'jedi' def load_plugin(self): """Load the Jedi introspection plugin"""
else: IPythonControlWidget = None # analysis:ignore # Check for Sphinx presence to activate rich text mode if programs.is_module_installed('sphinx', '>=0.6.6'): sphinx_version = programs.get_module_version('sphinx') from spyderlib.utils.inspector.sphinxify import (CSS_PATH, sphinxify, warning, generate_context, usage) else: sphinxify = sphinx_version = None # analysis:ignore # To add sphinx dependency to the Dependencies dialog SPHINX_REQVER = '>=0.6.6' dependencies.add("sphinx", _("Rich text help on the Object Inspector"), required_version=SPHINX_REQVER) class ObjectComboBox(EditableComboBox): """ QComboBox handling object names """ def __init__(self, parent): EditableComboBox.__init__(self, parent) self.object_inspector = parent self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.tips = {True: '', False: ''} def is_valid(self, qstr=None): """Return True if string is valid"""
if 'analysis:ignore' not in \ to_text_string(lines[warning.lineno-1], coding): results.append((warning.message % warning.message_args, warning.lineno)) except Exception: # Never return None to avoid lock in spyderlib/widgets/editor.py # See Issue 1547 results = [] if DEBUG_EDITOR: traceback.print_exc() # Print exception in internal console return results # Required version: # Why 0.5 (Python2)? Because it's based on _ast (thread-safe) PYFLAKES_REQVER = '>=0.6.0' if PY3 else '>=0.5.0' dependencies.add("pyflakes", _("Real-time code analysis on the Editor"), required_version=PYFLAKES_REQVER) PEP8_REQVER = '>=0.6' dependencies.add("pep8", _("Real-time code style analysis on the Editor"), required_version=PEP8_REQVER) def is_pyflakes_installed(): """Return True if pyflakes required version is installed""" return programs.is_module_installed('pyflakes', PYFLAKES_REQVER) def get_checker_executable(name): """Return checker executable in the form of a list of arguments for subprocess.Popen""" if programs.is_program_installed(name):
# Numpy scalars all inherit from np.generic. # Numpy arrays all inherit from np.ndarray. # If we check that we are certain we have one of these # types then we are less likely to generate an exception below. try: return obj.dtype.type except (AttributeError, RuntimeError): # AttributeError: some NumPy objects have no dtype attribute # RuntimeError: happens with NetCDF objects (Issue 998) return #----Pandas support PANDAS_REQVER = '>=0.13.1' dependencies.add('pandas', _("View and edit DataFrames and Series in the " "Variable Explorer"), required_version=PANDAS_REQVER) if programs.is_module_installed('pandas', PANDAS_REQVER): from pandas import DataFrame, TimeSeries else: DataFrame = TimeSeries = FakeObject # analysis:ignore #----PIL Images support try: from spyderlib import pil_patch Image = pil_patch.Image.Image except ImportError: Image = FakeObject # analysis:ignore
from spyderlib.baseconfig import _, debug_print from spyderlib.utils import programs from spyderlib.utils.debug import log_last_error, log_dt from spyderlib.utils.dochelpers import getsignaturefromtext from spyderlib.utils.introspection.plugin_manager import (DEBUG_EDITOR, LOG_FILENAME, IntrospectionPlugin) try: import jedi except ImportError: jedi = None JEDI_REQVER = '>=0.8.1' dependencies.add('jedi', _("(Experimental) Editor's code completion," " go-to-definition and help"), required_version=JEDI_REQVER) class JediPlugin(IntrospectionPlugin): """ Jedi based introspection plugin for jedi Experimental Editor's code completion, go-to-definition and help """ # ---- IntrospectionPlugin API -------------------------------------------- name = 'jedi' def load_plugin(self): """Load the Jedi introspection plugin"""
""" IPython configuration variables needed by Spyder """ from spyderlib.utils import programs from spyderlib import dependencies from spyderlib.config.base import _ # Constants IPYTHON_REQVER = '>=3.0' ZMQ_REQVER = '>=13.0.0' QTCONSOLE_REQVER = '>=4.0' # Dependencies dependencies.add("IPython", _("IPython Console integration"), required_version=IPYTHON_REQVER) dependencies.add("zmq", _("IPython Console integration"), required_version=ZMQ_REQVER) # Jupyter 4.0 requirements ipy4_installed = programs.is_module_installed('IPython', '>=4.0') if ipy4_installed: dependencies.add("qtconsole", _("IPython Console integration"), required_version=QTCONSOLE_REQVER) # Auxiliary functions def is_qtconsole_installed():
from spyderlib.py3compat import get_meth_class_inst, to_text_string from spyderlib.utils import icon_manager as ima from spyderlib.utils import programs from spyderlib.utils.help.sphinxify import (CSS_PATH, generate_context, sphinxify, usage, warning) from spyderlib.utils.qthelpers import (add_actions, create_action, create_toolbutton) from spyderlib.widgets.browser import FrameWebView from spyderlib.widgets.comboboxes import EditableComboBox from spyderlib.widgets.externalshell.pythonshell import ExtPythonShellWidget from spyderlib.widgets.findreplace import FindReplace from spyderlib.widgets.sourcecode import codeeditor # Sphinx dependency dependencies.add("sphinx", _("Show help for objects in the Editor and " "Consoles in a dedicated pane"), required_version='>=0.6.6') #XXX: Hardcoded dependency on optional IPython plugin component # that requires the hack to make this work without IPython if QTCONSOLE_INSTALLED: from spyderlib.widgets.ipython import IPythonControlWidget else: IPythonControlWidget = None # analysis:ignore class ObjectComboBox(EditableComboBox): """ QComboBox handling object names """ # Signals
# Local imports from spyderlib import dependencies from spyderlib.baseconfig import _ from spyderlib.config import CONF from spyderlib.utils.misc import get_error_match, remove_backslashes from spyderlib.utils import programs from spyderlib.utils.qthelpers import get_icon, create_action from spyderlib.widgets.tabs import Tabs from spyderlib.widgets.ipython import IPythonClient from spyderlib.widgets.findreplace import FindReplace from spyderlib.plugins import SpyderPluginWidget, PluginConfigPage from spyderlib.py3compat import to_text_string, u SYMPY_REQVER = '>=0.7.0' dependencies.add("sympy", _("Symbolic mathematics in the IPython Console"), required_version=SYMPY_REQVER) def tunnel_to_kernel(ci, hostname, sshkey=None, password=None, timeout=10): """tunnel connections to a kernel via ssh. remote ports are specified in the connection info ci.""" lports = tunnel.select_random_ports(4) rports = ci['shell_port'], ci['iopub_port'], ci['stdin_port'], ci[ 'hb_port'] remote_ip = ci['ip'] for lp, rp in zip(lports, rports): tunnel.ssh_tunnel(lp, rp, hostname, remote_ip, sshkey, password, timeout) return tuple(lports)
# Local imports from spyderlib import dependencies from spyderlib.baseconfig import _ from spyderlib.config import CONF from spyderlib.utils.misc import get_error_match, remove_backslashes from spyderlib.utils import programs from spyderlib.utils.qthelpers import get_icon, create_action from spyderlib.widgets.tabs import Tabs from spyderlib.widgets.ipython import IPythonClient from spyderlib.widgets.findreplace import FindReplace from spyderlib.plugins import SpyderPluginWidget, PluginConfigPage from spyderlib.py3compat import to_text_string, u SYMPY_REQVER = '>=0.7.0' dependencies.add("sympy", _("Symbolic mathematics in the IPython Console"), required_version=SYMPY_REQVER) def tunnel_to_kernel(ci, hostname, sshkey=None, password=None, timeout=10): """tunnel connections to a kernel via ssh. remote ports are specified in the connection info ci.""" lports = tunnel.select_random_ports(4) rports = ci['shell_port'], ci['iopub_port'], ci['stdin_port'], ci['hb_port'] remote_ip = ci['ip'] for lp, rp in zip(lports, rports): tunnel.ssh_tunnel(lp, rp, hostname, remote_ip, sshkey, password, timeout) return tuple(lports) class IPythonConsoleConfigPage(PluginConfigPage):