diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index c8464a32203..9d259f8a864 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,12 +1,24 @@ - + +### Issue Report Checklist + +* [ ] Searched the [issues page](https://github.com/spyder-ide/spyder/issues?q=is%3Aissue) for similar reports +* [ ] Read the relevant sections of the [Spyder Troubleshooting Guide](https://github.com/spyder-ide/spyder/wiki/Troubleshooting-Guide-and-FAQ) and followed its advice +* [ ] Reproduced the issue after updating with ``conda update spyder`` (or ``pip``, if not using Anaconda) +* [ ] Could not reproduce inside ``jupyter qtconsole`` (if console-related) +* [ ] Tried basic troubleshooting (if a bug/error) + * [ ] Restarted Spyder + * [ ] Reset preferences with ``spyder --reset`` + * [ ] Reinstalled the latest version of [Anaconda](https://www.anaconda.com/download/) + * [ ] Tried the other applicable steps from the Troubleshooting Guide +* [ ] Completed the **Problem Description**, **Steps to Reproduce** and **Version** sections below -If you don't find anything, please provide a detailed step-by-step description (in English) of the problem and what led up to it below. Issue reports without a clear way to reproduce them will be closed. Thanks! ---> ## Problem Description -### What steps will reproduce the problem? +### What steps reproduce the problem? 1. 2. @@ -25,13 +37,16 @@ PASTE TRACEBACK HERE ``` -## Package Versions +## Versions + -* Spyder: -* Python: -* Qt: -* PyQt: -* Operating System: +* Spyder version: +* Python version: +* Qt version: +* PyQt version: +* Operating System name/version: ### Dependencies + -1. You haven't touched any file in the `spyder/defaults` directory. - - There is *absolutely* no need to touch those files. - - If you want to add new configuration options, please go to - `spyder/config/main.py`. -2. You haven't eliminated unnecessary blank lines or spaces during your work. - That makes our reviewing work harder and it could introduce unnecessary - conflicts with other pull requests. -3. You haven't added new icons to Spyder. Please leave decisions about what - icons to use to us :) +### Pull Request Checklist ----- +* [ ] Read and followed this repo's [Contributing Guidelines](https://github.com/spyder-ide/spyder/blob/master/CONTRIBUTING.md) +* [ ] Based your PR on the latest version of the correct branch (master or 3.x) +* [ ] Followed [PEP8](https://www.python.org/dev/peps/pep-0008/) for code style +* [ ] Ensured your pull request hasn't eliminated unrelated blank lines/spaces, + modified the ``spyder/defaults`` directory, or added new icons/assets +* [ ] Wrote at least one-line docstrings for any new functions +* [ ] Added at least one unit test covering the changes, if at all possible +* [ ] Described your changes and the motivation for them below +* [ ] Noted what issue(s) this pull request resolves, creating one if needed +* [ ] Included a screenshot, if this PR makes any visible changes to the UI -*Note*: You can safely remove this text before submitting your work. + +## Description of Changes + + + + + + +### Issue(s) Resolved + + + + + +Fixes # + + + diff --git a/.travis.yml b/.travis.yml index 9b3e64065ae..fb021c50383 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,20 +7,16 @@ sudo: false matrix: include: - python: "2.7" - env: USE_PYQT=pyqt4 - os: linux - - python: "2.7" - env: USE_PYQT=pyqt5 + env: USE_PYQT=pyqt5 USE_CONDA=yes os: linux - python: "3.5" - env: USE_PYQT=pyqt4 + env: USE_PYQT=pyqt5 USE_CONDA=yes os: linux - # This slot runs our tests only with pip packages - - python: "3.5" - env: USE_PYQT=pyqt5 + - python: "3.6" + env: USE_PYQT=pyqt5 USE_CONDA=yes os: linux - python: "3.6" - env: USE_PYQT=pyqt5 + env: USE_PYQT=pyqt5 USE_CONDA=no os: linux before_install: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bffa2cda9f5..b323bd87290 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -89,9 +89,8 @@ the directory where your git clone is stored and run: $ pip install -r requirements/requirements.txt ``` -If you are using `pip` and Python 2, you also need to install a Qt binding -package (PyQt4 or PyQt5, with the latter strongly recommended). -This can be achieved by running: +If you are using `pip` and Python 3, you also need to install a Qt binding +package (PyQt5). This can be achieved by running: ```bash $ pip install pyqt5 @@ -184,6 +183,8 @@ To run the Spyder test suite, please use (from the `spyder` root directory): ## More information +[Main Website](https://www.spyder-ide.org/) + [Download Spyder (with Anaconda)](https://www.anaconda.com/download/) [Online Documentation](https://docs.spyder-ide.org/) @@ -191,7 +192,7 @@ To run the Spyder test suite, please use (from the `spyder` root directory): [Spyder Github](https://github.com/spyder-ide/spyder) [Troubleshooting Guide and FAQ]( -https://github.com/spyder-ide/spyder/wiki/Troubleshooting-Guide-and-FAQ') +https://github.com/spyder-ide/spyder/wiki/Troubleshooting-Guide-and-FAQ) [Development Wiki](https://github.com/spyder-ide/spyder/wiki/Dev:-Index) @@ -199,4 +200,8 @@ https://github.com/spyder-ide/spyder/wiki/Troubleshooting-Guide-and-FAQ') [Google Group](http://groups.google.com/group/spyderlib) +[@Spyder_IDE on Twitter](https://twitter.com/spyder_ide) + +[@SpyderIDE on Facebook](https://www.facebook.com/SpyderIDE/) + [Support Spyder on OpenCollective](https://opencollective.com/spyder/) diff --git a/MANIFEST.in b/MANIFEST.in index cb23eff7f67..697471b01c4 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -2,7 +2,6 @@ recursive-include spyder *.pot *.po *.svg *.png *.css *.qss *.c *.cpp *.html *.j recursive-include spyder_breakpoints *.pot *.po *.svg *.png recursive-include spyder_profiler *.pot *.po *.svg *.png recursive-include spyder_pylint *.pot *.po *.svg *.png -recursive-include doc *.py *.rst *.png *.ico *. include spyder/fonts/spyder.ttf include spyder/fonts/spyder-charmap.json include scripts/* diff --git a/README.md b/README.md index f68d74f97e2..c28aca4d6a4 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ [![license](https://img.shields.io/pypi/l/spyder.svg)](./LICENSE) [![pypi version](https://img.shields.io/pypi/v/spyder.svg)](https://pypi.python.org/pypi/spyder) +[![conda version](https://img.shields.io/conda/vn/conda-forge/spyder.svg)](https://www.anaconda.com/download/) +[![download count](https://img.shields.io/conda/dn/conda-forge/spyder.svg)](https://www.anaconda.com/download/) [![Join the chat at https://gitter.im/spyder-ide/public](https://badges.gitter.im/spyder-ide/spyder.svg)](https://gitter.im/spyder-ide/public) [![OpenCollective Backers](https://opencollective.com/spyder/backers/badge.svg?color=blue)](#backers) [![OpenCollective Sponsors](https://opencollective.com/spyder/sponsors/badge.svg?color=blue)](#sponsors) @@ -15,6 +17,7 @@ [![CircleCI](https://circleci.com/gh/spyder-ide/spyder.svg?style=shield)](https://circleci.com/gh/spyder-ide/spyder) [![Coverage Status](https://coveralls.io/repos/github/spyder-ide/spyder/badge.svg?branch=master)](https://coveralls.io/github/spyder-ide/spyder?branch=master) [![codecov](https://codecov.io/gh/spyder-ide/spyder/branch/master/graph/badge.svg)](https://codecov.io/gh/spyder-ide/spyder) +[![PyPI status](https://img.shields.io/pypi/status/spyder.svg)](https://github.com/spyder-ide/spyder) ![Screenshot of Spyder's main window](./img_src/screenshot.png) @@ -22,8 +25,24 @@ ## Overview -Spyder is a Python development environment with many features for research, -data analysis, and scientific package creation: +Spyder is a powerful scientific environment written in Python, for Python, +and designed by and for scientists, engineers and data analysts. It offers a +unique combination of the advanced editing, analysis, debugging, and profiling +functionality of a comprehensive development tool with the data exploration, +interactive execution, deep inspection, and beautiful visualization +capabilities of a scientific package. + +Beyond its many built-in features, its abilities can be extended even further +via its plugin system and API. Furthermore, Spyder can also be used as a PyQt5 +extension library, allowing you to build upon its functionality and embed +its components, such as the interactive console, in your own software. + +For more general information about Spyder and to stay up to date on the +latest Spyder news and information, please check out [our new website]( +https://www.spyder-ide.org/). + + +## Core components * **Editor** @@ -34,14 +53,15 @@ data analysis, and scientific package creation: * **Interactive console** - Multiple IPython consoles with workspace and debugging support to - instantly evaluate the code written in the Editor. - Spyder consoles also come with full Matplotlib integration. + Harness the power of as many IPython consoles as you like with full + workspace and debugging support, all within the flexibility of a full + GUI interface. Instantly run your code by line, cell, or file, + and render plots right inline with the output or in interactive windows. * **Documentation viewer** Render documentation in real-time with Sphinx for any class or function, - whether external or user-created from either the Editor or a Console. + whether external or user-created, from either the Editor or a Console. * **Variable explorer** @@ -53,22 +73,9 @@ data analysis, and scientific package creation: * **Development tools** Examine your code with the static analyzer, trace its execution with the - interactive debugger, measure its performance with the profiler, - and keep things organized with project support and a builtin file explorer. - -* **Find in files** - - Search for queries across multiple files in your project, - with full support for regular expressions. - -* **History log** - - Browse an automatically de-duplicated listing of every command you run - on any Spyder console. - -Spyder may also be used as a PyQt5 extension library (module `spyder`). -For example, the Python interactive shell widget used in -Spyder may be embedded in your own PyQt5 application. + interactive debugger, and unleash its performance with the profiler. + Keep things organized with project support and a builtin file explorer, and + use find in files to search across entire projects with full regex support. ## Documentation @@ -163,7 +170,7 @@ a Python version greater than 2.7 or 3.4 (Python <=3.3 is no longer supported). ### Runtime dependencies * **Python** 2.7 or 3.4+: The core language Spyder is written in and for. -* **PyQt5** 5.2+: Python bindings for Qt, used for Spyder's GUI. +* **PyQt5** 5.5+: Python bindings for Qt, used for Spyder's GUI. * **qtconsole** 4.2.0+: Enhanced Python interpreter. * **Rope** 0.9.4+ and **Jedi** 0.9.0+: Editor code completion, calltips and go-to-definition. @@ -195,6 +202,8 @@ a Python version greater than 2.7 or 3.4 (Python <=3.3 is no longer supported). ## More information +[Main Website](https://www.spyder-ide.org/) + [Download Spyder (with Anaconda)](https://www.anaconda.com/download/) [Online Documentation](https://docs.spyder-ide.org/) @@ -202,7 +211,7 @@ a Python version greater than 2.7 or 3.4 (Python <=3.3 is no longer supported). [Spyder Github](https://github.com/spyder-ide/spyder) [Troubleshooting Guide and FAQ]( -https://github.com/spyder-ide/spyder/wiki/Troubleshooting-Guide-and-FAQ') +https://github.com/spyder-ide/spyder/wiki/Troubleshooting-Guide-and-FAQ) [Development Wiki](https://github.com/spyder-ide/spyder/wiki/Dev:-Index) @@ -210,4 +219,8 @@ https://github.com/spyder-ide/spyder/wiki/Troubleshooting-Guide-and-FAQ') [Google Group](http://groups.google.com/group/spyderlib) +[@Spyder_IDE on Twitter](https://twitter.com/spyder_ide) + +[@SpyderIDE on Facebook](https://www.facebook.com/SpyderIDE/) + [Support Spyder on OpenCollective](https://opencollective.com/spyder/) diff --git a/appveyor.yml b/appveyor.yml index 768b7d1dfaf..752b57ed07a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -47,8 +47,6 @@ install: - "conda install jupyter_client=5.2.2" # Fix problems with latest pyqt - "conda install pyqt=5.6*" - # Fix test issues with the latest jedi 0.12 for now - - "conda install jedi=0.11.1" build: false diff --git a/bootstrap.py b/bootstrap.py index ae85b33122e..3e65e282537 100755 --- a/bootstrap.py +++ b/bootstrap.py @@ -12,6 +12,8 @@ """ # pylint: disable=C0103 +# pylint: disable=C0412 +# pylint: disable=C0413 import time time_start = time.time() @@ -20,6 +22,7 @@ import os.path as osp import sys import optparse +import shutil # --- Parse command line @@ -39,8 +42,9 @@ "is to show the console") parser.add_option('--hide-console', action='store_true', default=False, help="Hide parent console window (Windows only)") -parser.add_option('--test', dest="test", action='store_true', default=False, - help="Test Spyder with a clean settings dir") +parser.add_option('--safe-mode', dest="safe_mode", + action='store_true', default=False, + help="Start Spyder with a clean configuration directory") parser.add_option('--no-apport', action='store_true', default=False, help="Disable Apport exception hook (Ubuntu)") parser.add_option('--debug', action='store_true', @@ -54,9 +58,9 @@ assert options.gui in (None, 'pyqt5', 'pyqt', 'pyside'), \ "Invalid GUI toolkit option '%s'" % options.gui -# For testing purposes -if options.test: - os.environ['SPYDER_TEST'] = 'True' +# Start Spyder with a clean configuration directory for testing purposes +if options.safe_mode: + os.environ['SPYDER_SAFE_MODE'] = 'True' # Prepare arguments for Spyder's main script sys.argv = [sys.argv[0]] + args @@ -117,21 +121,14 @@ print("01. Patched sys.path with %s" % DEVPATH) -# Selecting the GUI toolkit: PyQt5 if installed, otherwise PySide or PyQt4 -# (Note: PyQt4 is still the officially supported GUI toolkit for Spyder) +# Selecting the GUI toolkit: PyQt5 if installed if options.gui is None: try: import PyQt5 # analysis:ignore print("02. PyQt5 is detected, selecting") os.environ['QT_API'] = 'pyqt5' except ImportError: - try: - import PyQt4 # analysis:ignore - print("02. PyQt4 is detected, selecting") - os.environ['QT_API'] = 'pyqt' - except ImportError: - print("02. No PyQt5 or PyQt4 detected, using PySide if available " - "(deprecated)") + sys.exit("ERROR: No PyQt5 detected!") else: print ("02. Skipping GUI toolkit detection") os.environ['QT_API'] = options.gui @@ -165,13 +162,20 @@ print("0x. Hiding parent console (Windows only)") sys.argv.append("--hide-console") # Windows only: show parent console +# Reset temporary config directory if starting in --safe-mode +if options.safe_mode or os.environ.get('SPYDER_SAFE_MODE'): + from spyder.config.base import get_conf_path # analysis:ignore + conf_dir = get_conf_path() + if osp.isdir(conf_dir): + shutil.rmtree(conf_dir) + print("04. Running Spyder") -from spyder.app import start +from spyder.app import start # analysis:ignore -time_lapse = time.time()-time_start -print("Bootstrap completed in " + - time.strftime("%H:%M:%S.", time.gmtime(time_lapse)) + - # gmtime() converts float into tuple, but loses milliseconds - ("%.4f" % time_lapse).split('.')[1]) +time_lapse = time.time() - time_start +print("Bootstrap completed in " + + time.strftime("%H:%M:%S.", time.gmtime(time_lapse)) + # gmtime() converts float into tuple, but loses milliseconds + + ("%.4f" % time_lapse).split('.')[1]) start.main() diff --git a/continuous_integration/circle/test-qt5.sh b/continuous_integration/circle/test-qt5.sh deleted file mode 100755 index 890b50a1774..00000000000 --- a/continuous_integration/circle/test-qt5.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -export PATH="$HOME/miniconda/bin:$PATH" -source activate test - -conda install -q qt=5.* pyqt=5.* qtconsole matplotlib - -python runtests.py diff --git a/continuous_integration/travis/install-qt.sh b/continuous_integration/travis/install-qt.sh index e962721a0b2..a4432d4ed43 100755 --- a/continuous_integration/travis/install-qt.sh +++ b/continuous_integration/travis/install-qt.sh @@ -3,15 +3,11 @@ export PATH="$HOME/miniconda/bin:$PATH" source activate test -# We test with pip packages in Python 3.5 and PyQt5 -if [ "$TRAVIS_PYTHON_VERSION" = "3.5" ] && [ "$USE_PYQT" = "pyqt5" ]; then +if [ "$USE_CONDA" = "no" ]; then pip uninstall -q -y pytest-xvfb # 5.10 is giving segfaults while collecting tests pip install -q pyqt5==5.9.2 - # Install qtconsole from Github - pip install git+https://github.com/jupyter/qtconsole.git - # Install qtpy from Github pip install git+https://github.com/spyder-ide/qtpy.git elif [ "$USE_PYQT" = "pyqt5" ]; then diff --git a/continuous_integration/travis/install.sh b/continuous_integration/travis/install.sh index c68527d20bf..b0fa91c2c61 100755 --- a/continuous_integration/travis/install.sh +++ b/continuous_integration/travis/install.sh @@ -1,7 +1,6 @@ #!/bin/bash -# We test with pip packages in Python 3.5 and PyQt5 -if [ "$TRAVIS_PYTHON_VERSION" = "3.5" ] && [ "$USE_PYQT" = "pyqt5" ]; then +if [ "$USE_CONDA" = "no" ]; then export PIP_DEPENDENCIES_FLAGS="-q" export PIP_DEPENDENCIES="coveralls" export CONDA_DEPENDENCIES="" @@ -23,8 +22,7 @@ export PATH="$HOME/miniconda/bin:$PATH" source activate test -# We test with pip packages in Python 3.5 and PyQt5 -if [ "$TRAVIS_PYTHON_VERSION" = "3.5" ] && [ "$USE_PYQT" = "pyqt5" ]; then +if [ "$USE_CONDA" = "no" ]; then # Install qtconsole from Github pip install git+https://github.com/jupyter/qtconsole.git @@ -36,16 +34,10 @@ if [ "$TRAVIS_PYTHON_VERSION" = "3.5" ] && [ "$USE_PYQT" = "pyqt5" ]; then # Fix connection to external kernels pip install jupyter-client==5.2.2 - - # Avoid test failures with the latest jedi 0.12 for now - pip install jedi==0.11.1 else # Run with tornado < 5.0 to avoid hangs conda install tornado=4.5.3 # Fix connection to external kernels conda install jupyter_client=5.2.2 - - # Avoid test failures with the latest jedi 0.12 for now - conda install jedi=0.11.1 fi diff --git a/doc/_static/favicon.ico b/doc/_static/favicon.ico deleted file mode 100644 index 3993a34f539..00000000000 Binary files a/doc/_static/favicon.ico and /dev/null differ diff --git a/doc/conf.py b/doc/conf.py deleted file mode 100644 index 64f1ed0685d..00000000000 --- a/doc/conf.py +++ /dev/null @@ -1,194 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Spyder documentation build configuration file, created by -# sphinx-quickstart on Fri Jul 10 16:32:25 2009. -# -# This file is execfile()d with the current directory set to its containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys, os - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.append(os.path.abspath('.')) - -# -- General configuration ----------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = [] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = 'Spyder' -copyright = 'The Spyder Project Contributors' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '3' -# The full version, including alpha/beta/rc tags. -release = '3' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of documents that shouldn't be included in the build. -#unused_docs = [] - -# List of directories, relative to source directory, that shouldn't be searched -# for source files. -exclude_trees = [] - -# The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - - -# -- Options for HTML output --------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. Major themes that come with -# Sphinx are currently 'default' and 'sphinxdoc'. -html_theme = 'sphinxdoc' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -## html_theme_options = {'sidebarbgcolor': '#227A2B', -## 'sidebarlinkcolor': '#98ff99'} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -html_logo = 'spyder_bbg.png' - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -html_favicon = '_static/favicon.ico' - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_use_modindex = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = '' - -# Output file base name for HTML help builder. -htmlhelp_basename = 'Spyderdoc' - - -# -- Options for LaTeX output -------------------------------------------------- - -# The paper size ('letter' or 'a4'). -#latex_paper_size = 'letter' - -# The font size ('10pt', '11pt' or '12pt'). -#latex_font_size = '10pt' - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). -latex_documents = [ - ('index', 'Spyder.tex', 'Spyder Documentation', 'Pierre Raybaut', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# Additional stuff for the LaTeX preamble. -#latex_preamble = '' - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_use_modindex = True diff --git a/doc/console.rst b/doc/console.rst deleted file mode 100644 index da358088d04..00000000000 --- a/doc/console.rst +++ /dev/null @@ -1,36 +0,0 @@ -Console -======= - -The **Console** is where you may enter, interact with and visualize data, -inside a command interpreter. All the commands entered in the console are -executed in a separate process, thus allowing the user to interrupt any -process at any time. - -.. image:: images/console.png - -Many command windows may be created in the **Console**: - -* Python interpreter -* Running Python script -* System command window (this terminal emulation window has quite limited - features compared to a real terminal: it may be useful on Windows - platforms where the system terminal is not much more powerful - on the - contrary, on GNU/Linux, a real system terminal is opened, outside Spyder) - -Python-based command windows support the following features: - -* Code completion and calltips -* Variable explorer with GUI-based editors for arrays, lists, - dictionaries, strings, etc. -* Debugging with standard Python debugger (`pdb`): at each breakpoint - the corresponding script is opened in the :doc:`editor` at the breakpoint - line number -* User Module Deleter (see below) - - -Related plugins: - -* :doc:`help` -* :doc:`historylog` -* :doc:`editor` -* :doc:`fileexplorer` diff --git a/doc/debugging.rst b/doc/debugging.rst deleted file mode 100644 index 3ddd88f75e6..00000000000 --- a/doc/debugging.rst +++ /dev/null @@ -1,37 +0,0 @@ -Debugging -========= - -Debugging in Spyder is supported thanks to the following Python modules: - -* `pdb`: the Python debugger, which is included in Python standard library. - -* `winpdb`: a graphical frontend to `pdb`, which is an external package - (in the :doc:`editor`, press F7 to run `winpdb` on the currently edited - script). - -Debugging with pdb ------------------- - -The Python debugger is partly integrated in Spyder: - -* Breakpoints may be defined in the :doc:`editor`. - - * Simple breakpoints can be set from the Run menu, by keyboard shortcut - (F12 by default), or by double-click to the left of line numbers - in the :doc:`editor`. - * Conditional breakpoints can also be set from the Run menu, by - keyboard shortcut (Shift+F12 by default), or by Shift+double-click - to the left of line numbers in the :doc:`editor`. - -* The current frame (debugging step) is highlighted in the :doc:`editor`. -* At each breakpoint, globals may be accessed through - the :doc:`variableexplorer`. - -For a simple, yet quite complete introduction to `pdb`, you may read this: -http://pythonconquerstheuniverse.wordpress.com/category/python-debugger/ - - -Related plugins: - -* :doc:`editor` -* :doc:`console` diff --git a/doc/editor.rst b/doc/editor.rst deleted file mode 100644 index a903a234625..00000000000 --- a/doc/editor.rst +++ /dev/null @@ -1,53 +0,0 @@ -Editor -====== - -Spyder's text editor is a multi-language editor with features such as syntax -coloring, code analysis (real-time code analysis powered by `pyflakes` and -advanced code analysis using `pylint`), introspection capabilities such as -code completion, calltips and go-to-definition features (powered by `rope`), -function/class browser, horizontal/vertical splitting features, etc. - -Function/class/method browser: - -| - -.. image:: images/editor1.png - :align: center -| - -Code analysis with `pyflakes`: - -| - -.. image:: images/editor2.png - :align: center -| - -Horizontal/vertical splitting feature: - -| - -.. image:: images/editor3.png - :align: center -| - -How to define a code cell --------------------------- - -A "code cell" is a concept similar to MATLAB's "cell" (except that there is -no "cell mode" in Spyder), i.e. a block of lines to be executed at once in the -current interpreter (Python or IPython). Every script may be divided in as -many cells as needed. - -Cells are separated by lines starting with: - -* `#%%` (standard cell separator) -* `# %%` (standard cell separator, when file has been edited with Eclipse) -* `# ` (IPython notebook cell separator) - - -Related plugins: - -* :doc:`console` -* :doc:`fileexplorer` -* :doc:`findinfiles` diff --git a/doc/fileexplorer.rst b/doc/fileexplorer.rst deleted file mode 100644 index f20d58599cd..00000000000 --- a/doc/fileexplorer.rst +++ /dev/null @@ -1,33 +0,0 @@ -File Explorer -============= - -The file explorer pane is a file/directory browser allowing the user to open -files with the internal editor or with the appropriate application (Windows -only). - -| - -.. image:: images/explorer.png - :align: center - -| - -Context menus may be used to run a script, open a terminal window or run a -Windows explorer window (Windows only): - -| - -.. image:: images/explorer_menu1.png - :align: center - -| - -.. image:: images/explorer_menu2.png - :align: center - -| - -Related plugins: - -* :doc:`ipythonconsole` -* :doc:`editor` diff --git a/doc/findinfiles.rst b/doc/findinfiles.rst deleted file mode 100644 index 0cb934feeb3..00000000000 --- a/doc/findinfiles.rst +++ /dev/null @@ -1,12 +0,0 @@ -Find in files -============= - -The *Find in Files* plugin provides text search in whole directories or -`mercurial` repositories (or even in PYTHONPATH) with regular expression -support for maximum search customization. - -.. image:: images/findinfiles.png - -Related plugins: - -* :doc:`editor` diff --git a/doc/help.rst b/doc/help.rst deleted file mode 100644 index d33c8b7a1ae..00000000000 --- a/doc/help.rst +++ /dev/null @@ -1,34 +0,0 @@ -Help -==== - -The help plugin works together with the :doc:`console` and the -:doc:`editor`: it shows automatically documentation available when the -user is instantiating a class or calling a function (pressing the left -parenthesis key after a valid function or class name triggers a call -in the help pane). - -Note that this automatic link may be disabled by pressing the "Lock" button -(at the top right corner of the window). - -Of course, one can use the documentation viewer directly by entering an object -name in the editable combo box field, or by selecting old documentation requests -in the combo box. - -Plain text mode: - -.. image:: images/help_plain.png - -Rich text mode: - -.. image:: images/help_rich.png - -Sometimes, when docstrings are not available or not sufficient to document the -object, the documentation viewer can show the source code (if available, i.e. -if the object is pure Python): - -.. image:: images/help_source.png - -Related plugins: - -* :doc:`console` -* :doc:`editor` diff --git a/doc/historylog.rst b/doc/historylog.rst deleted file mode 100644 index 9cbd3e7444f..00000000000 --- a/doc/historylog.rst +++ /dev/null @@ -1,11 +0,0 @@ -History log -=========== - -The history log plugin collects command histories of Python/IPython interpreters -or command windows. - -.. image:: images/historylog.png - -Related plugins: - -* :doc:`console` diff --git a/doc/images/arrayeditor.png b/doc/images/arrayeditor.png deleted file mode 100644 index 36fd440ceb2..00000000000 Binary files a/doc/images/arrayeditor.png and /dev/null differ diff --git a/doc/images/console.png b/doc/images/console.png deleted file mode 100644 index 151756cec30..00000000000 Binary files a/doc/images/console.png and /dev/null differ diff --git a/doc/images/dicteditor.png b/doc/images/dicteditor.png deleted file mode 100644 index 83861ce1884..00000000000 Binary files a/doc/images/dicteditor.png and /dev/null differ diff --git a/doc/images/editor1.png b/doc/images/editor1.png deleted file mode 100644 index 5638e4c4ed6..00000000000 Binary files a/doc/images/editor1.png and /dev/null differ diff --git a/doc/images/editor2.png b/doc/images/editor2.png deleted file mode 100644 index 07383d9abf3..00000000000 Binary files a/doc/images/editor2.png and /dev/null differ diff --git a/doc/images/editor3.png b/doc/images/editor3.png deleted file mode 100644 index 36e4a39997e..00000000000 Binary files a/doc/images/editor3.png and /dev/null differ diff --git a/doc/images/explorer.png b/doc/images/explorer.png deleted file mode 100644 index 5171466048f..00000000000 Binary files a/doc/images/explorer.png and /dev/null differ diff --git a/doc/images/explorer_menu1.png b/doc/images/explorer_menu1.png deleted file mode 100644 index cd8e3bc37cd..00000000000 Binary files a/doc/images/explorer_menu1.png and /dev/null differ diff --git a/doc/images/explorer_menu2.png b/doc/images/explorer_menu2.png deleted file mode 100644 index 68f1c04863a..00000000000 Binary files a/doc/images/explorer_menu2.png and /dev/null differ diff --git a/doc/images/findinfiles.png b/doc/images/findinfiles.png deleted file mode 100644 index dc94943f88d..00000000000 Binary files a/doc/images/findinfiles.png and /dev/null differ diff --git a/doc/images/git_install_dialog.png b/doc/images/git_install_dialog.png deleted file mode 100644 index 65e63a3dd11..00000000000 Binary files a/doc/images/git_install_dialog.png and /dev/null differ diff --git a/doc/images/help_plain.png b/doc/images/help_plain.png deleted file mode 100644 index a9ca61dfb76..00000000000 Binary files a/doc/images/help_plain.png and /dev/null differ diff --git a/doc/images/help_rich.png b/doc/images/help_rich.png deleted file mode 100644 index 69ab608c3bc..00000000000 Binary files a/doc/images/help_rich.png and /dev/null differ diff --git a/doc/images/help_source.png b/doc/images/help_source.png deleted file mode 100644 index a5b31780d75..00000000000 Binary files a/doc/images/help_source.png and /dev/null differ diff --git a/doc/images/historylog.png b/doc/images/historylog.png deleted file mode 100644 index 39651064647..00000000000 Binary files a/doc/images/historylog.png and /dev/null differ diff --git a/doc/images/internalconsole.png b/doc/images/internalconsole.png deleted file mode 100644 index 60e8ecca353..00000000000 Binary files a/doc/images/internalconsole.png and /dev/null differ diff --git a/doc/images/ipythonconsole.png b/doc/images/ipythonconsole.png deleted file mode 100644 index 13ac0f0f43f..00000000000 Binary files a/doc/images/ipythonconsole.png and /dev/null differ diff --git a/doc/images/ipythonconsolemenu.png b/doc/images/ipythonconsolemenu.png deleted file mode 100644 index 1034ae47e85..00000000000 Binary files a/doc/images/ipythonconsolemenu.png and /dev/null differ diff --git a/doc/images/ipythonkernelconnect.png b/doc/images/ipythonkernelconnect.png deleted file mode 100644 index 7f432264271..00000000000 Binary files a/doc/images/ipythonkernelconnect.png and /dev/null differ diff --git a/doc/images/lightmode.png b/doc/images/lightmode.png deleted file mode 100644 index 1f4bd14588e..00000000000 Binary files a/doc/images/lightmode.png and /dev/null differ diff --git a/doc/images/listeditor.png b/doc/images/listeditor.png deleted file mode 100644 index 87dd9a434ca..00000000000 Binary files a/doc/images/listeditor.png and /dev/null differ diff --git a/doc/images/new_project.png b/doc/images/new_project.png deleted file mode 100644 index 2e99b67dbbb..00000000000 Binary files a/doc/images/new_project.png and /dev/null differ diff --git a/doc/images/onlinehelp.png b/doc/images/onlinehelp.png deleted file mode 100644 index f8455ed8dce..00000000000 Binary files a/doc/images/onlinehelp.png and /dev/null differ diff --git a/doc/images/projectexplorer.png b/doc/images/projectexplorer.png deleted file mode 100644 index 0caf45cf590..00000000000 Binary files a/doc/images/projectexplorer.png and /dev/null differ diff --git a/doc/images/projectexplorer2.png b/doc/images/projectexplorer2.png deleted file mode 100644 index 4a4f73edca7..00000000000 Binary files a/doc/images/projectexplorer2.png and /dev/null differ diff --git a/doc/images/pylint.png b/doc/images/pylint.png deleted file mode 100644 index e186afa623e..00000000000 Binary files a/doc/images/pylint.png and /dev/null differ diff --git a/doc/images/texteditor.png b/doc/images/texteditor.png deleted file mode 100644 index 70cbe30d1db..00000000000 Binary files a/doc/images/texteditor.png and /dev/null differ diff --git a/doc/images/variableexplorer-imshow.png b/doc/images/variableexplorer-imshow.png deleted file mode 100644 index a1b91cffc34..00000000000 Binary files a/doc/images/variableexplorer-imshow.png and /dev/null differ diff --git a/doc/images/variableexplorer-plot.png b/doc/images/variableexplorer-plot.png deleted file mode 100644 index 6b6d6df1217..00000000000 Binary files a/doc/images/variableexplorer-plot.png and /dev/null differ diff --git a/doc/images/variableexplorer1.png b/doc/images/variableexplorer1.png deleted file mode 100644 index 3415ecc5523..00000000000 Binary files a/doc/images/variableexplorer1.png and /dev/null differ diff --git a/doc/index.rst b/doc/index.rst deleted file mode 100644 index 681319b91cc..00000000000 --- a/doc/index.rst +++ /dev/null @@ -1,51 +0,0 @@ -Spyder - Documentation -====================== - -Spyder is the Scientific PYthon Development EnviRonment: - -* A powerful interactive development environment for the Python language with - advanced editing, interactive testing, debugging and introspection features -* A numerical computing environment thanks to the support of `IPython` - (an enhanced interactive Python interpreter) and popular Python libraries - such as `NumPy` (linear algebra), `SciPy` (signal and image processing) - and `matplotlib` (interactive 2D/3D plotting). - -Spyder may also be used as a library providing powerful console-related widgets -for your PyQt-based applications -- for example, it may be used to integrate a -debugging console directly in the layout of your graphical user interface. - -Spyder websites: - -* Downloads, bug reports and feature requests: https://github.com/spyder-ide/spyder -* Discussions: http://groups.google.com/group/spyderlib -* Troubleshooting Guide and FAQ - https://github.com/spyder-ide/spyder/wiki/Troubleshooting-Guide-and-FAQ - - -Contents: - -.. toctree:: - :maxdepth: 2 - :glob: - - overview - installation - options - editor - ipythonconsole - debugging - console - variableexplorer - help - projects - pylint - fileexplorer - historylog - findinfiles - onlinehelp - internalconsole - -Indices and tables: - -* :ref:`genindex` -* :ref:`search` diff --git a/doc/installation.rst b/doc/installation.rst deleted file mode 100644 index 0aac555b1c6..00000000000 --- a/doc/installation.rst +++ /dev/null @@ -1,324 +0,0 @@ -Installation -============ - -Spyder is quite easy to install on Windows, Linux and macOS; just read the -following instructions with care. - -This section explains how to install the latest stable release of Spyder. -If you prefer testing the development version, please use the -``bootstrap`` script (see next section). - -If you run into problems, before posting a report, -*please* consult our comprehensive -`Troubleshooting Guide `_ -and search the `issue tracker `_ -for your error message and problem description, as these methods are known to -fix or at least isolate the vast majority of install-related problems. -Thanks! - - -The Easy/Recommended Way: Anaconda ----------------------------------- - -Spyder is included in the `Anaconda `_ -Python distribution, which comes with everything you need to get started in -an all-in-one package. - -This is the easiest way to install Spyder for any of our supported platforms, -and the way we recommend to avoid unexpected issues we aren't able to -help you with. If in doubt, you should install via this method; -it generally has the least likelihood of potential pitfalls for non-experts, -and we may be able to provide limited assistance if you do run into trouble. - - -The Harder Way: Alternative distributions ------------------------------------------ - -**Important Note:** While we offer alternative Spyder installation options -for users who desire them, we currently lack the resources to offer individual -assistance for problems specific to installing via these alternative distributions. -Therefore, we recommend you switch to Anaconda if you encounter installation -issues you are unable to solve on your own. - -Windows -~~~~~~~ - -Spyder is also included in the `WinPython `_ -scientific Python distribution, although some users have reported bugs specific -to it. You can use it immediately after installing, just like with Anaconda. - -macOS -~~~~~ - -Thanks to the `*MacPorts* project `_, Spyder can be -installed using its ``port`` package manager; however, it may be out of date -or have MacPorts-specific issues outside of Spyder's control. - -There are `several versions`__ available from which you can choose from. - -__ http://www.macports.org/ports.php?by=name&substr=spyder - - .. warning:: - - It is known that the MacPorts version of Spyder is raising this error: - ``ValueError: unknown locale: UTF-8``, which doesn't let it start correctly. - - To fix it you will have to set these environment variables in your - ``~/.profile`` (or ``~/.bashrc``) manually:: - - export LANG=en_US.UTF-8 - export LC_ALL=en_US.UTF-8 - -| - -GNU/Linux -~~~~~~~~~ - -Please refer to the `Requirements`_ section to see what other packages you -might need. - -**Ubuntu**: - -Using the official package manager: ``sudo apt-get install spyder``. - - .. note:: - - This package could be slightly outdated. If you find that is the case, - please use the Debian package mentioned below. - - -**Debian Unstable**: - -Using the package manager: ``sudo apt-get install spyder`` - -The Spyder's official Debian package is available `here`__ - -__ http://packages.debian.org/fr/sid/spyder. - - -**Other Distributions** - -Spyder is also available in other GNU/Linux distributions, like - -* `Archlinux `_ - -* `Fedora `_ - -* `Gentoo `_ - -* `openSUSE `_ - -* `Mageia `_ - -Please refer to your distribution's documentation to learn how to install it -there. - -| - - -The Expert Way: Installing with pip ------------------------------------ - -**Warning:** While this installation method is a viable option for -experienced users, installing Spyder (and other SciPy stack packages) -with `pip` can lead to a number of tricky issues. While you are welcome -to try this on your own, we unfortunately do not have the resources to help you -if you do run into problems, except to recommend using Anaconda instead. - - -Requirements -~~~~~~~~~~~~ - -The requirements to run Spyder are: - -* `Python `_ 2.7 or >=3.3 - -* `PyQt5 `_ >=5.2 or - `PyQt4 `_ >=4.6.0 - (PyQt5 is recommended). - -* `Qtconsole `_ >=4.2.0 -- for an - enhanced Python interpreter. - -* `Rope `_ >=0.9.4 and - `Jedi `_ >=0.9.0 -- for code completion, - go-to-definition and calltips on the Editor. - -* `Pyflakes `_ -- for real-time - code analysis. - -* `Sphinx `_ -- for the Help pane rich text mode - and to get our documentation. - -* `Pygments `_ >=2.0 -- for syntax highlighting and code - completion in the Editor of all file types it supports. - -* `Pylint `_ -- for static code analysis. - -* `Pycodestyle `_ -- for style analysis. - -* `Psutil `_ -- for memory/CPU usage in the status - bar. - -* `Nbconvert `_ -- to manipulate Jupyter notebooks - on the Editor. - -* `Qtawesome `_ >=0.4.1 -- for an icon theme based on - FontAwesome. - -* Pickleshare -- To show import completions on the Editor and Consoles. - -* `PyZMQ `_ -- To run introspection services on the - Editor asynchronously. - -* `QtPy `_ >=1.2.0 -- To run Spyder with PyQt4 or - PyQt5 seamlessly. - -* `Chardet `_ >=2.0.0-- Character encoding auto-detection - in Python. - -* `Numpydoc `_ Used by Jedi to get return types for - functions with Numpydoc docstrings. - -* `Cloudpickle `_ Serialize variables in the - IPython kernel to send them to Spyder. - - -Optional modules -~~~~~~~~~~~~~~~~ - -* `Matplotlib `_ >=1.0 -- for 2D and 3D plotting - in the consoles. - -* `Pandas `_ >=0.13.1 -- for view and editing DataFrames - and Series in the Variable Explorer. - -* `Numpy `_ -- for view and editing two or three - dimensional arrays in the Variable Explorer. - -* `Sympy `_ >=0.7.3 -- for working with symbolic mathematics - in the IPython console. - -* `Scipy `_ -- for importing Matlab workspace files in - the Variable Explorer. - -* `Cython `_ >=0.21 -- Run Cython files or Python files that - depend on Cython libraries in the IPython console. - - -Installation procedure -~~~~~~~~~~~~~~~~~~~~~~ - -You can install Spyder with the ``pip`` package manager, which comes by -default with most Python installations. -Before installing Spyder itself by this method, you need to acquire the -`Python programming language `_ - -Then, to install Spyder and its other dependencies, run ``pip install spyder``. -You may need to separately install a Qt binding with ``pip`` if running Python 2; -PyQt5 is strongly recommended though the legacy PyQt4 is also still supported. - - -Run without installing -~~~~~~~~~~~~~~~~~~~~~~ - -You can execute Spyder without installing it first by following these steps: - -#. Unzip the source package available for download on the - `Spyder Github repo `_ - (or clone from Github, see the next section) -#. Change current directory to the unzipped directory -#. Run Spyder with the command ``python bootstrap.py`` -#. (*Optional*) Build the documentation with ``python setup.py build_doc``. - -This is especially useful for beta-testing, troubleshooting and helping develop -Spyder itself. - -| - - -Updating Spyder ---------------- - -You can update Spyder by: - -* Updating Anaconda (recommended), WinPython, MacPorts, or - through your system package manager, if you installed via those options. - - With Anaconda, just run (in Anaconda Prompt if on Windows) - ``conda update spyder`` - to update Spyder specifically, and - ``conda update anaconda`` - to update the rest of the distribution, as desired. - -* If you installed Spyder via the advanced/crossplatform method, - ``pip``, run - ``pip install --upgrade spyder`` - - .. note:: - - This command will also update all Spyder dependencies - -| - - -Installing the development version ----------------------------------- - -If you want to try the next Spyder version before it is released, you can! -You may want to do this for fixing bugs in Spyder, adding new -features, learning how Spyder works or just getting a taste of it. -For more information, please see the CONTRIBUTING.md document included -with the Spyder source or on Github, or for further detail consult the -`online development wiki `_ . - -To do so: - -#. Install Spyder `requirements`_ - - The recommended and easiest way to do this is with ``conda``: - ``conda install spyder`` - then - ``conda remove spyder`` - - This installs all of Spyder's dependencies into the environment along with - the stable/packaged version of Spyder itself, and then removes the latter. - -#. Install `Git `_, a powerful - source control management tool. - -#. Clone the Spyder source code repository with the command: - - ``git clone https://github.com/spyder-ide/spyder.git`` - -#. Run Spyder with the ``bootstrap.py`` script from within the cloned directory: - ``python bootstrap.py`` - -#. To keep your repository up-to-date, run - - ``git pull`` - - inside the cloned directory. - -#. (*Optional*) If you want to read the documentation, you must build it first - with the command - - ``python setup.py build_doc`` - -| - - -Help and support ----------------- - -Spyder websites: - -* For a comprehensive guide to spyder troubleshooting, including - installation issues, read our `Troubleshooting Guide and FAQ - `_. -* For bug reports and feature requests you can go to our - `website `_. -* For general and development-oriented information, visit - `our Github wiki `_. -* For discussions and help requests, you can subscribe to our - `Google Group `_. diff --git a/doc/internalconsole.rst b/doc/internalconsole.rst deleted file mode 100644 index c12881f370b..00000000000 --- a/doc/internalconsole.rst +++ /dev/null @@ -1,19 +0,0 @@ -Internal Console -================ - -The **Internal Console** is dedicated to Spyder internal debugging or may be -used as an embedded Python console in your own application. -All the commands entered in the internal console are executed in the same -process as Spyder's, but the Internal Console may be executed in a separate -thread (this is optional and for example this is not the case in Spyder itself). - -| - -.. image:: images/internalconsole.png - :align: center - -| - -The internal console support the following features: - -* Code completion and calltips diff --git a/doc/ipythonconsole.rst b/doc/ipythonconsole.rst deleted file mode 100644 index f530daee17b..00000000000 --- a/doc/ipythonconsole.rst +++ /dev/null @@ -1,86 +0,0 @@ -IPython Console -=============== - -Spyder's **IPython Console** implements a full two-process -`IPython `_ session where -a lightweight front-end interface connects to a full IPython kernel on the -back end. Visit the IPython project website for full documentation of -IPython's many features. - -| - -.. image:: images/ipythonconsole.png - :align: center -| - -From the Consoles menu, Spyder can launch **IPython Console** -instances that attach to kernels that are managed -by Spyder itself or it can connect to external kernels that are managed -by IPython Qt Console sessions or the IPython Notebook. - -| - -.. image:: images/ipythonconsolemenu.png - :align: center - -| - -When "Connect to an existing kernel" is selected, Spyder prompts for the -kernel connection file details: - -| - -.. image:: images/ipythonkernelconnect.png - :align: center -| - -**IPython Consoles** that are attached to kernels that were created by -Spyder support the following features: - -* Code completion -* Variable explorer with GUI-based editors for arrays, lists, - dictionaries, strings, etc. -* Debugging with standard Python debugger (`pdb`): at each breakpoint - the corresponding script is opened in the :doc:`editor` at the breakpoint - line number -* User Module Deleter (see :doc:`console` for more details) - -**IPython Consoles** attached to external kernels support a smaller feature -set: - -* Code completion -* Debugging toolbar integration for launching the debugger and sending - debugging step commands to the kernel. Breakpoints must be set manually - from the console command line. - - -Reloading modules: the User Module Reloader (UMR) -------------------------------------------------- - -When working with Python scripts interactively, one must keep in mind that -Python import a module from its source code (on disk) only when parsing the -first corresponding import statement. During this first import, the byte code -is generated (.pyc file) if necessary and the imported module code object is -cached in `sys.modules`. Then, when re-importing the same module, this cached -code object will be directly used even if the source code file (.py[w] file) -has changed meanwhile. - -This behavior is sometimes unexpected when working with the Python interpreter -in interactive mode, because one must either always restart the interpreter -or remove manually the .pyc files to be sure that changes made in imported -modules were taken into account. - -The User Module Reloader (UMR) is a Spyder console's exclusive feature that -forces the Python interpreter to reload modules completely when executing -a Python script. - -For example, when UMR is turned on, one may test complex applications -within the same Python interpreter without having to restart it every time -(restart time may be relatively long when testing GUI-based applications). - - -Related plugins: - -* :doc:`help` -* :doc:`editor` -* :doc:`fileexplorer` diff --git a/doc/onlinehelp.rst b/doc/onlinehelp.rst deleted file mode 100644 index 97e281a8596..00000000000 --- a/doc/onlinehelp.rst +++ /dev/null @@ -1,12 +0,0 @@ -Online help -=========== - -The online help plugin provides an internal web browser to explore dynamically -generated Python documentation on installed module, including your own modules -(this documentation is provided by a pydoc server running in background). - -.. image:: images/onlinehelp.png - -Related plugins: - -* :doc:`help` diff --git a/doc/options.rst b/doc/options.rst deleted file mode 100644 index 57e2501d888..00000000000 --- a/doc/options.rst +++ /dev/null @@ -1,23 +0,0 @@ -Command line options -==================== - -Spyder's command line options are the following: - -Options: - -h, --help show this help message and exit - --new-instance Run a new instance of Spyder, even if the single - instance mode has been turned on (default) - --defaults Reset configuration settings to defaults - --reset Remove all configuration files! - --optimize Optimize Spyder bytecode (this may require - administrative privileges) - -w WORKING_DIRECTORY, --workdir=WORKING_DIRECTORY - Default working directory - --hide-console Hide parent console window (Windows) - --show-console (Deprecated) Does nothing, now the default behavior is to show the console - --multithread Internal console is executed in another thread - (separate from main application thread) - --profile Profile mode (internal test, not related with Python - profiling) - --window-title=WINDOW_TITLE - String to show in the main window title diff --git a/doc/overview.rst b/doc/overview.rst deleted file mode 100644 index b4d258c4548..00000000000 --- a/doc/overview.rst +++ /dev/null @@ -1,80 +0,0 @@ -Overview -======== - -Spyder is a Python development environment with the following key features: - -Key features: - -* general features: - - * MATLAB-like PYTHONPATH management dialog box (works with all consoles) - * Windows only: current user environment variables editor - * direct links to documentation (Python, Matplotlib, !NumPy, !Scipy, etc.) - * direct link to Python(x,y) launcher - * direct links to !QtDesigner, !QtLinguist and !QtAssistant (Qt documentation) - -* *preferences* dialog box: - - * keyboard shortcuts - * syntax coloring schemes (source editor, history log, help) - * console: background color (black/white), automatic code completion, etc. - * and a lot more... - -* :doc:`editor`: - - * syntax coloring (Python, C/C++, Fortran) - * *breakpoints* and *conditional breakpoints* (debugger: `pdb`) - * run or debug Python scripts (see console features) - * *run configuration* dialog box: - - * working directory - * command line options - * run in a new Python interpreter or in an existing Python interpreter or IPython client - * Python interpreter command line options - - * *code outline explorer*: functions, classes, if/else/try/... statements - * *powerful code introspection features* (powered by `rope`): - - * *code completion* - * *calltips* - * *go-to-definition*: go to object (any symbol: function, class, attribute, etc.) definition by pressing Ctrl+Left mouse click on word or Ctrl+G (default shortcut) - - * *occurrence highlighting* - * typing helpers (optional): - - * automatically insert closing parentheses, braces and brackets - * automatically unindent after 'else', 'elif', 'finally', etc. - - * *to-do* lists (TODO, FIXME, XXX) - * errors/warnings (real-time *code analysis* provided by `pyflakes`) - * integrated static code analysis (using `pylint`) - * direct link to `winpdb` external debugger - -* :doc:`console`: - - * *all consoles are executed in a separate process* - * *code completion*/calltips and automatic link to help (see below) - * open Python interpreters or basic terminal command windows - * run Python scripts (see source editor features) - * *variable explorer*: - - * *GUI-based editors* for a lot of data types (numbers, strings, lists, arrays, dictionaries, ...) - * *import/export data* from/to a lot of file types (text files, !NumPy files, MATLAB files) - * multiple array/list/dict editor instances at once, thus allowing to compare variable contents - * data visualization - -* :doc:`historylog` -* :doc:`help`: - - * provide documentation or source code on any Python object (class, function, module, ...) - * documentation may be displayed as an html page thanks to the rich text mode (powered by `sphinx`) - -* :doc:`onlinehelp`: automatically generated html documentation on installed Python modules -* :doc:`findinfiles`: find string occurrences in a directory, a mercurial repository or directly in PYTHONPATH (support for regular expressions and included/excluded string lists) -* :doc:`fileexplorer` -* :doc:`projects` - - -Spyder may also be used as a PyQt5 or PyQt4 extension library -(module 'spyder'). For example, the Python interactive shell widget -used in Spyder may be embedded in your own PyQt5 or PyQt4 application. diff --git a/doc/projects.rst b/doc/projects.rst deleted file mode 100644 index 98840bf021c..00000000000 --- a/doc/projects.rst +++ /dev/null @@ -1,69 +0,0 @@ -Projects -======== - -Spyder allows users to associate a given directory with a project. This has two -main advantages: - -1. Projects remember the list of open files in Editor. This permits to easily - work on several coding efforts at the same time. -2. The project's path is added to the list of paths Python looks modules for, so - that modules developed as part of a project can be easily imported in any - console. - -To create a project, it is necessary to select the *New Project* entry from the -*Projects* menu: - -| - -.. image:: images/new_project.png - :align: center - -| - -When a project is activated, the *Project explorer* pane is shown, which -presents a tree view structure of the current project - -| - -.. image:: images/projectexplorer.png - :align: center - -| - -Through this pane it is possible to make several operations on the files that -belong to project - -| - -.. image:: images/projectexplorer2.png - :align: center - -| - -.. note:: Projects are completely optional and not imposed on users, i.e. users - can work without creating any project. - - -Version Control Integration ---------------------------- - -Spyder has limited integration with Git_ and Mercurial_. Commit and browse -commands are available by right-clicking on relevant files that reside within -an already initialized repository. This menu assume that certain commands are -available on the system path. - -* For Mercurial repositories, TortoiseHG_ must be installed, and either ``thg`` - or ``hgtk`` must be on the system path. -* For git repositories, the commands ``git`` and ``gitk`` must be on the - system path. For Windows systems, the `Git for Windows`_ package provides a - convenient installer and the option to place common git commands on the - system path without creating conflicts with Windows system tools. - The second option in the dialog below is generally a safe approach. - -.. image:: images/git_install_dialog.png - :align: center - -.. _Git: http://git-scm.com/ -.. _Mercurial: http://mercurial.selenic.com/ -.. _TortoiseHg: http://tortoisehg.bitbucket.org/ -.. _Git for Windows: https://git-for-windows.github.io/ diff --git a/doc/pylint.rst b/doc/pylint.rst deleted file mode 100644 index 309cd5b0551..00000000000 --- a/doc/pylint.rst +++ /dev/null @@ -1,18 +0,0 @@ -Static code analysis -==================== - -The static code analysis tool may be used directly from the :doc:`editor`, or -by entering manually the Python module or package path - i.e. it works either -with `.py` (or `.pyw`) Python scripts or with whole Python packages -(directories containing an `__init__.py` script). - -| - -.. image:: images/pylint.png - :align: center - -| - -Related plugins: - -* :doc:`editor` diff --git a/doc/spyder_bbg.png b/doc/spyder_bbg.png deleted file mode 100644 index e01a4eeb696..00000000000 Binary files a/doc/spyder_bbg.png and /dev/null differ diff --git a/doc/variableexplorer.rst b/doc/variableexplorer.rst deleted file mode 100644 index 39167c8097b..00000000000 --- a/doc/variableexplorer.rst +++ /dev/null @@ -1,71 +0,0 @@ -Variable Explorer -================= - -The variable explorer shows the namespace contents (i.e. all global object -references) of the current console - -| - -.. image:: images/variableexplorer1.png - :align: center - -| - -The following screenshots show some interesting features such as editing -lists, strings, dictionaries, NumPy arrays, or plotting/showing NumPy arrays -data. - -| - -.. image:: images/listeditor.png - :align: center - -| - -.. image:: images/texteditor.png - :align: center - -| - -.. image:: images/dicteditor.png - :align: center - -| - -.. image:: images/arrayeditor.png - :align: center - -| - -.. image:: images/variableexplorer-plot.png - :align: center - -| - -.. image:: images/variableexplorer-imshow.png - :align: center - -| - - -Supported types ---------------- - -The variable explorer can't show all types of objects. The ones currently -supported are: - -#. `Pandas` DataFrame, TimeSeries and DatetimeIndex objects -#. `NumPy` arrays and matrices -#. `PIL/Pillow` images -#. `datetime` dates -#. Integers -#. Floats -#. Complex numbers -#. Lists -#. Dictionaries -#. Tuples -#. Strings - -Related plugins: - -* :doc:`ipythonconsole` diff --git a/img_src/spyder_readme_banner.png b/img_src/spyder_readme_banner.png index 7a32de15974..23e934a3cac 100644 Binary files a/img_src/spyder_readme_banner.png and b/img_src/spyder_readme_banner.png differ diff --git a/setup.py b/setup.py index a48768593ee..5dcd3029fdb 100644 --- a/setup.py +++ b/setup.py @@ -20,8 +20,6 @@ import shutil from distutils.core import setup -from distutils.command.build import build -from distutils.command.install import install from distutils.command.install_data import install_data @@ -36,8 +34,8 @@ # Taken from the notebook setup.py -- Modified BSD License #============================================================================== v = sys.version_info -if v[:2] < (2,7) or (v[0] >= 3 and v[:2] < (3,3)): - error = "ERROR: Spyder requires Python version 2.7 or 3.3 or above." +if v[:2] < (2, 7) or (v[0] >= 3 and v[:2] < (3, 4)): + error = "ERROR: Spyder requires Python version 2.7 or 3.4 and above." print(error, file=sys.stderr) sys.exit(1) @@ -120,87 +118,6 @@ def run(self): CMDCLASS = {'install_data': MyInstallData} -#============================================================================== -# Sphinx build (documentation) -#============================================================================== -def get_html_help_exe(): - """Return HTML Help Workshop executable path (Windows only)""" - if os.name == 'nt': - hhc_base = r'C:\Program Files%s\HTML Help Workshop\hhc.exe' - for hhc_exe in (hhc_base % '', hhc_base % ' (x86)'): - if osp.isfile(hhc_exe): - return hhc_exe - else: - return - -try: - from sphinx import setup_command - - class MyBuild(build): - user_options = [('no-doc', None, "Don't build Spyder documentation")] \ - + build.user_options - def __init__(self, *args, **kwargs): - build.__init__(self, *args, **kwargs) - self.no_doc = False - def with_doc(self): - setup_dir = os.path.dirname(os.path.abspath(__file__)) - is_doc_dir = os.path.isdir(os.path.join(setup_dir, 'doc')) - install_obj = self.distribution.get_command_obj('install') - return (is_doc_dir and not self.no_doc and not install_obj.no_doc) - sub_commands = build.sub_commands + [('build_doc', with_doc)] - CMDCLASS['build'] = MyBuild - - - class MyInstall(install): - user_options = [('no-doc', None, "Don't build Spyder documentation")] \ - + install.user_options - def __init__(self, *args, **kwargs): - install.__init__(self, *args, **kwargs) - self.no_doc = False - CMDCLASS['install'] = MyInstall - - - class MyBuildDoc(setup_command.BuildDoc): - def run(self): - build = self.get_finalized_command('build') - sys.path.insert(0, os.path.abspath(build.build_lib)) - dirname = self.distribution.get_command_obj('build').build_purelib - self.builder_target_dir = osp.join(dirname, 'spyder', 'doc') - - if not osp.exists(self.builder_target_dir): - os.mkdir(self.builder_target_dir) - - hhc_exe = get_html_help_exe() - self.builder = "html" if hhc_exe is None else "htmlhelp" - - try: - setup_command.BuildDoc.run(self) - except UnicodeDecodeError: - print("ERROR: unable to build documentation because Sphinx "\ - "do not handle source path with non-ASCII characters. "\ - "Please try to move the source package to another "\ - "location (path with *only* ASCII characters).", - file=sys.stderr) - sys.path.pop(0) - - # Building chm doc, if HTML Help Workshop is installed - if hhc_exe is not None: - fname = osp.join(self.builder_target_dir, 'Spyderdoc.chm') - subprocess.call('"%s" %s' % (hhc_exe, fname), shell=True) - if osp.isfile(fname): - dest = osp.join(dirname, 'spyder') - try: - shutil.move(fname, dest) - except shutil.Error: - print("Unable to replace %s" % dest) - shutil.rmtree(self.builder_target_dir) - - CMDCLASS['build_doc'] = MyBuildDoc -except ImportError: - print('WARNING: unable to build documentation because Sphinx '\ - 'is not installed', file=sys.stderr) - - #============================================================================== # Main scripts #============================================================================== @@ -233,15 +150,15 @@ def run(self): long_description= """Spyder is an interactive Python development environment providing MATLAB-like features in a simple and light-weighted software. -It also provides ready-to-use pure-Python widgets to your PyQt5 or -PyQt4 application: source code editor with syntax highlighting and +It also provides ready-to-use pure-Python widgets to your PyQt5 +application: A source code editor with syntax highlighting and code introspection/analysis features, NumPy array editor, dictionary editor, Python console, etc.""", download_url='%s/files/%s-%s.zip' % (__project_url__, NAME, __version__), author="The Spyder Project Contributors", url=__project_url__, license='MIT', - keywords='PyQt5 PyQt4 editor shell console widgets IDE', + keywords='PyQt5 editor shell console widgets IDE', platforms=['any'], packages=get_packages(), package_data={LIBNAME: get_package_data(LIBNAME, EXTLIST), @@ -291,10 +208,7 @@ def run(self): 'numpydoc', # Packages for pyqt5 are only available in # Python 3 - 'pyqt5<5.10;python_version>="3"', - # This is only needed for our wheels on Linux. - # See issue #3332 - 'pyopengl;platform_system=="Linux"' + 'pyqt5<5.10;python_version>="3"' ] extras_require = { diff --git a/spyder/__init__.py b/spyder/__init__.py index 08b2cef155d..e31439569fe 100644 --- a/spyder/__init__.py +++ b/spyder/__init__.py @@ -84,7 +84,7 @@ def get_versions(reporev=True): 'python': platform.python_version(), # "2.7.3" 'bitness': 64 if sys.maxsize > 2**32 else 32, 'qt': qtpy.QtCore.__version__, - 'qt_api': qtpy.API_NAME, # PyQt5 or PyQt4 + 'qt_api': qtpy.API_NAME, # PyQt5 'qt_api_ver': qtpy.PYQT_VERSION, 'system': system, # Linux, Windows, ... 'release': platform.release(), # XP, 10.6, 2.2.0, etc. diff --git a/spyder/app/mainwindow.py b/spyder/app/mainwindow.py index fbad989c987..70d4356c4a1 100644 --- a/spyder/app/mainwindow.py +++ b/spyder/app/mainwindow.py @@ -82,10 +82,8 @@ from qtpy.QtWidgets import (QAction, QApplication, QDockWidget, QMainWindow, QMenu, QMessageBox, QShortcut, QSplashScreen, QStyleFactory) + # Avoid a "Cannot mix incompatible Qt library" error on Windows platforms -# when PySide is selected by the QT_API environment variable and when PyQt4 -# is also installed (or any other Qt-based application prepending a directory -# containing incompatible Qt DLLs versions in PATH): from qtpy import QtSvg # analysis:ignore # Avoid a bug in Qt: https://bugreports.qt.io/browse/QTBUG-46720 @@ -141,10 +139,9 @@ # Local utility imports #============================================================================== from spyder import (__version__, __project_url__, __forum_url__, - __trouble_url__, get_versions) -from spyder.config.base import (get_conf_path, get_module_data_path, - get_module_source_path, STDERR, DEBUG, - debug_print, MAC_APP_NAME, get_home_dir, + __trouble_url__, __trouble_url_short__, get_versions) +from spyder.config.base import (get_conf_path, get_module_source_path, STDERR, + DEBUG, debug_print, MAC_APP_NAME, get_home_dir, running_in_mac_app, get_module_path, reset_config_files) from spyder.config.main import OPEN_FILES_PORT @@ -213,18 +210,6 @@ def get_python_doc_path(): return file_uri(python_doc) -def get_focus_python_shell(): - """Extract and return Python shell from widget - Return None if *widget* is not a Python shell (e.g. IPython kernel)""" - widget = QApplication.focusWidget() - from spyder.widgets.shell import PythonShellWidget - from spyder.widgets.externalshell.pythonshell import ExternalPythonShell - if isinstance(widget, PythonShellWidget): - return widget - elif isinstance(widget, ExternalPythonShell): - return widget.shell - - #============================================================================== # Main Window #============================================================================== @@ -243,12 +228,6 @@ class MainWindow(QMainWindow): _("Numpy and Scipy documentation")), ('matplotlib', "http://matplotlib.sourceforge.net/contents.html", _("Matplotlib documentation")), - ('PyQt4', - "http://pyqt.sourceforge.net/Docs/PyQt4/", - _("PyQt4 Reference Guide")), - ('PyQt4', - "http://pyqt.sourceforge.net/Docs/PyQt4/classes.html", - _("PyQt4 API Reference")), ('PyQt5', "http://pyqt.sourceforge.net/Docs/PyQt5/", _("PyQt5 Reference Guide")), @@ -733,11 +712,7 @@ def create_edit_action(text, tr_text, icon): if qtlact: break args = ['-no-opengl'] if os.name == 'nt' else [] - qteact = create_python_script_action(self, - _("Qt examples"), 'qt.png', "PyQt4", - osp.join("examples", "demos", - "qtdemo", "qtdemo"), args) - for act in (qtdact, qtlact, qteact): + for act in (qtdact, qtlact): if act: additact.append(act) if additact and is_module_installed('winpython'): @@ -758,7 +733,7 @@ def create_edit_action(text, tr_text, icon): "guidata", osp.join("tests", "__init__")) gdgq_act += [guidata_act] - except (ImportError, AssertionError): + except: pass try: from guidata import configtools @@ -774,7 +749,7 @@ def create_edit_action(text, tr_text, icon): sift_icon, "guiqwt", osp.join("tests", "sift")) if sift_act: gdgq_act += [sift_act] - except (ImportError, AssertionError): + except: pass if gdgq_act: self.external_tools_menu_actions += [None] + gdgq_act @@ -941,25 +916,7 @@ def create_edit_action(text, tr_text, icon): triggered=self.check_updates) # Spyder documentation - doc_path = get_module_data_path('spyder', relpath="doc", - attr_name='DOCPATH') - # * Trying to find the chm doc - spyder_doc = osp.join(doc_path, "Spyderdoc.chm") - if not osp.isfile(spyder_doc): - spyder_doc = osp.join(doc_path, os.pardir, "Spyderdoc.chm") - # * Trying to find the html doc - if not osp.isfile(spyder_doc): - spyder_doc = osp.join(doc_path, "index.html") - # * Trying to find the development-version html doc - if not osp.isfile(spyder_doc): - spyder_doc = osp.join(get_module_source_path('spyder'), - os.pardir, 'build', 'lib', 'spyder', - 'doc', "index.html") - # * If we totally fail, point to our web build - if not osp.isfile(spyder_doc): - spyder_doc = 'https://docs.spyder-ide.org/' - else: - spyder_doc = file_uri(spyder_doc) + spyder_doc = 'https://docs.spyder-ide.org/' doc_action = create_action(self, _("Spyder documentation"), icon=ima.icon('DialogHelpButton'), triggered=lambda: @@ -2409,7 +2366,7 @@ def render_issue(self, description='', traceback=''): revision = versions['revision'] # Store and format the reminder message for the troubleshooting guide - reminder_message = ( + reminder_message_full = ( "" ).format(__trouble_url__) + reminder_message_short = ( + "" + ) + + bug_checklist = ( + "* [ ] Searched issues page for similar reports\n" + "* [ ] Read and followed relevant sections of the" + "[Troubleshooting Guide]({0!s})\n" + "* [ ] Reproduced after updating (`conda update spyder`)\n" + "* [ ] Tried basic troubleshooting\n" + " * [ ] Restarted Spyder\n" + " * [ ] Ran `spyder --reset`\n" + " * [ ] Reinstalled latest Anaconda\n" + ).format(__trouble_url_short__) + # Make a description header in case no description is supplied if not description: - description = "### What steps will reproduce the problem?" + description = "### What steps reproduce the problem?" - # Make error section from traceback + # Make error section from traceback and add appropriate reminder header if traceback: error_section = ("### Traceback\n" "```python-traceback\n" "{}\n" "```".format(traceback)) + reminder_message = reminder_message_full else: error_section = '' + reminder_message = reminder_message_short + "\n\n" + bug_checklist issue_template = """\ {reminder_message} -## Problem Description +## Description {description} {error_section} -## Package Versions +## Versions * Spyder version: {spyder_version} {commit} * Python version: {python_version} * Qt version: {qt_version} * {qt_api_name} version: {qt_api_version} -* Operating system: {os_name} {os_version} +* Operating System: {os_name} {os_version} ### Dependencies @@ -2496,13 +2471,13 @@ def report_issue(self, body=None, title=None): @Slot() def trouble_guide(self): - """Open Spyder troubleshooting guide in a web browser""" + """Open Spyder troubleshooting guide in a web browser.""" url = QUrl(__trouble_url__) QDesktopServices.openUrl(url) @Slot() def google_group(self): - """Open Spyder troubleshooting guide in a web browser""" + """Open Spyder Google Group in a web browser.""" url = QUrl(__forum_url__) QDesktopServices.openUrl(url) diff --git a/spyder/app/start.py b/spyder/app/start.py index ef3c88c05bc..b135f1bcdd9 100644 --- a/spyder/app/start.py +++ b/spyder/app/start.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # Std imports +import ctypes import os import os.path as osp import random @@ -12,10 +13,10 @@ # See issue 5324 import zmq -# This import is needed to fix errors with OpenGL when installed using pip -# See issue 3332 +# Load GL library to prevent segmentation faults on some Linux systems +# See issues 3226 and 3332 try: - from OpenGL import GL + ctypes.CDLL("libGL.so.1", mode=ctypes.RTLD_GLOBAL) except: pass @@ -96,8 +97,8 @@ def main(): os.environ['QT_SCALE_FACTOR'] = '' os.environ['QT_SCREEN_SCALE_FACTORS'] = '' - # Prevent Spyder from crashing in macOS if locale is not defined if sys.platform == 'darwin': + # Prevent Spyder from crashing in macOS if locale is not defined LANG = os.environ.get('LANG') LC_ALL = os.environ.get('LC_ALL') if bool(LANG) and not bool(LC_ALL): @@ -109,6 +110,20 @@ def main(): os.environ['LANG'] = LANG os.environ['LC_ALL'] = LC_ALL + else: + # Prevent our kernels to crash when Python fails to identify + # the system locale. + # Fixes issue 7051. + try: + from locale import getlocale + getlocale() + except ValueError: + # This can fail on Windows. See issue 6886 + try: + os.environ['LANG'] = 'C' + os.environ['LC_ALL'] = 'C' + except Exception: + pass if CONF.get('main', 'single_instance') and not options.new_instance \ and not options.reset_config_files and not running_in_mac_app(): diff --git a/spyder/app/tests/test_mainwindow.py b/spyder/app/tests/test_mainwindow.py index f46a4290533..797d4da3204 100644 --- a/spyder/app/tests/test_mainwindow.py +++ b/spyder/app/tests/test_mainwindow.py @@ -27,7 +27,7 @@ import numpy as np from numpy.testing import assert_array_equal import pytest -from qtpy import PYQT4, PYQT5, PYQT_VERSION +from qtpy import PYQT5, PYQT_VERSION from qtpy.QtCore import Qt, QTimer, QEvent, QUrl from qtpy.QtTest import QTest from qtpy.QtGui import QImage @@ -165,6 +165,14 @@ def main_window(request): else: CONF.set('main', 'single_instance', False) + # Get config values passed in parametrize and apply them + try: + param = request.param + if isinstance(param, dict) and 'spy_config' in param: + CONF.set(*param['spy_config']) + except AttributeError: + pass + # Start the window window = start.main() @@ -214,6 +222,37 @@ def test_calltip(main_window, qtbot): main_window.editor.close_file() +@pytest.mark.slow +@flaky(max_runs=3) +@pytest.mark.skipif(np.__version__ < '1.14.0', reason="This only happens in Numpy 1.14+") +@pytest.mark.parametrize('main_window', [{'spy_config': ('variable_explorer', 'minmax', True)}], indirect=True) +def test_filter_numpy_warning(main_window, qtbot): + """ + Test that we filter a warning shown when an array contains nan + values and the Variable Explorer option 'Show arrays min/man' + is on. + + For issue 7063 + """ + shell = main_window.ipyconsole.get_current_shellwidget() + control = shell._control + qtbot.waitUntil(lambda: shell._prompt_html is not None, + timeout=SHELL_TIMEOUT) + + # Create an array with a nan value + with qtbot.waitSignal(shell.executed): + shell.execute('import numpy as np; A=np.full(16, np.nan)') + + qtbot.wait(1000) + + # Assert that no warnings are shown in the console + assert "warning" not in control.toPlainText() + assert "Warning" not in control.toPlainText() + + # Restore default config value + CONF.set('variable_explorer', 'minmax', False) + + @pytest.mark.slow @flaky(max_runs=3) @pytest.mark.use_introspection @@ -320,8 +359,7 @@ def test_single_instance_and_edit_magic(main_window, qtbot, tmpdir): @pytest.mark.slow @flaky(max_runs=3) -@pytest.mark.skipif(os.name == 'nt' or PY2 or PYQT4, - reason="It fails sometimes") +@pytest.mark.skipif(os.name == 'nt' or PY2, reason="It fails sometimes") def test_move_to_first_breakpoint(main_window, qtbot): """Test that we move to the first breakpoint if there's one present.""" # Wait until the window is fully up diff --git a/spyder/config/base.py b/spyder/config/base.py index 25e2524f38c..93f345a417b 100644 --- a/spyder/config/base.py +++ b/spyder/config/base.py @@ -20,6 +20,8 @@ import os import shutil import sys +import getpass +import tempfile # Local imports from spyder.utils import encoding @@ -34,9 +36,9 @@ # SPYDER_DEV is (and *only* has to be) set in bootstrap.py DEV = os.environ.get('SPYDER_DEV') -# For testing purposes -# SPYDER_TEST can be set using the --test option of bootstrap.py -TEST = os.environ.get('SPYDER_TEST') +# Make Spyder use a temp clean configuration directory for testing purposes +# SPYDER_SAFE_MODE can be set using the --safe-mode option of bootstrap.py +SAFE_MODE = os.environ.get('SPYDER_SAFE_MODE') def running_under_pytest(): @@ -121,15 +123,27 @@ def get_home_dir(): raise RuntimeError('Please define environment variable $HOME') +def get_clean_conf_dir(): + """ + Return the path to a temp clean configuration dir, for tests and safe mode. + """ + if sys.platform.startswith("win"): + current_user = '' + else: + current_user = '-' + str(getpass.getuser()) + + conf_dir = osp.join(str(tempfile.gettempdir()), + 'pytest-spyder{0!s}'.format(current_user), + SUBFOLDER) + return conf_dir + + def get_conf_path(filename=None): - """Return absolute path for configuration file with specified filename""" + """Return absolute path to the config file with the specified filename.""" # Define conf_dir - if running_under_pytest(): - import py - from _pytest.tmpdir import get_user - conf_dir = osp.join(str(py.path.local.get_temproot()), - 'pytest-of-{}'.format(get_user()), - SUBFOLDER) + if running_under_pytest() or SAFE_MODE: + # Use clean config dir if running tests or the user requests it. + conf_dir = get_clean_conf_dir() elif sys.platform.startswith('linux'): # This makes us follow the XDG standard to save our settings # on Linux, as it was requested on Issue 2629 @@ -144,7 +158,7 @@ def get_conf_path(filename=None): # Create conf_dir if not osp.isdir(conf_dir): - if running_under_pytest(): + if running_under_pytest() or SAFE_MODE: os.makedirs(conf_dir) else: os.mkdir(conf_dir) @@ -152,7 +166,7 @@ def get_conf_path(filename=None): return conf_dir else: return osp.join(conf_dir, filename) - + def get_module_path(modname): """Return module *modname* base path""" @@ -348,13 +362,27 @@ def get_translation(modname, dirname=None): """Return translation callback for module *modname*""" if dirname is None: dirname = modname + + def translate_dumb(x): + """Dumb function to not use translations.""" + if not is_unicode(x): + return to_text_string(x, "utf-8") + return x + locale_path = get_module_data_path(dirname, relpath="locale", attr_name='LOCALEPATH') - # If LANG is defined in ubuntu, a warning message is displayed, so in unix - # systems we define the LANGUAGE variable. + + # If LANG is defined in Ubuntu, a warning message is displayed, + # so in Unix systems we define the LANGUAGE variable. language = load_lang_conf() if os.name == 'nt': - os.environ["LANG"] = language # Works on Windows + # Trying to set LANG on Windows can fail when Spyder is + # run with admin privileges. + # Fixes issue 6886 + try: + os.environ["LANG"] = language # Works on Windows + except Exception: + return translate_dumb else: os.environ["LANGUAGE"] = language # Works on Linux @@ -371,12 +399,7 @@ def translate_gettext(x): else: return to_text_string(y, "utf-8") return translate_gettext - except IOError as _e: # analysis:ignore - # Not using translations - def translate_dumb(x): - if not is_unicode(x): - return to_text_string(x, "utf-8") - return x + except Exception: return translate_dumb # Translation callback diff --git a/spyder/config/main.py b/spyder/config/main.py index 1a3d4fcc4aa..a5448959d97 100755 --- a/spyder/config/main.py +++ b/spyder/config/main.py @@ -12,21 +12,21 @@ """ import os -import sys import os.path as osp +import sys # Local import from spyder.config.base import (CHECK_ALL, EXCLUDED_NAMES, get_home_dir, - SUBFOLDER, TEST) + SUBFOLDER) from spyder.config.fonts import BIG, MEDIUM, MONOSPACE, SANS_SERIF from spyder.config.user import UserConfig from spyder.config.utils import IMPORT_EXT from spyder.utils import codeanalysis -#============================================================================== +# ============================================================================= # Main constants -#============================================================================== +# ============================================================================= # Find in files exclude patterns EXCLUDE_PATTERNS = [r'\.pyc$|\.pyo$|\.git'] @@ -629,9 +629,9 @@ ] -#============================================================================== +# ============================================================================= # Config instance -#============================================================================== +# ============================================================================= # IMPORTANT NOTES: # 1. If you want to *change* the default value of a current option, you need to # do a MINOR update in config version, e.g. from 3.0.0 to 3.1.0 @@ -643,10 +643,10 @@ # Main configuration instance try: - CONF = UserConfig('spyder', defaults=DEFAULTS, load=(not TEST), + CONF = UserConfig('spyder', defaults=DEFAULTS, load=True, version=CONF_VERSION, subfolder=SUBFOLDER, backup=True, raw_mode=True) -except: +except Exception: CONF = UserConfig('spyder', defaults=DEFAULTS, load=False, version=CONF_VERSION, subfolder=SUBFOLDER, backup=True, raw_mode=True) diff --git a/spyder/config/user.py b/spyder/config/user.py index 4734b261275..f23822e21e2 100644 --- a/spyder/config/user.py +++ b/spyder/config/user.py @@ -15,14 +15,14 @@ # Std imports import ast import os -import re import os.path as osp +import re import shutil import time # Local imports from spyder.config.base import (get_conf_path, get_home_dir, - get_module_source_path, TEST) + get_module_source_path) from spyder.utils.programs import check_version from spyder.py3compat import configparser as cp from spyder.py3compat import PY2, is_text_string, to_text_string @@ -92,10 +92,6 @@ def _save(self): """ Save config into the associated .ini file """ - # Don't save settings if we are on testing mode - if TEST: - return - # See Issue 1086 and 1242 for background on why this # method contains all the exception handling. fname = self.filename() @@ -110,10 +106,10 @@ def _write_file(fname): with open(fname, 'w', encoding='utf-8') as configfile: self.write(configfile) - try: # the "easy" way + try: # the "easy" way _write_file(fname) except IOError: - try: # the "delete and sleep" way + try: # the "delete and sleep" way if osp.isfile(fname): os.remove(fname) time.sleep(0.05) diff --git a/spyder/locale/fr/LC_MESSAGES/spyder.mo b/spyder/locale/fr/LC_MESSAGES/spyder.mo index 463bd51a43f..9a8e899dc8a 100644 Binary files a/spyder/locale/fr/LC_MESSAGES/spyder.mo and b/spyder/locale/fr/LC_MESSAGES/spyder.mo differ diff --git a/spyder/locale/fr/LC_MESSAGES/spyder.po b/spyder/locale/fr/LC_MESSAGES/spyder.po index 420c5d119b3..fb8f3ff6cd9 100644 --- a/spyder/locale/fr/LC_MESSAGES/spyder.po +++ b/spyder/locale/fr/LC_MESSAGES/spyder.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.1\n" "POT-Creation-Date: 2018-02-19 11:56+-05\n" -"PO-Revision-Date: 2018-02-21 23:36+0100\n" +"PO-Revision-Date: 2018-05-21 00:14-0500\n" "Last-Translator: Melaine Euzenat \n" "Language-Team: Python\n" "Language: fr\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: pygettext.py 1.5\n" -"X-Generator: Poedit 2.0.4\n" +"X-Generator: Poedit 2.0.7\n" #: spyder/app/mainwindow.py:134 msgid "Initializing..." @@ -1661,7 +1661,7 @@ msgstr "&Enregistrer" #: spyder/plugins/editor.py:673 spyder/widgets/editor.py:1672 msgid "Save file" -msgstr "Enregitrer un fichier" +msgstr "Enregistrer un fichier" #: spyder/plugins/editor.py:679 msgid "Sav&e all" diff --git a/spyder/plugins/ipythonconsole.py b/spyder/plugins/ipythonconsole.py index b98aeeff0d4..21bcdc863b6 100644 --- a/spyder/plugins/ipythonconsole.py +++ b/spyder/plugins/ipythonconsole.py @@ -20,6 +20,7 @@ import os.path as osp import uuid import sys +import traceback # Third party imports from jupyter_client.connect import find_connection_file @@ -77,6 +78,10 @@ dependencies.add("IPython", _("IPython interactive python environment"), required_version=IPYTHON_REQVER) +MATPLOTLIB_REQVER = '>=2.0.0' +dependencies.add("matplotlib", _("Display 2D graphics in the IPython Console"), + required_version=MATPLOTLIB_REQVER, optional=True) + #------------------------------------------------------------------------------ # Existing kernels #------------------------------------------------------------------------------ @@ -1533,7 +1538,7 @@ def create_kernel_manager_and_kernel_client(self, connection_file, # Kernel spec kernel_spec = self.create_kernel_spec(is_cython=is_cython) if not kernel_spec.env.get('PYTHONPATH'): - error_msg = _("This error was most probably caused by installing " + error_msg = _("This error is most probably caused by installing " "Spyder in a directory with non-ascii characters " "(i.e. characters with tildes, apostrophes or " "non-latin symbols).

