Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PR: Compatibility changes for Spyder 4 #218

Merged
merged 6 commits into from
Oct 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 14 additions & 17 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,42 @@ version: 2

main: &main
machine: true
environment:
# Used by qthelpers to close widgets after a defined time
- TEST_CI: "True"
- TEST_CI_APP: "True"
steps:
- checkout
- run:
command: docker pull dorowu/ubuntu-desktop-lxde-vnc:trusty
- run:
name: Install required pachages
command: ./.circleci/install.sh
name: Install system packages
command: |
sudo apt-get -qq update
sudo apt-get install -q libegl1-mesa
- run:
command: bash ./continuous_integration/circle/install.sh
- run:
name: Run tests
command: ./.circleci/run-tests.sh
command: bash ./continuous_integration/circle/run_tests.sh
- run:
command: bash ./continuous_integration/circle/coverage.sh

jobs:
python2.7:
<<: *main
environment:
- PYTHON_VERSION: 2.7
SPYDER_BRANCH: 3.x
- PYTHON_VERSION: "2.7"

python3.6:
<<: *main
environment:
- PYTHON_VERSION: 3.6
SPYDER_BRANCH: 3.x
- PYTHON_VERSION: "3.6"

python3.7_spyder4:
python3.7:
<<: *main
environment:
- PYTHON_VERSION: 3.7
SPYDER_BRANCH: master

- PYTHON_VERSION: "3.7"

workflows:
version: 2
build_and_test:
jobs:
- python2.7
- python3.6
- python3.7_spyder4
- python3.7
43 changes: 0 additions & 43 deletions .circleci/install.sh

This file was deleted.

12 changes: 0 additions & 12 deletions .circleci/run-tests.sh

This file was deleted.

30 changes: 30 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# https://travis-ci.org/spyder-ide/spyder-notebook

language: generic
dist: xenial
services:
- xvfb

matrix:
fast_finish: true
include:
- env: PYTHON_VERSION=2.7 USE_CONDA=yes
- env: PYTHON_VERSION=3.6 USE_CONDA=yes
- env: PYTHON_VERSION=3.7 USE_CONDA=yes

before_install:
# Avoid annoying focus problems when running tests
# See discussion in e.g. https://github.com/spyder-ide/spyder/pull/6132
- sudo apt-get -qq update
- sudo apt-get install -y matchbox-window-manager xterm libxkbcommon-x11-0
- matchbox-window-manager&
- sleep 5

install:
- ./continuous_integration/circle/install.sh

script:
- ./continuous_integration/circle/run_tests.sh

after_success:
- ./continuous_integration/circle/coverage.sh
7 changes: 7 additions & 0 deletions continuous_integration/circle/coverage.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

export COVERALLS_REPO_TOKEN=Kr503QwklmJYKXYRXLywrtw8zbX7K8SKx
source $HOME/miniconda/etc/profile.d/conda.sh
conda activate test

coveralls
29 changes: 29 additions & 0 deletions continuous_integration/circle/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash -ex

# -- Install Miniconda
MINICONDA=Miniconda3-latest-Linux-x86_64.sh
wget https://repo.continuum.io/miniconda/$MINICONDA -O miniconda.sh
bash miniconda.sh -b -p $HOME/miniconda
source $HOME/miniconda/etc/profile.d/conda.sh


# -- Make new conda environment with required Python version
conda create -y -n test python=$PYTHON_VERSION
conda activate test


# -- Install dependencies

# Avoid problems with invalid SSL certificates
if [ "$PYTHON_VERSION" = "2.7" ]; then
conda install -q -y python=2.7.16=h9bab390_0
fi

# Install nomkl to avoid installing Intel MKL libraries
conda install -q -y nomkl

# Install main dependencies
conda install -q -y -c spyder-ide --file requirements/conda.txt

# Install test ones
conda install -q -y -c spyder-ide --file requirements/tests.txt
7 changes: 7 additions & 0 deletions continuous_integration/circle/run_tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

source $HOME/miniconda/etc/profile.d/conda.sh
conda activate test

# Run tests
pytest -x -vv --cov=spyder_notebook spyder_notebook
2 changes: 2 additions & 0 deletions requirements/conda.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
notebook
spyder >=4.0.0b5
6 changes: 6 additions & 0 deletions requirements/tests.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
coveralls
flaky
pytest
pytest-cov
pytest-mock
pytest-qt
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def get_version(module='spyder_notebook'):
return version


