def show_tutorial(self): """Show the Spyder tutorial in the Help plugin, opening it if needed""" self.switch_to_plugin() tutorial_path = get_module_source_path('spyder.plugins.help.utils') tutorial = osp.join(tutorial_path, 'tutorial.rst') text = open(tutorial).read() self.show_rich_text(text, collapse=True)
def _load_old_defaults(self, old_version): """Read old defaults""" old_defaults = cp.ConfigParser() if check_version(old_version, '3.0.0', '<='): path = get_module_source_path('spyder') else: path = osp.dirname(self.filename()) path = osp.join(path, 'defaults') old_defaults.read(osp.join(path, 'defaults-'+old_version+'.ini')) return old_defaults
def _load_old_defaults(self, old_version): """Read old defaults""" old_defaults = cp.ConfigParser() if check_version(old_version, '3.0.0', '<='): path = get_module_source_path('spyder') else: path = osp.dirname(self.filename()) path = osp.join(path, 'defaults') old_defaults.read(osp.join(path, 'defaults-' + old_version + '.ini')) return old_defaults
def __init__(self, name, path, defaults=None, load=True, version=None, backup=False, raw_mode=False, remove_obsolete=False, external_plugin=False): """UserConfig class, based on ConfigParser.""" super(UserConfig, self).__init__(name=name, path=path) self._load = load self._version = self._check_version(version) self._backup = backup self._raw = 1 if raw_mode else 0 self._remove_obsolete = remove_obsolete self._external_plugin = external_plugin self._module_source_path = get_module_source_path('spyder') self._defaults_folder = 'defaults' self._backup_folder = 'backups' self._backup_suffix = '.bak' self._defaults_name_prefix = 'defaults' # This attribute is overriding a method from cp.ConfigParser self.defaults = self._check_defaults(defaults) if backup: self._make_backup() if load: # If config file already exists, it overrides Default options previous_fpath = self.get_previous_config_fpath() self._load_from_ini(previous_fpath) old_version = self.get_version(version) self._old_version = old_version # Save new defaults self._save_new_defaults(self.defaults) # Updating defaults only if major/minor version is different if (self._get_minor_version(version) != self._get_minor_version(old_version)): if backup: self._make_backup(version=old_version) self.apply_configuration_patches(old_version=old_version) # Remove deprecated options if major version has changed if remove_obsolete: self._remove_deprecated_options(old_version) # Set new version number self.set_version(version, save=False) if defaults is None: # If no defaults are defined set .ini file settings as default self.set_as_defaults()
def generate_configuration(directory): """ Generates a Sphinx configuration in `directory`. Parameters ---------- directory : str Base directory to use """ # conf.py file for Sphinx conf = osp.join(get_module_source_path('spyder.utils.help'), 'conf.py') # Docstring layout page (in Jinja): layout = osp.join(osp.join(CONFDIR_PATH, 'templates'), 'layout.html') os.makedirs(osp.join(directory, 'templates')) os.makedirs(osp.join(directory, 'static')) shutil.copy(conf, directory) shutil.copy(layout, osp.join(directory, 'templates')) open(osp.join(directory, '__init__.py'), 'w').write('') open(osp.join(directory, 'static', 'empty'), 'w').write('')
def generate_configuration(directory): """ Generates a Sphinx configuration in `directory`. Parameters ---------- directory : str Base directory to use """ # conf.py file for Sphinx conf = osp.join(get_module_source_path('spyder.plugins.help.utils'), 'conf.py') # Docstring layout page (in Jinja): layout = osp.join(osp.join(CONFDIR_PATH, 'templates'), 'layout.html') os.makedirs(osp.join(directory, 'templates')) os.makedirs(osp.join(directory, 'static')) shutil.copy(conf, directory) shutil.copy(layout, osp.join(directory, 'templates')) open(osp.join(directory, '__init__.py'), 'w').write('') open(osp.join(directory, 'static', 'empty'), 'w').write('')
def _default_config(self): # py2exe/cx_Freeze distribution from spyder.config.base import get_module_source_path fname = get_module_source_path('spyder', 'default_config.py') return open(fname, 'rb').read()
from jinja2 import Environment, FileSystemLoader import sphinx from sphinx.application import Sphinx # Local imports from spyder.config.base import (_, get_module_data_path, get_module_source_path) from spyder.utils import encoding #----------------------------------------------------------------------------- # Globals and constants #----------------------------------------------------------------------------- # Note: we do not use __file__ because it won't be working in the stand-alone # version of Spyder (i.e. the py2exe or cx_Freeze build) CONFDIR_PATH = get_module_source_path('spyder.plugins.help.utils') CSS_PATH = osp.join(CONFDIR_PATH, 'static', 'css') DARK_CSS_PATH = osp.join(CONFDIR_PATH, 'static', 'dark_css') JS_PATH = osp.join(CONFDIR_PATH, 'js') # To let Debian packagers redefine the MathJax and JQuery locations so they can # use their own packages for them. See spyder-ide/spyder#1230, comment #7. MATHJAX_PATH = get_module_data_path('spyder', relpath=osp.join('utils', 'help', JS_PATH, 'mathjax'), attr_name='MATHJAXPATH') JQUERY_PATH = get_module_data_path('spyder', relpath=osp.join('utils', 'help', JS_PATH), attr_name='JQUERYPATH')
def __init__(self, parent=None, fname=None, wdir=None, interact=False, debug=False, post_mortem=False, path=[], python_args='', ipykernel=False, arguments='', stand_alone=None, umr_enabled=True, umr_namelist=[], umr_verbose=True, pythonstartup=None, pythonexecutable=None, external_interpreter=False, monitor_enabled=True, mpl_backend=None, ets_backend='qt4', qt_api=None, merge_output_channels=False, colorize_sys_stderr=False, autorefresh_timeout=3000, autorefresh_state=True, light_background=True, menu_actions=None, show_buttons_inside=True, show_elapsed_time=True): assert qt_api in (None, 'pyqt', 'pyside', 'pyqt5') self.namespacebrowser = None # namespace browser widget! self.dialog_manager = DialogManager() self.stand_alone = stand_alone # stand alone settings (None: plugin) self.interact = interact self.is_ipykernel = ipykernel self.pythonstartup = pythonstartup self.pythonexecutable = pythonexecutable self.external_interpreter = external_interpreter self.monitor_enabled = monitor_enabled self.mpl_backend = mpl_backend self.ets_backend = ets_backend self.qt_api = qt_api self.merge_output_channels = merge_output_channels self.colorize_sys_stderr = colorize_sys_stderr self.umr_enabled = umr_enabled self.umr_namelist = umr_namelist self.umr_verbose = umr_verbose self.autorefresh_timeout = autorefresh_timeout self.autorefresh_state = autorefresh_state self.namespacebrowser_button = None self.cwd_button = None self.env_button = None self.syspath_button = None self.terminate_button = None self.notification_thread = None ExternalShellBase.__init__(self, parent=parent, fname=fname, wdir=wdir, history_filename='history.py', light_background=light_background, menu_actions=menu_actions, show_buttons_inside=show_buttons_inside, show_elapsed_time=show_elapsed_time) if self.pythonexecutable is None: self.pythonexecutable = get_python_executable() self.python_args = None if python_args: assert is_text_string(python_args) self.python_args = python_args assert is_text_string(arguments) self.arguments = arguments self.connection_file = None if self.is_ipykernel: self.interact = False # Running our custom startup script for IPython kernels: # (see spyder/widgets/externalshell/start_ipython_kernel.py) self.fname = get_module_source_path('spyder.widgets.externalshell', 'start_ipython_kernel.py') self.shell.set_externalshell(self) self.toggle_globals_explorer(False) self.interact_action.setChecked(self.interact) self.debug_action.setChecked(debug) self.introspection_socket = None self.is_interpreter = fname is None if self.is_interpreter: self.terminate_button.hide() self.post_mortem_action.setChecked(post_mortem and not self.is_interpreter) # Additional python path list self.path = path self.shell.path = path
def sphinxify(docstring, context, buildername='html'): """ Runs Sphinx on a docstring and outputs the processed documentation. Parameters ---------- docstring : str a ReST-formatted docstring context : dict Variables to be passed to the layout template to control how its rendered (through the Sphinx variable *html_context*). buildername: str It can be either `html` or `text`. Returns ------- An Sphinx-processed string, in either HTML or plain text format, depending on the value of `buildername` """ srcdir = mkdtemp() srcdir = encoding.to_unicode_from_fs(srcdir) destdir = osp.join(srcdir, '_build') rst_name = osp.join(srcdir, 'docstring.rst') if buildername == 'html': suffix = '.html' else: suffix = '.txt' output_name = osp.join(destdir, 'docstring' + suffix) # This is needed so users can type \\ on latex eqnarray envs inside raw # docstrings if context['right_sphinx_version'] and context['math_on']: docstring = docstring.replace('\\\\', '\\\\\\\\') # Add a class to several characters on the argspec. This way we can # highlight them using css, in a similar way to what IPython does. # NOTE: Before doing this, we escape common html chars so that they # don't interfere with the rest of html present in the page argspec = escape(context['argspec']) for char in ['=', ',', '(', ')', '*', '**']: argspec = argspec.replace(char, '<span class="argspec-highlight">' + char + '</span>') context['argspec'] = argspec doc_file = codecs.open(rst_name, 'w', encoding='utf-8') doc_file.write(docstring) doc_file.close() temp_confdir = False if temp_confdir: # TODO: This may be inefficient. Find a faster way to do it. confdir = mkdtemp() confdir = encoding.to_unicode_from_fs(confdir) generate_configuration(confdir) else: confdir = osp.join(get_module_source_path('spyder.plugins.help.utils')) confoverrides = {'html_context': context} doctreedir = osp.join(srcdir, 'doctrees') sphinx_app = Sphinx(srcdir, confdir, destdir, doctreedir, buildername, confoverrides, status=None, warning=None, freshenv=True, warningiserror=False, tags=None) try: sphinx_app.build(None, [rst_name]) except SystemMessage: output = _("It was not possible to generate rich text help for this " "object.</br>" "Please see it in plain text.") return warning(output) # TODO: Investigate if this is necessary/important for us if osp.exists(output_name): output = codecs.open(output_name, 'r', encoding='utf-8').read() output = output.replace('<pre>', '<pre class="literal-block">') else: output = _("It was not possible to generate rich text help for this " "object.</br>" "Please see it in plain text.") return warning(output) if temp_confdir: shutil.rmtree(confdir, ignore_errors=True) shutil.rmtree(srcdir, ignore_errors=True) return output
# -*- coding: utf-8 -*- # # Copyright © Spyder Project Contributors # Licensed under the terms of the MIT or BSD Licenses # (See every file for its license) """ spyder.utils.help ================= Configuration files for the Help plugin rich text mode """ import sys from spyder.config.base import get_module_source_path sys.path.insert(0, get_module_source_path(__name__))
def show_tutorial(self): tutorial_path = get_module_source_path('spyder.utils.help') tutorial = osp.join(tutorial_path, 'tutorial.rst') text = open(tutorial).read() self.show_rich_text(text, collapse=True)
def sphinxify(docstring, context, buildername='html'): """ Runs Sphinx on a docstring and outputs the processed documentation. Parameters ---------- docstring : str a ReST-formatted docstring context : dict Variables to be passed to the layout template to control how its rendered (through the Sphinx variable *html_context*). buildername: str It can be either `html` or `text`. Returns ------- An Sphinx-processed string, in either HTML or plain text format, depending on the value of `buildername` """ srcdir = mkdtemp() srcdir = encoding.to_unicode_from_fs(srcdir) destdir = osp.join(srcdir, '_build') rst_name = osp.join(srcdir, 'docstring.rst') if buildername == 'html': suffix = '.html' else: suffix = '.txt' output_name = osp.join(destdir, 'docstring' + suffix) # This is needed so users can type \\ on latex eqnarray envs inside raw # docstrings if context['right_sphinx_version'] and context['math_on']: docstring = docstring.replace('\\\\', '\\\\\\\\') # Add a class to several characters on the argspec. This way we can # highlight them using css, in a similar way to what IPython does. # NOTE: Before doing this, we escape common html chars so that they # don't interfere with the rest of html present in the page argspec = escape(context['argspec']) for char in ['=', ',', '(', ')', '*', '**']: argspec = argspec.replace( char, '<span class="argspec-highlight">' + char + '</span>') context['argspec'] = argspec doc_file = codecs.open(rst_name, 'w', encoding='utf-8') doc_file.write(docstring) doc_file.close() temp_confdir = False if temp_confdir: # TODO: This may be inefficient. Find a faster way to do it. confdir = mkdtemp() confdir = encoding.to_unicode_from_fs(confdir) generate_configuration(confdir) else: confdir = osp.join(get_module_source_path('spyder.utils.help')) confoverrides = {'html_context': context} doctreedir = osp.join(srcdir, 'doctrees') sphinx_app = Sphinx(srcdir, confdir, destdir, doctreedir, buildername, confoverrides, status=None, warning=None, freshenv=True, warningiserror=False, tags=None) try: sphinx_app.build(None, [rst_name]) except SystemMessage: output = _("It was not possible to generate rich text help for this " "object.</br>" "Please see it in plain text.") return warning(output) # TODO: Investigate if this is necessary/important for us if osp.exists(output_name): output = codecs.open(output_name, 'r', encoding='utf-8').read() output = output.replace('<pre>', '<pre class="literal-block">') else: output = _("It was not possible to generate rich text help for this " "object.</br>" "Please see it in plain text.") return warning(output) if temp_confdir: shutil.rmtree(confdir, ignore_errors=True) shutil.rmtree(srcdir, ignore_errors=True) return output
# -*- coding: utf-8 -*- # # Copyright © Spyder Project Contributors # Licensed under the terms of the MIT License # (see spyder/__init__.py for details) """ spyder.utils.external ===================== External libraries needed for Spyder to work. Put here only untouched libraries, else put them in utils. """ import os # Hack to be able to use our own versions of rope and pyflakes, # included in our Windows installers if os.name == 'nt': import os.path as osp import sys from spyder.config.base import get_module_source_path dirname = get_module_source_path(__name__) if osp.isdir(osp.join(dirname, 'rope')): sys.path.insert(0, dirname)
from spyder.utils.qthelpers import (add_actions, create_action, create_toolbutton, DialogManager, MENU_SEPARATOR) from spyder.py3compat import to_text_string from spyder.plugins.ipythonconsole.widgets import ShellWidget from spyder.widgets.mixins import SaveHistoryMixin from spyder.plugins.variableexplorer.widgets.collectionseditor import ( CollectionsEditor) #----------------------------------------------------------------------------- # Templates #----------------------------------------------------------------------------- # Using the same css file from the Help plugin for now. Maybe # later it'll be a good idea to create a new one. PLUGINS_PATH = get_module_source_path('spyder', 'plugins') CSS_PATH = osp.join(PLUGINS_PATH, 'help', 'utils', 'static', 'css') TEMPLATES_PATH = osp.join(PLUGINS_PATH, 'ipythonconsole', 'assets', 'templates') BLANK = open(osp.join(TEMPLATES_PATH, 'blank.html')).read() LOADING = open(osp.join(TEMPLATES_PATH, 'loading.html')).read() KERNEL_ERROR = open(osp.join(TEMPLATES_PATH, 'kernel_error.html')).read() try: time.monotonic # time.monotonic new in 3.3 except AttributeError: time.monotonic = time.time #-----------------------------------------------------------------------------
from jinja2 import Environment, FileSystemLoader import sphinx from sphinx.application import Sphinx # Local imports from spyder.config.base import (_, get_module_data_path, get_module_source_path) from spyder.utils import encoding #----------------------------------------------------------------------------- # Globals and constants #----------------------------------------------------------------------------- # Note: we do not use __file__ because it won't be working in the stand-alone # version of Spyder (i.e. the py2exe or cx_Freeze build) CONFDIR_PATH = get_module_source_path('spyder.utils.help') CSS_PATH = osp.join(CONFDIR_PATH, 'static', 'css') JS_PATH = osp.join(CONFDIR_PATH, 'js') # To let Debian packagers redefine the MathJax and JQuery locations so they can # use their own packages for them. See Issue 1230, comment #7. MATHJAX_PATH = get_module_data_path('spyder', relpath=osp.join('utils', 'help', JS_PATH, 'mathjax'), attr_name='MATHJAXPATH') JQUERY_PATH = get_module_data_path('spyder', relpath=osp.join('utils', 'help', JS_PATH), attr_name='JQUERYPATH') #-----------------------------------------------------------------------------
def __init__(self, parent=None, fname=None, wdir=None, interact=False, debug=False, post_mortem=False, path=[], python_args='', ipykernel=False, arguments='', stand_alone=None, umr_enabled=True, umr_namelist=[], umr_verbose=True, pythonstartup=None, pythonexecutable=None, external_interpreter=False, monitor_enabled=True, mpl_backend=None, ets_backend='qt4', qt_api=None, merge_output_channels=False, colorize_sys_stderr=False, autorefresh_timeout=3000, autorefresh_state=True, light_background=True, menu_actions=None, show_buttons_inside=True, show_elapsed_time=True): assert qt_api in (None, 'pyqt', 'pyside', 'pyqt5') self.namespacebrowser = None # namespace browser widget! self.dialog_manager = DialogManager() self.stand_alone = stand_alone # stand alone settings (None: plugin) self.interact = interact self.is_ipykernel = ipykernel self.pythonstartup = pythonstartup self.pythonexecutable = pythonexecutable self.external_interpreter = external_interpreter self.monitor_enabled = monitor_enabled self.mpl_backend = mpl_backend self.ets_backend = ets_backend self.qt_api = qt_api self.merge_output_channels = merge_output_channels self.colorize_sys_stderr = colorize_sys_stderr self.umr_enabled = umr_enabled self.umr_namelist = umr_namelist self.umr_verbose = umr_verbose self.autorefresh_timeout = autorefresh_timeout self.autorefresh_state = autorefresh_state self.namespacebrowser_button = None self.cwd_button = None self.env_button = None self.syspath_button = None self.terminate_button = None self.notification_thread = None ExternalShellBase.__init__(self, parent=parent, fname=fname, wdir=wdir, history_filename='history.py', light_background=light_background, menu_actions=menu_actions, show_buttons_inside=show_buttons_inside, show_elapsed_time=show_elapsed_time) if self.pythonexecutable is None: self.pythonexecutable = get_python_executable() self.python_args = None if python_args: assert is_text_string(python_args) self.python_args = python_args assert is_text_string(arguments) self.arguments = arguments self.connection_file = None if self.is_ipykernel: self.interact = False # Running our custom startup script for IPython kernels: # (see spyder/widgets/externalshell/start_ipython_kernel.py) self.fname = get_module_source_path( 'spyder.widgets.externalshell', 'start_ipython_kernel.py') self.shell.set_externalshell(self) self.toggle_globals_explorer(False) self.interact_action.setChecked(self.interact) self.debug_action.setChecked(debug) self.introspection_socket = None self.is_interpreter = fname is None if self.is_interpreter: self.terminate_button.hide() self.post_mortem_action.setChecked(post_mortem and not self.is_interpreter) # Additional python path list self.path = path self.shell.path = path
# Spyder imports from spyder.config.base import _, get_image_path, get_module_source_path from spyder.py3compat import is_text_string from spyder.utils.qthelpers import add_actions from spyder.utils import sourcecode from spyder.widgets.findreplace import FindReplace # Local imports from ..widgets.dom import DOMWidget # ----------------------------------------------------------------------------- # Templates # ----------------------------------------------------------------------------- # Using the same css file from the Help plugin for now. Maybe # later it'll be a good idea to create a new one. UTILS_PATH = get_module_source_path('spyder', 'utils') CSS_PATH = osp.join(UTILS_PATH, 'help', 'static', 'css') TEMPLATES_PATH = osp.join(UTILS_PATH, 'ipython', 'templates') BLANK = open(osp.join(TEMPLATES_PATH, 'blank.html')).read() LOADING = open(osp.join(TEMPLATES_PATH, 'loading.html')).read() KERNEL_ERROR = open(osp.join(TEMPLATES_PATH, 'kernel_error.html')).read() # ----------------------------------------------------------------------------- # Widgets # ----------------------------------------------------------------------------- class NotebookWidget(DOMWidget): """WebView widget for notebooks.""" def contextMenuEvent(self, event): """Don't show some actions which have no meaning for the notebook."""
get_module_source_path) from spyder.config.gui import get_font, get_shortcut from spyder.utils import icon_manager as ima from spyder.utils.qthelpers import (add_actions, create_action, create_toolbutton) from spyder.widgets.browser import WebView from spyder.widgets.mixins import SaveHistoryMixin from spyder.widgets.ipythonconsole import ShellWidget #----------------------------------------------------------------------------- # Templates #----------------------------------------------------------------------------- # Using the same css file from the Help plugin for now. Maybe # later it'll be a good idea to create a new one. UTILS_PATH = get_module_source_path('spyder', 'utils') CSS_PATH = osp.join(UTILS_PATH, 'help', 'static', 'css') TEMPLATES_PATH = osp.join(UTILS_PATH, 'ipython', 'templates') BLANK = open(osp.join(TEMPLATES_PATH, 'blank.html')).read() LOADING = open(osp.join(TEMPLATES_PATH, 'loading.html')).read() KERNEL_ERROR = open(osp.join(TEMPLATES_PATH, 'kernel_error.html')).read() #----------------------------------------------------------------------------- # Auxiliary functions #----------------------------------------------------------------------------- def background(f): """ Call a function in a simple thread, to prevent blocking
class SpyderKernelSpec(KernelSpec): """Kernel spec for Spyder kernels""" default_interpreter = CONF.get('main_interpreter', 'default') spy_path = get_module_source_path('spyder') def __init__(self, **kwargs): super(SpyderKernelSpec, self).__init__(**kwargs) self.display_name = 'Python 2 (Spyder)' if PY2 else 'Python 3 (Spyder)' self.language = 'python2' if PY2 else 'python3' self.resource_dir = '' @property def argv(self): """Command to start kernels""" # Python interpreter used to start kernels if self.default_interpreter: pyexec = get_python_executable() else: # Avoid IPython adding the virtualenv on which Spyder is running # to the kernel sys.path os.environ.pop('VIRTUAL_ENV', None) pyexec = CONF.get('main_interpreter', 'executable') # Fixes Issue #3427 if os.name == 'nt': dir_pyexec = osp.dirname(pyexec) pyexec_w = osp.join(dir_pyexec, 'pythonw.exe') if osp.isfile(pyexec_w): pyexec = pyexec_w # Command used to start kernels utils_path = osp.join(self.spy_path, 'utils', 'ipython') kernel_cmd = [ pyexec, osp.join("%s" % utils_path, "start_kernel.py"), '-f', '{connection_file}' ] return kernel_cmd @property def env(self): """Env vars for kernels""" # Paths that we need to add to PYTHONPATH: # 1. sc_path: Path to our sitecustomize # 2. spy_path: Path to our main module, so we can use our config # system to configure kernels started by exterrnal interpreters # 3. spy_pythonpath: Paths saved by our users with our PYTHONPATH # manager sc_path = osp.join(self.spy_path, 'utils', 'site') spy_pythonpath = CONF.get('main', 'spyder_pythonpath', default=[]) default_interpreter = CONF.get('main_interpreter', 'default') if default_interpreter: pathlist = [sc_path] + spy_pythonpath else: pathlist = [sc_path, self.spy_path] + spy_pythonpath pypath = add_pathlist_to_PYTHONPATH([], pathlist, ipyconsole=True, drop_env=(not default_interpreter)) # 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 = { 'EXTERNAL_INTERPRETER': not default_interpreter, 'UMR_ENABLED': CONF.get('main_interpreter', 'umr/enabled'), 'UMR_VERBOSE': CONF.get('main_interpreter', 'umr/verbose'), 'UMR_NAMELIST': ','.join(umr_namelist) } # 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
def create_process(self): self.shell.clear() self.process = QProcess(self) if self.merge_output_channels: self.process.setProcessChannelMode(QProcess.MergedChannels) else: self.process.setProcessChannelMode(QProcess.SeparateChannels) self.shell.wait_for_ready_read.connect( lambda: self.process.waitForReadyRead(250)) # Working directory if self.wdir is not None: self.process.setWorkingDirectory(self.wdir) #-------------------------Python specific------------------------------ # Python arguments p_args = ['-u'] if DEBUG >= 3: p_args += ['-v'] p_args += get_python_args(self.fname, self.python_args, self.interact_action.isChecked(), self.debug_action.isChecked(), self.arguments) env = [ to_text_string(_path) for _path in self.process.systemEnvironment() ] if self.pythonstartup: env.append('PYTHONSTARTUP=%s' % self.pythonstartup) #-------------------------Python specific------------------------------- # Post mortem debugging if self.post_mortem_action.isChecked(): env.append('SPYDER_EXCEPTHOOK=True') # Set standard input/output encoding for Python consoles # See http://stackoverflow.com/q/26312400/438386, specifically # the comments of Martijn Pieters env.append('PYTHONIOENCODING=UTF-8') # Monitor if self.monitor_enabled: env.append('SPYDER_SHELL_ID=%s' % id(self)) env.append('SPYDER_AR_TIMEOUT=%d' % self.autorefresh_timeout) env.append('SPYDER_AR_STATE=%r' % self.autorefresh_state) from spyder.widgets.externalshell import introspection introspection_server = introspection.start_introspection_server() introspection_server.register(self) notification_server = introspection.start_notification_server() self.notification_thread = notification_server.register(self) self.notification_thread.sig_pdb.connect( lambda fname, lineno: self.sig_pdb.emit(fname, lineno)) self.notification_thread.open_file.connect( lambda fname, lineno: self.open_file.emit(fname, lineno)) if self.namespacebrowser is not None: self.configure_namespacebrowser() env.append('SPYDER_I_PORT=%d' % introspection_server.port) env.append('SPYDER_N_PORT=%d' % notification_server.port) # External modules options env.append('ETS_TOOLKIT=%s' % self.ets_backend) if self.mpl_backend is not None: backends = {0: 'Automatic', 1: 'None', 2: 'TkAgg'} env.append('SPY_MPL_BACKEND=%s' % backends[self.mpl_backend]) if self.qt_api: env.append('QT_API=%s' % self.qt_api) env.append('COLORIZE_SYS_STDERR=%s' % self.colorize_sys_stderr) # # Socket-based alternative (see input hook in sitecustomize.py): # if self.install_qt_inputhook: # from PyQt4.QtNetwork import QLocalServer # self.local_server = QLocalServer() # self.local_server.listen(str(id(self))) # User Module Deleter if self.is_interpreter: env.append('UMR_ENABLED=%r' % self.umr_enabled) env.append('UMR_NAMELIST=%s' % ','.join(self.umr_namelist)) env.append('UMR_VERBOSE=%r' % self.umr_verbose) env.append('MATPLOTLIB_ION=True') else: if self.interact: env.append('MATPLOTLIB_ION=True') else: env.append('MATPLOTLIB_ION=False') # External interpreter env.append('EXTERNAL_INTERPRETER=%r' % self.external_interpreter) # Add sitecustomize path to path list pathlist = [] spy_path = get_module_source_path('spyder') sc_path = osp.join(spy_path, 'utils', 'site') pathlist.append(sc_path) # Adding Spyder path pathlist += self.path # Adding path list to PYTHONPATH environment variable add_pathlist_to_PYTHONPATH(env, pathlist) #-------------------------Python specific------------------------------ self.process.readyReadStandardOutput.connect(self.write_output) self.process.readyReadStandardError.connect(self.write_error) self.process.finished.connect( lambda ec, es=QProcess.ExitStatus: self.finished(ec, es)) self.sig_finished.connect(self.dialog_manager.close_all) self.terminate_button.clicked.connect(self.process.terminate) self.kill_button.clicked.connect(self.process.kill) #-------------------------Python specific------------------------------ # Fixes for our Mac app: # 1. PYTHONPATH and PYTHONHOME are set while bootstrapping the app, # but their values are messing sys.path for external interpreters # (e.g. EPD) so we need to remove them from the environment. # 2. Set PYTHONPATH again but without grabbing entries defined in the # environment (Fixes Issue 1321) # 3. Remove PYTHONOPTIMIZE from env so that we can have assert # statements working with our interpreters (See Issue 1281) if running_in_mac_app(): if MAC_APP_NAME not in self.pythonexecutable: env = [p for p in env if not (p.startswith('PYTHONPATH') or \ p.startswith('PYTHONHOME'))] # 1. add_pathlist_to_PYTHONPATH(env, pathlist, drop_env=True) # 2. env = [p for p in env if not p.startswith('PYTHONOPTIMIZE')] # 3. processEnvironment = QProcessEnvironment() for envItem in env: envName, separator, envValue = envItem.partition('=') processEnvironment.insert(envName, envValue) self.process.setProcessEnvironment(processEnvironment) self.process.start(self.pythonexecutable, p_args) #-------------------------Python specific------------------------------ running = self.process.waitForStarted(3000) self.set_running_state(running) if not running: QMessageBox.critical(self, _("Error"), _("A Python console failed to start!")) else: self.shell.setFocus() self.started.emit() return self.process
import sphinx from sphinx.application import Sphinx # Local imports from spyder.config.base import (_, get_module_data_path, get_module_source_path) from spyder.utils import encoding #----------------------------------------------------------------------------- # Globals and constants #----------------------------------------------------------------------------- # Note: we do not use __file__ because it won't be working in the stand-alone # version of Spyder (i.e. the py2exe or cx_Freeze build) CONFDIR_PATH = get_module_source_path('spyder.plugins.help.utils') CSS_PATH = osp.join(CONFDIR_PATH, 'static', 'css') DARK_CSS_PATH = osp.join(CONFDIR_PATH, 'static', 'dark_css') JS_PATH = osp.join(CONFDIR_PATH, 'js') # To let Debian packagers redefine the MathJax and JQuery locations so they can # use their own packages for them. See Issue 1230, comment #7. MATHJAX_PATH = get_module_data_path('spyder', relpath=osp.join('utils', 'help', JS_PATH, 'mathjax'), attr_name='MATHJAXPATH') JQUERY_PATH = get_module_data_path('spyder', relpath=osp.join('utils', 'help', JS_PATH), attr_name='JQUERYPATH')
class SpyderKernelSpec(KernelSpec): """Kernel spec for Spyder kernels""" spy_path = get_module_source_path('spyder') def __init__(self, is_cython=False, is_pylab=False, is_sympy=False, **kwargs): super(SpyderKernelSpec, self).__init__(**kwargs) self.is_cython = is_cython self.is_pylab = is_pylab self.is_sympy = is_sympy self.display_name = 'Python 2 (Spyder)' if PY2 else 'Python 3 (Spyder)' self.language = 'python2' if PY2 else 'python3' self.resource_dir = '' @property def argv(self): """Command to start kernels""" # Python interpreter used to start kernels if CONF.get('main_interpreter', 'default'): pyexec = get_python_executable() else: # Avoid IPython adding the virtualenv on which Spyder is running # to the kernel sys.path os.environ.pop('VIRTUAL_ENV', None) pyexec = CONF.get('main_interpreter', 'executable') if not is_python_interpreter(pyexec): pyexec = get_python_executable() CONF.set('main_interpreter', 'executable', '') CONF.set('main_interpreter', 'default', True) CONF.set('main_interpreter', 'custom', False) # Fixes Issue #3427 if os.name == 'nt': dir_pyexec = osp.dirname(pyexec) pyexec_w = osp.join(dir_pyexec, 'pythonw.exe') if osp.isfile(pyexec_w): pyexec = pyexec_w # Command used to start kernels utils_path = osp.join(self.spy_path, 'utils', 'ipython') kernel_cmd = [ pyexec, osp.join("%s" % utils_path, "start_kernel.py"), '-f', '{connection_file}' ] return kernel_cmd @property def env(self): """Env vars for kernels""" # Paths that we need to add to PYTHONPATH: # 1. sc_path: Path to our sitecustomize # 2. spy_path: Path to our main module, so we can use our config # system to configure kernels started by exterrnal interpreters # 3. spy_pythonpath: Paths saved by our users with our PYTHONPATH # manager sc_path = osp.join(self.spy_path, 'utils', 'site') spy_pythonpath = CONF.get('main', 'spyder_pythonpath', default=[]) default_interpreter = CONF.get('main_interpreter', 'default') if default_interpreter: pathlist = [sc_path] + spy_pythonpath else: pathlist = [sc_path, self.spy_path] + spy_pythonpath pypath = add_pathlist_to_PYTHONPATH([], pathlist, ipyconsole=True, drop_env=(not default_interpreter)) # 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 } 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
# Local imports from ..widgets.dom import DOMWidget # ----------------------------------------------------------------------------- # Templates # ----------------------------------------------------------------------------- # Using the same css file from the Help plugin for now. Maybe # later it'll be a good idea to create a new one. try: FileNotFoundError except NameError: FileNotFoundError = IOError # Python 2 try: # Spyder 4 PLUGINS_PATH = get_module_source_path('spyder', 'plugins') CSS_PATH = osp.join(PLUGINS_PATH, 'help', 'utils', 'static', 'css') TEMPLATES_PATH = osp.join(PLUGINS_PATH, 'ipythonconsole', 'assets', 'templates') open(osp.join(TEMPLATES_PATH, 'blank.html')) except FileNotFoundError: # Spyder 3 UTILS_PATH = get_module_source_path('spyder', 'utils') CSS_PATH = osp.join(UTILS_PATH, 'help', 'static', 'css') TEMPLATES_PATH = osp.join(UTILS_PATH, 'ipython', 'templates') BLANK = open(osp.join(TEMPLATES_PATH, 'blank.html')).read() LOADING = open(osp.join(TEMPLATES_PATH, 'loading.html')).read() KERNEL_ERROR = open(osp.join(TEMPLATES_PATH, 'kernel_error.html')).read()
def create_process(self): self.shell.clear() self.process = QProcess(self) if self.merge_output_channels: self.process.setProcessChannelMode(QProcess.MergedChannels) else: self.process.setProcessChannelMode(QProcess.SeparateChannels) self.shell.wait_for_ready_read.connect( lambda: self.process.waitForReadyRead(250)) # Working directory if self.wdir is not None: self.process.setWorkingDirectory(self.wdir) #-------------------------Python specific------------------------------ # Python arguments p_args = ['-u'] if DEBUG >= 3: p_args += ['-v'] p_args += get_python_args(self.fname, self.python_args, self.interact_action.isChecked(), self.debug_action.isChecked(), self.arguments) env = [to_text_string(_path) for _path in self.process.systemEnvironment()] if self.pythonstartup: env.append('PYTHONSTARTUP=%s' % self.pythonstartup) #-------------------------Python specific------------------------------- # Post mortem debugging if self.post_mortem_action.isChecked(): env.append('SPYDER_EXCEPTHOOK=True') # Set standard input/output encoding for Python consoles # See http://stackoverflow.com/q/26312400/438386, specifically # the comments of Martijn Pieters env.append('PYTHONIOENCODING=UTF-8') # Monitor if self.monitor_enabled: env.append('SPYDER_SHELL_ID=%s' % id(self)) env.append('SPYDER_AR_TIMEOUT=%d' % self.autorefresh_timeout) env.append('SPYDER_AR_STATE=%r' % self.autorefresh_state) from spyder.widgets.externalshell import introspection introspection_server = introspection.start_introspection_server() introspection_server.register(self) notification_server = introspection.start_notification_server() self.notification_thread = notification_server.register(self) self.notification_thread.sig_pdb.connect( lambda fname, lineno: self.sig_pdb.emit(fname, lineno)) self.notification_thread.open_file.connect( lambda fname, lineno: self.open_file.emit(fname, lineno)) if self.namespacebrowser is not None: self.configure_namespacebrowser() env.append('SPYDER_I_PORT=%d' % introspection_server.port) env.append('SPYDER_N_PORT=%d' % notification_server.port) # External modules options env.append('ETS_TOOLKIT=%s' % self.ets_backend) if self.mpl_backend is not None: backends = {0: 'Automatic', 1: 'None', 2: 'TkAgg'} env.append('SPY_MPL_BACKEND=%s' % backends[self.mpl_backend]) if self.qt_api: env.append('QT_API=%s' % self.qt_api) env.append('COLORIZE_SYS_STDERR=%s' % self.colorize_sys_stderr) # # Socket-based alternative (see input hook in sitecustomize.py): # if self.install_qt_inputhook: # from PyQt4.QtNetwork import QLocalServer # self.local_server = QLocalServer() # self.local_server.listen(str(id(self))) # User Module Deleter if self.is_interpreter: env.append('UMR_ENABLED=%r' % self.umr_enabled) env.append('UMR_NAMELIST=%s' % ','.join(self.umr_namelist)) env.append('UMR_VERBOSE=%r' % self.umr_verbose) env.append('MATPLOTLIB_ION=True') else: if self.interact: env.append('MATPLOTLIB_ION=True') else: env.append('MATPLOTLIB_ION=False') # External interpreter env.append('EXTERNAL_INTERPRETER=%r' % self.external_interpreter) # Add sitecustomize path to path list pathlist = [] spy_path = get_module_source_path('spyder') sc_path = osp.join(spy_path, 'utils', 'site') pathlist.append(sc_path) # Adding Spyder path pathlist += self.path # Adding path list to PYTHONPATH environment variable add_pathlist_to_PYTHONPATH(env, pathlist) #-------------------------Python specific------------------------------ self.process.readyReadStandardOutput.connect(self.write_output) self.process.readyReadStandardError.connect(self.write_error) self.process.finished.connect(lambda ec, es=QProcess.ExitStatus: self.finished(ec, es)) self.sig_finished.connect(self.dialog_manager.close_all) self.terminate_button.clicked.connect(self.process.terminate) self.kill_button.clicked.connect(self.process.kill) #-------------------------Python specific------------------------------ # Fixes for our Mac app: # 1. PYTHONPATH and PYTHONHOME are set while bootstrapping the app, # but their values are messing sys.path for external interpreters # (e.g. EPD) so we need to remove them from the environment. # 2. Set PYTHONPATH again but without grabbing entries defined in the # environment (Fixes Issue 1321) # 3. Remove PYTHONOPTIMIZE from env so that we can have assert # statements working with our interpreters (See Issue 1281) if running_in_mac_app(): if MAC_APP_NAME not in self.pythonexecutable: env = [p for p in env if not (p.startswith('PYTHONPATH') or \ p.startswith('PYTHONHOME'))] # 1. add_pathlist_to_PYTHONPATH(env, pathlist, drop_env=True) # 2. env = [p for p in env if not p.startswith('PYTHONOPTIMIZE')] # 3. processEnvironment = QProcessEnvironment() for envItem in env: envName, separator, envValue = envItem.partition('=') processEnvironment.insert(envName, envValue) self.process.setProcessEnvironment(processEnvironment) self.process.start(self.pythonexecutable, p_args) #-------------------------Python specific------------------------------ running = self.process.waitForStarted(3000) self.set_running_state(running) if not running: QMessageBox.critical(self, _("Error"), _("A Python console failed to start!")) else: self.shell.setFocus() self.started.emit() return self.process