Skip to content

Commit

Permalink
Merge branch '4.x' into separate_cmd_input
Browse files Browse the repository at this point in the history
  • Loading branch information
Quentin Peter committed Jul 24, 2020
2 parents b12d6e5 + b12e8a3 commit 3698b89
Show file tree
Hide file tree
Showing 11 changed files with 410 additions and 134 deletions.
3 changes: 3 additions & 0 deletions .github/scripts/modules_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ for f in spyder/*/*.py; do
if [[ $f == spyder/widgets/switcher.py ]]; then
continue
fi
if [[ $f == spyder/widgets/about.py ]]; then
continue
fi
python "$f"
if [ $? -ne 0 ]; then
exit 1
Expand Down
124 changes: 6 additions & 118 deletions spyder/app/mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -1150,7 +1150,7 @@ def add_ipm_action(text, path):
about_action = create_action(self,
_("About %s...") % "Spyder",
icon=ima.icon('MessageBoxInformation'),
triggered=self.about)
triggered=self.show_about)
self.help_menu_actions += [MENU_SEPARATOR, about_action]

# Status bar widgets
Expand Down Expand Up @@ -2672,123 +2672,11 @@ def add_to_toolbar(self, toolbar, widget):
add_actions(toolbar, actions)

@Slot()
def about(self):
"""Create About Spyder dialog with general information."""
versions = get_versions()
# Show Git revision for development version
revlink = ''
if versions['revision']:
rev = versions['revision']
revlink = " (<a href='https://github.com/spyder-ide/spyder/"\
"commit/%s'>Commit: %s</a>)" % (rev, rev)

# Get current font properties
font = self.font()
font_family = font.family()
font_size = font.pointSize()
if sys.platform == 'darwin':
font_size -= 2

msgBox = QMessageBox(self)
msgBox.setText(
"""
<div style='font-family: "{font_family}";
font-size: {font_size}pt;
font-weight: normal;
'>
<p>
<b>Spyder {spyder_ver}</b> {revision}
<br>
The Scientific Python Development Environment |
<a href="{website_url}">Spyder-IDE.org</a>
<br>
Copyright &copy; 2009-2019 Spyder Project Contributors and
<a href="{github_url}/blob/master/AUTHORS.txt">others</a>.
<br>
Distributed under the terms of the
<a href="{github_url}/blob/master/LICENSE.txt">MIT License</a>.
</p>
<p>
Created by Pierre Raybaut; current maintainer is Carlos Cordoba.
Developed by the
<a href="{github_url}/graphs/contributors">international
Spyder community</a>. Many thanks to all the Spyder beta testers
and dedicated users.
</p>
<p>For help with Spyder errors and crashes, please read our
<a href="{trouble_url}">Troubleshooting Guide</a>, and for bug
reports and feature requests, visit our
<a href="{github_url}">Github site</a>. For project discussion,
see our <a href="{forum_url}">Google Group</a>.
</p>
<p>
This project is part of a larger effort to promote and
facilitate the use of Python for scientific and engineering
software development.
The popular Python distributions
<a href="https://www.anaconda.com/download/">Anaconda</a> and
<a href="https://winpython.github.io/">WinPython</a>
also contribute to this plan.
</p>
<p>
Python {python_ver} {bitness}-bit | Qt {qt_ver} |
{qt_api} {qt_api_ver} | {os_name} {os_ver}
</p>
<p><small>Certain source files under other compatible permissive
licenses and/or originally by other authors.
Spyder 3 theme icons derived from
<a href="https://fontawesome.com/">Font Awesome</a> 4.7
(&copy; 2016 David Gandy; SIL OFL 1.1) and
<a href="http://materialdesignicons.com/">Material Design</a>
(&copy; 2014 Austin Andrews; SIL OFL 1.1).
Most Spyder 2 theme icons sourced from the
<a href="https://www.everaldo.com">Crystal Project iconset</a>
(&copy; 2006-2007 Everaldo Coelho; LGPL 2.1+).
Other icons from
<a href="http://p.yusukekamiyamane.com/">Yusuke Kamiyamane</a>
(&copy; 2013 Yusuke Kamiyamane; CC-BY 3.0),
the <a href="http://www.famfamfam.com/lab/icons/silk/">FamFamFam
Silk icon set</a> 1.3 (&copy; 2006 Mark James; CC-BY 2.5), and
the <a href="https://www.kde.org/">KDE Oxygen icons</a>
(&copy; 2007 KDE Artists; LGPL 3.0+).</small>
</p>
<p>
See the <a href="{github_url}/blob/master/NOTICE.txt">NOTICE</a>
file for full legal information.
</p>
</div>
""".format(
spyder_ver=versions['spyder'],
revision=revlink,
website_url=__website_url__,
github_url=__project_url__,
trouble_url=__trouble_url__,
forum_url=__forum_url__,
python_ver=versions['python'],
bitness=versions['bitness'],
qt_ver=versions['qt'],
qt_api=versions['qt_api'],
qt_api_ver=versions['qt_api_ver'],
os_name=versions['system'],
os_ver=versions['release'],
font_family=font_family,
font_size=font_size,
)
)
msgBox.setWindowTitle(_("About %s") % "Spyder")
msgBox.setStandardButtons(QMessageBox.Ok)

from spyder.config.gui import is_dark_interface
if is_dark_interface():
icon_filename = "spyder.svg"
else:
icon_filename = "spyder_dark.svg"
app_icon = QIcon(get_image_path(icon_filename))
msgBox.setIconPixmap(app_icon.pixmap(QSize(64, 64)))

msgBox.setTextInteractionFlags(
Qt.LinksAccessibleByMouse | Qt.TextSelectableByMouse)
msgBox.exec_()
def show_about(self):
"""Show About Spyder dialog box"""
from spyder.widgets.about import AboutDialog
abt = AboutDialog(self)
abt.exec_()

@Slot()
def show_dependencies(self):
Expand Down
20 changes: 19 additions & 1 deletion spyder/plugins/ipythonconsole/confpage.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,23 @@ def setup_page(self):
run_lines_layout.addWidget(run_lines_edit)
run_lines_group.setLayout(run_lines_layout)

# Pdb run lines Group
pdb_run_lines_group = QGroupBox(_("Run code while debugging"))
pdb_run_lines_label = QLabel(_(
"You can run several lines of code on each "
"new prompt while debugging. Please "
"introduce each one separated by semicolons "
"and a space, for example:<br>"
"<i>import matplotlib.pyplot as plt</i>"))
pdb_run_lines_label.setWordWrap(True)
pdb_run_lines_edit = self.create_lineedit(
_("Lines:"), 'startup/pdb_run_lines', '', alignment=Qt.Horizontal)

pdb_run_lines_layout = QVBoxLayout()
pdb_run_lines_layout.addWidget(pdb_run_lines_label)
pdb_run_lines_layout.addWidget(pdb_run_lines_edit)
pdb_run_lines_group.setLayout(pdb_run_lines_layout)

# Run file Group
run_file_group = QGroupBox(_("Run a file"))
run_file_label = QLabel(_("You can also run a whole file at startup "
Expand Down Expand Up @@ -374,7 +391,8 @@ def setup_page(self):
source_code_group), _("Display"))
tabs.addTab(self.create_tab(pylab_group, backend_group, inline_group),
_("Graphics"))
tabs.addTab(self.create_tab(run_lines_group, run_file_group),
tabs.addTab(self.create_tab(run_lines_group, pdb_run_lines_group,
run_file_group),
_("Startup"))
tabs.addTab(self.create_tab(jedi_group, greedy_group, autocall_group,
sympy_group, prompts_group,
Expand Down
26 changes: 26 additions & 0 deletions spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py
Original file line number Diff line number Diff line change
Expand Up @@ -1719,6 +1719,32 @@ def test_stderr_poll(ipyconsole, qtbot):
assert "test_test" in ipyconsole.get_focus_widget().toPlainText()


@pytest.mark.slow
@pytest.mark.use_startup_wdir
def test_startup_code_pdb(ipyconsole, qtbot):
"""Test that startup code for pdb works."""
shell = ipyconsole.get_current_shellwidget()
qtbot.waitUntil(lambda: shell._prompt_html is not None,
timeout=SHELL_TIMEOUT)

# Give focus to the widget that's going to receive clicks
control = ipyconsole.get_focus_widget()
control.setFocus()

# Run a line on startup
CONF.set('ipython_console', 'startup/pdb_run_lines',
'abba = 12; print("Hello")')

shell.execute('%debug print()')
qtbot.waitUntil(lambda: 'Hello' in control.toPlainText())

# Verify that the line was executed
assert shell.get_value('abba') == 12

# Reset setting
CONF.set('ipython_console', 'startup/pdb_run_lines', '')


@flaky(max_runs=3)
@pytest.mark.parametrize(
"backend",
Expand Down
7 changes: 7 additions & 0 deletions spyder/plugins/ipythonconsole/widgets/debugging.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,13 @@ def pdb_input(self, prompt, password=None):

self._pdb_input_ready = True

start_line = CONF.get('ipython_console', 'startup/pdb_run_lines', '')
# Only run these lines when printing a new prompt
if start_line and print_prompt and self.is_waiting_pdb_input():
# Send a few commands
self.pdb_execute(start_line, hidden=True)
return

# While the widget thinks only one input is going on,
# other functions can be sending messages to the kernel.
# This must be properly processed to avoid dropping messages.
Expand Down
9 changes: 7 additions & 2 deletions spyder/plugins/plots/widgets/figurebrowser.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,17 @@ def save_figure_tofile(fig, fmt, fname):
f.write(fig)


def get_unique_figname(dirname, root, ext):
def get_unique_figname(dirname, root, ext, start_at_zero=False):
"""
Append a number to "root" to form a filename that does not already exist
in "dirname".
"""
i = 1
figname = '{}{}'.format(root, ext)
if start_at_zero:
i = 0
figname = '{} ({}){}'.format(root, i, ext)

while True:
if osp.exists(osp.join(dirname, figname)):
figname = '{} ({}){}'.format(root, i, ext)
Expand Down Expand Up @@ -762,7 +766,8 @@ def save_all_figures_todir(self, dirname):
'image/jpeg': '.jpg',
'image/svg+xml': '.svg'}[fmt]

figname = get_unique_figname(dirname, figname_root, fext)
figname = get_unique_figname(dirname, figname_root, fext,
start_at_zero=True)
save_figure_tofile(fig, fmt, figname)
fignames.append(figname)
return fignames
Expand Down
29 changes: 29 additions & 0 deletions spyder/plugins/plots/widgets/tests/test_plots_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# Standard library imports
from __future__ import division
import os.path as osp
import datetime
try:
from unittest.mock import Mock
except ImportError:
Expand All @@ -30,6 +31,7 @@
# Local imports
from spyder.plugins.plots.widgets.figurebrowser import (FigureBrowser,
FigureThumbnail)
from spyder.plugins.plots.widgets.figurebrowser import get_unique_figname
from spyder.py3compat import to_text_string


Expand Down Expand Up @@ -176,6 +178,33 @@ def test_save_all_figures(figbrowser, tmpdir, mocker, fmt):
assert expected_qpix.toImage() == saved_qpix.toImage()


def test_get_unique_figname(tmpdir):
"""
Test that the unique fig names work when saving only one and when
saving multiple figures.
"""
fext = '.png'
# Saving only one figure
figname_root = ('Figure ' +
datetime.datetime.now().strftime('%Y-%m-%d %H%M%S'))
figname = get_unique_figname(tmpdir, figname_root, fext)
expected = osp.join(tmpdir, '{}{}'.format(figname_root, fext))
assert figname == expected

# Saving multiple figures
figname_root = ('Figure ' +
datetime.datetime.now().strftime('%Y-%m-%d %H%M%S'))
for i in range(5):
figname = get_unique_figname(tmpdir, figname_root, fext,
start_at_zero=True)
# Create empty file with figname
with open(figname, 'w') as _:
pass

expected = osp.join(tmpdir, '{} ({}){}'.format(figname_root, i, fext))
assert figname == expected


@pytest.mark.parametrize("fmt", ['image/png', 'image/svg+xml'])
def test_close_current_figure(figbrowser, tmpdir, fmt):
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@ def test_arrayeditor_edit_2d_array(qtbot):
assert np.sum(diff_arr != dlg.get_value()) == 2


@pytest.mark.skipif(
sys.platform.startswith('linux'),
reason="Sometimes fails on Linux ")
@pytest.mark.slow
def test_arrayeditor_edit_complex_array(qtbot):
"""See: spyder-ide/spyder#7848"""
Expand Down

0 comments on commit 3698b89

Please sign in to comment.