REQUIREMENTS = ['spyder>=3.2.0', 'notebook>=4.3',
REQUIREMENTS = ['spyder>=4', 'notebook>=4.3',
'qtpy', 'requests', 'psutil', 'nbformat']

setup(
Expand Down
100 changes: 61 additions & 39 deletions spyder_notebook/notebookplugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,15 @@
import nbformat

# Spyder imports
from spyder.api.plugins import SpyderPluginWidget
from spyder.config.base import _
from spyder.config.main import CONF
from spyder.utils import icon_manager as ima
from spyder.utils.programs import get_temp_dir
from spyder.utils.qthelpers import (create_action, create_toolbutton,
add_actions, MENU_SEPARATOR)
from spyder.utils.switcher import shorten_paths
from spyder.widgets.tabs import Tabs

try:
# Spyder >= 3.3.2
from spyder.utils.programs import get_temp_dir
except ImportError:
# Spyder < 3.3.2
from spyder.utils.programs import TEMPDIR

def get_temp_dir():
return TEMPDIR
try:
# Spyder 4
from spyder.api.plugins import SpyderPluginWidget
except ImportError:
# Spyder 3
from spyder.plugins import SpyderPluginWidget

# Local imports
from .utils.nbopen import nbopen, NBServerError
Expand All @@ -65,6 +52,9 @@ class NotebookPlugin(SpyderPluginWidget):

def __init__(self, parent, testing=False):
"""Constructor."""
if testing:
self.CONF_FILE = False

SpyderPluginWidget.__init__(self, parent)
self.testing = testing

Expand All @@ -80,21 +70,17 @@ def __init__(self, parent, testing=False):
self.recent_notebook_menu = QMenu(_("Open recent"), self)
self.options_menu = QMenu(self)

# Initialize plugin
self.initialize_plugin()

layout = QVBoxLayout()

new_notebook_btn = create_toolbutton(self,
icon=ima.icon('project_expanded'),
icon=ima.icon('options_more'),
tip=_('Open a new notebook'),
triggered=self.create_new_client)
menu_btn = create_toolbutton(self, icon=ima.icon('tooloptions'),
tip=_('Options'))

menu_btn.setMenu(self.options_menu)
menu_btn.setPopupMode(menu_btn.InstantPopup)
add_actions(self.options_menu, self.menu_actions)
corner_widgets = {Qt.TopRightCorner: [new_notebook_btn, menu_btn]}
self.tabwidget = Tabs(self, menu=self.options_menu,
actions=self.menu_actions,
Expand Down Expand Up @@ -192,13 +178,17 @@ def get_plugin_actions(self):

def register_plugin(self):
"""Register plugin in Spyder's main window."""
super(NotebookPlugin, self).register_plugin()
self.focus_changed.connect(self.main.plugin_focus_changed)
self.main.add_dockwidget(self)
self.ipyconsole = self.main.ipyconsole
self.create_new_client(give_focus=False)
icon_path = os.path.join(PACKAGE_PATH, 'images', 'icon.svg')
self.main.add_to_fileswitcher(self, self.tabwidget, self.clients,
QIcon(icon_path))

# Connect to switcher
self.switcher = self.main.switcher
self.switcher.sig_mode_selected.connect(self.handle_switcher_modes)
self.switcher.sig_item_selected.connect(
self.handle_switcher_selection)

self.recent_notebook_menu.aboutToShow.connect(self.setup_menu_actions)

def check_compatibility(self):
Expand Down Expand Up @@ -321,8 +311,8 @@ def create_new_client(self, filename=None, give_focus=True):
# Save spyder_pythonpath before creating a client
# because it's needed by our kernel spec.
if not self.testing:
CONF.set('main', 'spyder_pythonpath',
self.main.get_spyder_pythonpath())
self.set_option('main/spyder_pythonpath',
self.main.get_spyder_pythonpath())

# Open the notebook with nbopen and get the url we need to render
try:
Expand Down Expand Up @@ -461,23 +451,55 @@ def add_tab(self, widget):
index = self.tabwidget.addTab(widget, widget.get_short_name())
self.tabwidget.setCurrentIndex(index)
self.tabwidget.setTabToolTip(index, widget.get_filename())
if self.dockwidget and not self.ismaximized:
self.dockwidget.setVisible(True)
self.dockwidget.raise_()
if self.dockwidget:
self.switch_to_plugin()
self.activateWindow()
widget.notebookwidget.setFocus()

def move_tab(self, index_from, index_to):
"""Move tab."""
client = self.clients.pop(index_from)
self.clients.insert(index_to, client)

# ------ Public API (for FileSwitcher) ------------------------------------
def set_stack_index(self, index, instance):
"""Set the index of the current notebook."""
if instance == self:
self.tabwidget.setCurrentIndex(index)

def get_current_tab_manager(self):
"""Get the widget with the TabWidget attribute."""
return self
def handle_switcher_modes(self, mode):
"""
Populate switcher with opened notebooks.

List the file names of the opened notebooks with their directories in
the switcher. Only handle file mode, where `mode` is empty string.
"""
if mode != '':
return

paths = [client.get_filename() for client in self.clients]
is_unsaved = [False for client in self.clients]
short_paths = shorten_paths(paths, is_unsaved)
icon = QIcon(os.path.join(PACKAGE_PATH, 'images', 'icon.svg'))
section = self.get_plugin_title()

for path, short_path, client in zip(paths, short_paths, self.clients):
title = osp.basename(path)
description = osp.dirname(path)
if len(path) > 75:
description = short_path
is_last_item = (client == self.clients[-1])
self.switcher.add_item(
title=title, description=description, icon=icon,
section=section, data=client, last_item=is_last_item)

def handle_switcher_selection(self, item, mode, search_text):
"""
Handle user selecting item in switcher.

If the selected item is not in the section of the switcher that
corresponds to this plugin, then ignore it. Otherwise, switch to
selected item in notebook plugin and hide the switcher.
"""
if item.get_section() != self.get_plugin_title():
return

client = item.get_data()
index = self.clients.index(client)
self.tabwidget.setCurrentIndex(index)
self.switch_to_plugin()
self.switcher.hide()
1 change: 0 additions & 1 deletion spyder_notebook/tests/test_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ def notebook(qtbot):
notebook_plugin = NotebookPlugin(None, testing=True)
qtbot.addWidget(notebook_plugin)
notebook_plugin.create_new_client()
notebook_plugin.show()
return notebook_plugin


Expand Down
Loading