" @@ -1542,8 +1547,13 @@ def create_kernel_manager_and_kernel_client(self, connection_file, return (error_msg, None) # Kernel manager - kernel_manager = QtKernelManager(connection_file=connection_file, - config=None, autorestart=True) + try: + kernel_manager = QtKernelManager(connection_file=connection_file, + config=None, autorestart=True) + except Exception as e: + error_msg = _("The error is:

" + "{}").format(traceback.format_exc()) + return (error_msg, None) kernel_manager._kernel_spec = kernel_spec # Save stderr in a file to read it later in case of errors diff --git a/spyder/plugins/tests/test_editor_introspection.py b/spyder/plugins/tests/test_editor_introspection.py index cb6d594be69..18cb1928a11 100644 --- a/spyder/plugins/tests/test_editor_introspection.py +++ b/spyder/plugins/tests/test_editor_introspection.py @@ -15,7 +15,6 @@ from unittest.mock import Mock except ImportError: from mock import Mock # Python 2 -from qtpy import PYQT4 from qtpy.QtWidgets import QWidget, QApplication from qtpy.QtCore import Qt diff --git a/spyder/plugins/tests/test_ipythonconsole.py b/spyder/plugins/tests/test_ipythonconsole.py index 06e6b457b93..6b17a86cbaa 100644 --- a/spyder/plugins/tests/test_ipythonconsole.py +++ b/spyder/plugins/tests/test_ipythonconsole.py @@ -24,7 +24,7 @@ import ipykernel from pygments.token import Name import pytest -from qtpy import PYQT4, PYQT5 +from qtpy import PYQT5 from qtpy.QtCore import Qt import zmq @@ -112,8 +112,7 @@ def close_console(): @pytest.mark.slow @flaky(max_runs=3) @pytest.mark.auto_backend -@pytest.mark.skipif(os.name == 'nt' or PYQT4, - reason="It times out sometimes on Windows and it's not needed in PyQt4") +@pytest.mark.skipif(os.name == 'nt', reason="It times out sometimes on Windows") @pytest.mark.xfail(zmq.__version__ >= '17.0.0' and ipykernel.__version__ <= "4.8.1", reason="A bug with pyzmq 17 and ipykernel 4.8.1") def test_auto_backend(ipyconsole, qtbot): @@ -630,7 +629,7 @@ def add(x, y): @pytest.mark.slow @flaky(max_runs=3) -@pytest.mark.skipif(os.name == 'nt' or (PY2 and PYQT5) or PYQT4, +@pytest.mark.skipif(os.name == 'nt' or (PY2 and PYQT5), reason="It times out frequently") def test_mpl_backend_change(ipyconsole, qtbot): """ diff --git a/spyder/requirements.py b/spyder/requirements.py index 49d9bb6cfc5..0bd8afc9840 100644 --- a/spyder/requirements.py +++ b/spyder/requirements.py @@ -34,7 +34,7 @@ def check_path(): def check_qt(): """Check Qt binding requirements""" - qt_infos = dict(pyqt5=("PyQt5", "5.2"), pyqt=("PyQt4", "4.6")) + qt_infos = dict(pyqt5=("PyQt5", "5.5")) try: import qtpy package_name, required_ver = qt_infos[qtpy.API] diff --git a/spyder/utils/dochelpers.py b/spyder/utils/dochelpers.py index d099b9ff154..6234714b2ba 100644 --- a/spyder/utils/dochelpers.py +++ b/spyder/utils/dochelpers.py @@ -174,7 +174,7 @@ def getsource(obj): def getsignaturefromtext(text, objname): """Get object signatures from text (object documentation) Return a list containing a single string in most cases - Example of multiple signatures: PyQt4 objects""" + Example of multiple signatures: PyQt5 objects""" if isinstance(text, dict): text = text.get('docstring', '') # Regexps @@ -242,7 +242,7 @@ def getargs(obj): if args is not None: return args else: - # Example: PyQt4 + # Example: PyQt5 return getargsfromdoc(obj) args, _, _ = inspect.getargs(func_obj.func_code) if not args: diff --git a/spyder/utils/help/sphinxify.py b/spyder/utils/help/sphinxify.py index 9145bed9af9..51ce8caf51c 100644 --- a/spyder/utils/help/sphinxify.py +++ b/spyder/utils/help/sphinxify.py @@ -166,15 +166,14 @@ def sphinxify(docstring, context, buildername='html'): srcdir = mkdtemp() srcdir = encoding.to_unicode_from_fs(srcdir) + destdir = osp.join(srcdir, '_build') - base_name = osp.join(srcdir, 'docstring') - rst_name = base_name + '.rst' - + rst_name = osp.join(srcdir, 'docstring.rst') if buildername == 'html': suffix = '.html' else: suffix = '.txt' - output_name = base_name + suffix + output_name = osp.join(destdir, 'docstring' + suffix) # This is needed so users can type \\ on latex eqnarray envs inside raw # docstrings @@ -208,7 +207,7 @@ def sphinxify(docstring, context, buildername='html'): doctreedir = osp.join(srcdir, 'doctrees') - sphinx_app = Sphinx(srcdir, confdir, srcdir, doctreedir, buildername, + sphinx_app = Sphinx(srcdir, confdir, destdir, doctreedir, buildername, confoverrides, status=None, warning=None, freshenv=True, warningiserror=False, tags=None) try: diff --git a/spyder/utils/introspection/utils.py b/spyder/utils/introspection/utils.py index d805bbe8a4c..c1b43b2b9b5 100644 --- a/spyder/utils/introspection/utils.py +++ b/spyder/utils/introspection/utils.py @@ -21,10 +21,8 @@ ) from pygments.lexer import words -from pygments.lexers import ( - get_lexer_for_filename, get_lexer_by_name, TextLexer -) -from pygments.util import ClassNotFound +from pygments.lexers import (get_lexer_for_filename, get_lexer_by_name, + TextLexer) from pygments.token import Token @@ -178,7 +176,7 @@ def find_lexer_for_filename(filename): else: try: lexer = get_lexer_for_filename(filename) - except ClassNotFound: + except Exception: return TextLexer() return lexer diff --git a/spyder/utils/ipython/kernelspec.py b/spyder/utils/ipython/kernelspec.py index a8220b38f11..6a73ff52a0e 100644 --- a/spyder/utils/ipython/kernelspec.py +++ b/spyder/utils/ipython/kernelspec.py @@ -13,7 +13,8 @@ from jupyter_client.kernelspec import KernelSpec -from spyder.config.base import get_module_source_path +from spyder.config.base import (SAFE_MODE, get_module_source_path, + running_under_pytest) from spyder.config.main import CONF from spyder.utils.encoding import to_unicode_from_fs from spyder.utils.programs import is_python_interpreter @@ -128,7 +129,8 @@ def env(self): '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_RUN_CYTHON': self.is_cython + 'SPY_RUN_CYTHON': self.is_cython, + 'SPY_TESTING': running_under_pytest() or SAFE_MODE } # Add our PYTHONPATH to env_vars diff --git a/spyder/utils/ipython/start_kernel.py b/spyder/utils/ipython/start_kernel.py index 112a961cad4..2fcb8d763b4 100644 --- a/spyder/utils/ipython/start_kernel.py +++ b/spyder/utils/ipython/start_kernel.py @@ -66,13 +66,17 @@ def kernel_config(): # ---- Spyder config ---- spy_cfg = Config() + # Enable/disable certain features for testing + testing = os.environ.get('SPY_TESTING') == 'True' + if testing: + # Don't load nor save history in our IPython consoles. + spy_cfg.HistoryAccessor.enabled = False + # Until we implement Issue 1052 spy_cfg.InteractiveShell.xmode = 'Plain' - # Jedi completer + # Jedi completer. It's only available in Python 3 jedi_o = os.environ.get('SPY_JEDI_O') == 'True' - # - Using Jedi slow completions a lot for objects with big repr's. - # - Jedi completions are not available in Python 2. if not PY2: spy_cfg.IPCompleter.use_jedi = jedi_o diff --git a/spyder/utils/site/sitecustomize.py b/spyder/utils/site/sitecustomize.py index 431e648b6ef..08857d24afe 100644 --- a/spyder/utils/site/sitecustomize.py +++ b/spyder/utils/site/sitecustomize.py @@ -305,6 +305,21 @@ def __init__(self, *args, **kwargs): pass +# ============================================================================= +# Numpy adjustments +# ============================================================================= +try: + # Filter warning that appears when users have 'Show max/min' + # turned on and Numpy arrays contain a nan value. + # Fixes Issue 7063 + # Note: It only happens in Numpy 1.14+ + warnings.filterwarnings(action='ignore', category=RuntimeWarning, + module='numpy.core._methods', + message=".*invalid value encountered in.*") +except: + pass + + #============================================================================== # Pdb adjustments #============================================================================== @@ -540,7 +555,13 @@ def __init__(self, namelist=None, pathlist=None): namelist = [] spy_modules = ['sitecustomize', 'spyder', 'spyderplugins'] mpl_modules = ['matplotlib', 'tkinter', 'Tkinter'] - self.namelist = namelist + spy_modules + mpl_modules + # Add other, necessary modules to the UMR blacklist + # astropy: see issue 6962 + # pytorch: see issue 7041 + other_modules = ['pytorch'] + if PY2: + other_modules.append('astropy') + self.namelist = namelist + spy_modules + mpl_modules + other_modules if pathlist is None: pathlist = [] diff --git a/spyder/widgets/editor.py b/spyder/widgets/editor.py index 080dfb5a5a0..abf53cd47be 100644 --- a/spyder/widgets/editor.py +++ b/spyder/widgets/editor.py @@ -19,7 +19,6 @@ from collections import MutableSequence # Third party imports -from qtpy import is_pyqt46 from qtpy.compat import getsavefilename from qtpy.QtCore import (QByteArray, QFileInfo, QObject, QPoint, QSize, Qt, QThread, QTimer, Signal, Slot) @@ -802,8 +801,6 @@ def closeEvent(self, event): self.outlineexplorer.remove_editor(finfo.editor) QWidget.closeEvent(self, event) - if is_pyqt46: - self.destroyed.emit() def clone_editor_from(self, other_finfo, set_current): fname = other_finfo.filename @@ -2441,8 +2438,6 @@ def __init__(self, parent, plugin, menu_actions, first=False, def closeEvent(self, event): QSplitter.closeEvent(self, event) - if is_pyqt46: - self.destroyed.emit() def __give_focus_to_remaining_editor(self): focus_widget = self.plugin.get_focus_widget() @@ -2727,12 +2722,6 @@ def resizeEvent(self, event): def closeEvent(self, event): """Reimplement Qt method""" QMainWindow.closeEvent(self, event) - if is_pyqt46: - self.destroyed.emit() - for editorstack in self.editorwidget.editorstacks[:]: - if DEBUG_EDITOR: - print("--> destroy_editorstack:", editorstack, file=STDOUT) - editorstack.destroyed.emit() def get_layout_settings(self): """Return layout state""" diff --git a/spyder/widgets/explorer.py b/spyder/widgets/explorer.py index 344cb86a854..2c114c5ffec 100644 --- a/spyder/widgets/explorer.py +++ b/spyder/widgets/explorer.py @@ -22,7 +22,6 @@ import mimetypes as mime # Third party imports -from qtpy import API, is_pyqt46 from qtpy.compat import getsavefilename, getexistingdirectory from qtpy.QtCore import (QDir, QFileInfo, QMimeData, QSize, QSortFilterProxyModel, Qt, QTimer, QUrl, @@ -207,9 +206,8 @@ def install_model(self): def setup_view(self): """Setup view""" self.install_model() - if not is_pyqt46: - self.fsmodel.directoryLoaded.connect( - lambda: self.resizeColumnToContents(0)) + self.fsmodel.directoryLoaded.connect( + lambda: self.resizeColumnToContents(0)) self.setAnimated(False) self.setSortingEnabled(True) self.sortByColumn(0, Qt.AscendingOrder) @@ -477,8 +475,13 @@ def viewportEvent(self, event): def contextMenuEvent(self, event): """Override Qt method""" - self.update_menu() - self.menu.popup(event.globalPos()) + # Needed to handle not initialized menu. + # See issue 6975 + try: + self.update_menu() + self.menu.popup(event.globalPos()) + except AttributeError: + pass def keyPressEvent(self, event): """Reimplement Qt method""" @@ -884,7 +887,7 @@ def restore_directory_state(self, fname): self._to_be_loaded = [] self._to_be_loaded.append(path) self.setExpanded(self.get_index(path), True) - if not self.__expanded_state and not is_pyqt46: + if not self.__expanded_state: self.fsmodel.directoryLoaded.disconnect(self.restore_directory_state) def follow_directories_loaded(self, fname): @@ -894,8 +897,7 @@ def follow_directories_loaded(self, fname): path = osp.normpath(to_text_string(fname)) if path in self._to_be_loaded: self._to_be_loaded.remove(path) - if self._to_be_loaded is not None and len(self._to_be_loaded) == 0 \ - and not is_pyqt46: + if self._to_be_loaded is not None and len(self._to_be_loaded) == 0: self.fsmodel.directoryLoaded.disconnect( self.follow_directories_loaded) if self._scrollbar_positions is not None: @@ -906,7 +908,7 @@ def restore_expanded_state(self): """Restore all items expanded state""" if self.__expanded_state is not None: # In the old project explorer, the expanded state was a dictionnary: - if isinstance(self.__expanded_state, list) and not is_pyqt46: + if isinstance(self.__expanded_state, list): self.fsmodel.directoryLoaded.connect( self.restore_directory_state) self.fsmodel.directoryLoaded.connect( diff --git a/spyder/widgets/ipythonconsole/client.py b/spyder/widgets/ipythonconsole/client.py index 593aac03a3c..8e8a2c5a716 100644 --- a/spyder/widgets/ipythonconsole/client.py +++ b/spyder/widgets/ipythonconsole/client.py @@ -436,7 +436,12 @@ def set_infowidget_font(self): def set_color_scheme(self, color_scheme, reset=True): """Set IPython color scheme.""" - self.shellwidget.set_color_scheme(color_scheme, reset) + # Needed to handle not initialized kernel_client + # See issue 6996 + try: + self.shellwidget.set_color_scheme(color_scheme, reset) + except AttributeError: + pass def shutdown(self): """Shutdown kernel""" diff --git a/spyder/widgets/sourcecode/codeeditor.py b/spyder/widgets/sourcecode/codeeditor.py index 8ffdcfb8b36..d7b1f95fce1 100644 --- a/spyder/widgets/sourcecode/codeeditor.py +++ b/spyder/widgets/sourcecode/codeeditor.py @@ -27,7 +27,7 @@ import time # Third party imports -from qtpy import is_pyqt46, QT_VERSION +from qtpy import QT_VERSION from qtpy.compat import to_qvariant from qtpy.QtCore import QRect, QRegExp, QSize, Qt, QTimer, Signal, Slot from qtpy.QtGui import (QBrush, QColor, QCursor, QFont, QIntValidator, @@ -668,8 +668,6 @@ def get_shortcut_data(self): def closeEvent(self, event): TextEditBaseWidget.closeEvent(self, event) - if is_pyqt46: - self.destroyed.emit() def get_document_id(self): return self.document_id diff --git a/spyder/widgets/tests/test_pathmanager.py b/spyder/widgets/tests/test_pathmanager.py index 5d418fe6927..922dabc68e8 100644 --- a/spyder/widgets/tests/test_pathmanager.py +++ b/spyder/widgets/tests/test_pathmanager.py @@ -13,7 +13,6 @@ # Test library imports import pytest -from qtpy import PYQT4 from qtpy.QtCore import Qt # Local imports @@ -32,7 +31,6 @@ def setup_pathmanager(qtbot, parent=None, pathlist=None, ro_pathlist=None, return widget -@pytest.mark.skipif(PY3 and PYQT4, reason="It segfaults frequently") def test_pathmanager(qtbot): """Run PathManager test""" pathmanager = setup_pathmanager(qtbot, None, pathlist=sys.path[:-10], diff --git a/spyder/widgets/variableexplorer/tests/test_dataframeeditor.py b/spyder/widgets/variableexplorer/tests/test_dataframeeditor.py index 1317c3baccd..435f3621da3 100644 --- a/spyder/widgets/variableexplorer/tests/test_dataframeeditor.py +++ b/spyder/widgets/variableexplorer/tests/test_dataframeeditor.py @@ -23,7 +23,6 @@ # Third party imports from pandas import DataFrame, date_range, read_csv, concat -from qtpy import PYQT4 from qtpy.QtGui import QColor from qtpy.QtCore import Qt, QTimer import numpy