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: Initial Editor migration to the new API #21353

Merged
merged 78 commits into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from 73 commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
bcd574f
Editor: Rename plugin.py to widgets/main_widget.py
dalthviz Aug 9, 2023
bc818ec
Initial Editor migration to 'new' plugins API
dalthviz Sep 19, 2023
d4accf7
Merge branch 'master' into editor_migration
dalthviz Sep 19, 2023
bc4b18f
Fix window.py Editor widget test
dalthviz Sep 20, 2023
2e7d523
Initial code clean
dalthviz Sep 21, 2023
b9a0c71
Fix Editor test_plugin tests
dalthviz Sep 22, 2023
d029bb9
Initial fix for Editor widgets tests
dalthviz Sep 25, 2023
cf129df
Fix navigation action (go to previous file) on macOS
dalthviz Sep 25, 2023
949714e
Initial change to apply configs/options and template fix
dalthviz Sep 27, 2023
16e0d75
Fix eol preference test
dalthviz Sep 27, 2023
82901e4
Fix Editor closing logic
dalthviz Sep 29, 2023
384fbcd
Merge branch 'master' into editor_migration
dalthviz Sep 29, 2023
7980c1d
Run setup teardown and some fixes to mainwindow tests
dalthviz Sep 29, 2023
de139fa
Fix File menu actions order and prevent registration warnings for Edi…
dalthviz Oct 3, 2023
ebc8dc9
Fix EditorSplitter related tests and add force_focus to switch to plu…
dalthviz Oct 3, 2023
9c426aa
Fix EditorSplitter test on Linux. Start fixing some mainwindow tests
dalthviz Oct 4, 2023
c12120a
Merge branch 'master' into editor_migration
dalthviz Oct 4, 2023
6d6647d
More fixes for mainwindow tests
dalthviz Oct 4, 2023
beabdf0
Fix Editor-Projects connection and recent files config handling
dalthviz Oct 5, 2023
cd9110a
CI: Revision on slow tests cleanup logic
dalthviz Oct 11, 2023
66494b4
Merge branch 'master' into editor_migration
dalthviz Oct 11, 2023
3d33f4e
Initial Editor migration comments clean up
dalthviz Oct 11, 2023
0046f34
More code clean up (commented out code removal and TODO comments)
dalthviz Oct 12, 2023
afc508c
Testing
dalthviz Oct 13, 2023
e4a99ce
Teardown implementation for some plugins used by the Editor
dalthviz Oct 16, 2023
cb17f94
Switcher: Fix symbol switcher mode and selected item usage
dalthviz Oct 17, 2023
1d72a43
Merge branch 'master' into editor_migration
dalthviz Oct 17, 2023
b50694b
Merge branch 'master' into editor_migration
dalthviz Oct 18, 2023
80a645c
Testing
dalthviz Oct 19, 2023
792b99d
Merge branch 'master' into editor_migration
dalthviz Oct 31, 2023
13ecfc2
Fix EditorSplitter setup for tests
dalthviz Oct 31, 2023
7ff1fc9
Fix some teardown logic and run config. Test using teardown logic ena…
dalthviz Nov 30, 2023
4d4a5eb
Merge branch 'master' into editor_migration
dalthviz Nov 30, 2023
f3dec4b
Add validations for elements managed by the run plugin and tours clos…
dalthviz Nov 30, 2023
b8fd3c7
Testing
dalthviz Dec 1, 2023
a516b75
Merge branch 'master' into editor_migration
dalthviz Dec 6, 2023
1917cc2
Merge branch 'master' into editor_migration
dalthviz Dec 12, 2023
323d2ce
Editor menus migration to use SpyderMenu
dalthviz Feb 1, 2024
80d852f
Merge branch 'master' into editor_migration
dalthviz Feb 2, 2024
6b667ff
Testing
dalthviz Feb 2, 2024
70c2fff
Testing
dalthviz Feb 5, 2024
fc197db
Merge branch 'master' into editor_migration
dalthviz Feb 5, 2024
35f52d3
Merge branch 'master' into editor_migration
dalthviz Feb 6, 2024
0d291a0
Testing
dalthviz Feb 6, 2024
1d2c486
Merge branch 'master' into editor_migration
dalthviz Feb 7, 2024
99f082b
Testing
dalthviz Feb 8, 2024
c653f95
Testing
dalthviz Feb 8, 2024
2254d2f
Testing
dalthviz Feb 8, 2024
b091c77
Merge branch 'master' into editor_migration
dalthviz Feb 9, 2024
14df8b6
Merge branch 'master' into editor_migration
dalthviz Feb 12, 2024
e319912
Fix code style issues. Restore runtests.py
dalthviz Feb 12, 2024
a117a2d
Testing
dalthviz Feb 12, 2024
f07fafe
Testing
dalthviz Feb 13, 2024
f675978
Testing
dalthviz Feb 13, 2024
6d8eb28
Testing
dalthviz Feb 14, 2024
ad6c66f
Testing
dalthviz Feb 14, 2024
6f150ef
Merge branch 'master' into editor_migration
dalthviz Feb 16, 2024
ebab1d4
Merge branch 'master' into editor_migration
dalthviz Feb 19, 2024
5cb5580
Some TODO removal
dalthviz Feb 20, 2024
6851b83
Testing
dalthviz Feb 21, 2024
fda8ee9
Color scheme and switcher handling improvements
dalthviz Feb 21, 2024
5129433
Missing get_color_scheme rename and some TODOS removal
dalthviz Feb 21, 2024
cd1e7b2
Testing
dalthviz Feb 22, 2024
ea1c454
Merge branch 'master' into editor_migration
dalthviz Feb 22, 2024
6834411
Move some on config change handling to the editorstack
dalthviz Feb 22, 2024
ace3d30
Merge branch 'editor_migration' of https://github.com/dalthviz/spyder…
dalthviz Feb 22, 2024
094ebd9
Testing
dalthviz Feb 23, 2024
020c20c
Testing
dalthviz Feb 26, 2024
3bb251e
Testing
dalthviz Feb 26, 2024
682ff8f
Testing
dalthviz Feb 26, 2024
c0692f2
Testing
dalthviz Feb 26, 2024
8eec799
Merge branch 'master' into editor_migration
dalthviz Feb 27, 2024
dfd4f4f
Initial changes for CodeEditor as SpyderWidgetMixin
dalthviz Feb 27, 2024
af56c2c
Fix code style, UI and API issues
ccordoba12 Mar 3, 2024
fb51641
Intial review changes
dalthviz Mar 13, 2024
656b68d
Improve on_conf_change usage in the EditorStack
dalthviz Mar 19, 2024
b79fbcb
Merge branch 'master' into editor_migration
dalthviz Mar 20, 2024
afeac61
Main window: Validate if Projects is available when saving its files
ccordoba12 Mar 21, 2024
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
2 changes: 1 addition & 1 deletion runtests.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def run_pytest(run_slow=False, extra_args=None):
"""Run pytest tests for Spyder."""
# Be sure to ignore subrepos
pytest_args = ['-vv', '-rw', '--durations=10', '--ignore=./external-deps',
'-W ignore::UserWarning', '--timeout=120']
'-W ignore::UserWarning', '--timeout=120', '--timeout_method=thread']

if CI:
# Show coverage
Expand Down
26 changes: 10 additions & 16 deletions spyder/api/plugin_registration/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
from spyder.utils.icon_manager import ima


# TODO: Remove SpyderPlugin and SpyderPluginWidget once the migration
# is complete.
# TODO: Remove SpyderPlugin and SpyderPluginWidget now that the migration
# is complete
Spyder5PluginClass = Union[SpyderPluginV2, SpyderDockablePlugin]
Spyder4PluginClass = Union[SpyderPlugin, SpyderPluginWidget]
SpyderPluginClass = Union[Spyder4PluginClass, Spyder5PluginClass]
Expand Down Expand Up @@ -403,18 +403,12 @@ def can_delete_plugin(self, plugin_name: str) -> bool:

Returns
-------
plugin_deleted: bool
True if the plugin can be deleted. False otherwise.
can_close: bool
True if the plugin can be closed. False otherwise.
"""
plugin_instance = self.plugin_registry[plugin_name]
# Determine if plugin can be closed
can_delete = True
if isinstance(plugin_instance, SpyderPluginV2):
can_delete = plugin_instance.can_close()
elif isinstance(plugin_instance, SpyderPlugin):
can_delete = plugin_instance.closing_plugin(True)

return can_delete
return plugin_instance.can_close()

def dock_undocked_plugin(
self, plugin_name: str, save_undocked: bool = False):
Expand Down Expand Up @@ -598,11 +592,9 @@ def can_delete_all_plugins(self,
for plugin_name in (
set(self.external_plugins) | set(self.internal_plugins)):
if plugin_name not in excluding:
plugin_instance = self.plugin_registry[plugin_name]
if isinstance(plugin_instance, SpyderPlugin):
can_close &= self.can_delete_plugin(plugin_name)
if not can_close:
break
can_close &= self.can_delete_plugin(plugin_name)
if not can_close:
break

return can_close

Expand Down Expand Up @@ -794,6 +786,8 @@ def reset(self):
# Omit failures if there are no slots connected
pass

dependencies.DEPENDENCIES = []

def set_all_internal_plugins(
self, all_plugins: Dict[str, Type[SpyderPluginClass]]):
self.all_internal_plugins = all_plugins
Expand Down
6 changes: 3 additions & 3 deletions spyder/api/plugins/new_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,9 @@ def __init__(self, parent, configuration=None):
parent=parent
)

if hasattr(container, '_setup'):
container._setup()

if isinstance(container, SpyderWidgetMixin):
container.setup()
container.update_actions()
Expand All @@ -344,9 +347,6 @@ def __init__(self, parent, configuration=None):

self.after_container_creation()

if hasattr(container, '_setup'):
container._setup()

# Load the custom images of the plugin
if self.IMG_PATH:
plugin_path = osp.join(self.get_path(), self.IMG_PATH)
Expand Down
6 changes: 5 additions & 1 deletion spyder/api/widgets/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,8 @@ def _update_action_state(self, action_name, value):
# other it refers to a section of the configuration (or the widget
# name where it is applied).
def create_action(self, name, text, icon=None, icon_text='', tip=None,
toggled=None, triggered=None, shortcut_context=None,
toggled=None, triggered=None, data=None,
shortcut_context=None,
context=Qt.WidgetWithChildrenShortcut, initial=None,
register_shortcut=False, section=None, option=None,
parent=None, register_action=True, overwrite=False,
Expand All @@ -461,6 +462,8 @@ def create_action(self, name, text, icon=None, icon_text='', tip=None,
behave like a checkbox.
triggered: callable
The callable to use when triggering this action.
data: Any
Data to be set on the action.
shortcut_context: str
Set the `str` context of the shortcut.
context: Qt.ShortcutContext
Expand Down Expand Up @@ -528,6 +531,7 @@ def create_action(self, name, text, icon=None, icon_text='', tip=None,
tip=tip,
toggled=toggled,
triggered=triggered,
data=data,
context=context,
section=section,
option=option,
Expand Down
22 changes: 12 additions & 10 deletions spyder/api/widgets/toolbars.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,6 @@ def add_item(self, action_or_widget: ToolbarItem,
item_id = action_or_widget.action_id
elif hasattr(action_or_widget, 'ID'):
item_id = action_or_widget.ID

if not omit_id and item_id is None and action_or_widget is not None:
raise SpyderAPIError(
f'Item {action_or_widget} must declare an ID attribute.')
Expand Down Expand Up @@ -219,15 +218,18 @@ def add_item(self, action_or_widget: ToolbarItem,

def remove_item(self, item_id: str):
"""Remove action or widget from toolbar by id."""
item = self._item_map.pop(item_id)
for section in list(self._section_items.keys()):
section_items = self._section_items[section]
if item in section_items:
section_items.remove(item)
if len(section_items) == 0:
self._section_items.pop(section)
self.clear()
self._render()
try:
item = self._item_map.pop(item_id)
for section in list(self._section_items.keys()):
section_items = self._section_items[section]
if item in section_items:
section_items.remove(item)
if len(section_items) == 0:
self._section_items.pop(section)
self.clear()
self._render()
except KeyError:
pass

def _render(self):
"""
Expand Down
15 changes: 2 additions & 13 deletions spyder/app/mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,10 +234,7 @@ def signal_handler(signum, frame=None):
self.paste_action = None
self.selectall_action = None

# TODO: Move to corresponding Plugins
self.file_toolbar = None
self.file_toolbar_actions = []

# TODO: Is this being used somewhere?
self.menus = []

if running_under_pytest():
Expand Down Expand Up @@ -801,14 +798,6 @@ def setup(self):

# Set window title
self.set_window_title()
self.set_splash("")

# Toolbars
# TODO: Remove after finishing the migration
logger.info("Creating toolbars...")
toolbar = self.toolbar
self.file_toolbar = toolbar.get_application_toolbar("file_toolbar")

self.set_splash(_("Setting up main window..."))

def __getattr__(self, attr):
Expand Down Expand Up @@ -1048,7 +1037,7 @@ def createPopupMenu(self):

def closeEvent(self, event):
"""closeEvent reimplementation"""
if self.closing(True):
if self.closing(cancelable=True):
event.accept()
else:
event.ignore()
Expand Down
42 changes: 32 additions & 10 deletions spyder/app/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import pytest

# Spyder imports
from spyder.api.plugin_registration.registry import PLUGIN_REGISTRY
from spyder.api.plugins import Plugins
from spyder.app import start
from spyder.config.base import get_home_dir, running_in_ci
Expand All @@ -35,7 +36,6 @@
from spyder.utils.environ import (get_user_env, set_user_env,
amend_user_shell_init)


# =============================================================================
# ---- Constants
# =============================================================================
Expand Down Expand Up @@ -242,7 +242,7 @@ def preferences_dialog_helper(qtbot, main_window, section):
def generate_run_parameters(mainwindow, filename, selected=None,
executor=None):
"""Generate run configuration parameters for a given filename."""
file_uuid = mainwindow.editor.id_per_file[filename]
file_uuid = mainwindow.editor.get_widget().id_per_file[filename]
if executor is None:
executor = mainwindow.ipyconsole.NAME

Expand Down Expand Up @@ -281,10 +281,18 @@ def close_window():
if hasattr(main_window, 'window') and main_window.window is not None:
window = main_window.window
main_window.window = None
window.closing(close_immediately=True)
window.close()
window = None
CONF.reset_to_defaults(notification=False)
CONF.reset_manager()
PLUGIN_REGISTRY.reset()
if qapp.instance():
for widget in qapp.allWidgets():
try:
widget.close()
except RuntimeError:
pass
qapp.quit()

request.addfinalizer(close_window)
Expand Down Expand Up @@ -370,9 +378,6 @@ def main_window(request, tmpdir, qtbot):
QApplication.processEvents()

if not hasattr(main_window, 'window') or main_window.window is None:
from spyder.api.plugin_registration.registry import PLUGIN_REGISTRY
PLUGIN_REGISTRY.reset()

# Start the window
window = start.main()
main_window.window = window
Expand Down Expand Up @@ -444,9 +449,13 @@ def main_window(request, tmpdir, qtbot):
print('info_page')
print(client.info_page)
main_window.window = None
window.closing(close_immediately=True)
window.close()
window = None
CONF.reset_to_defaults(notification=False)
CONF.reset_manager()
PLUGIN_REGISTRY.reset()

else:
# Try to close used mainwindow directly on fixture
# after running test that uses the fixture
Expand All @@ -457,25 +466,26 @@ def main_window(request, tmpdir, qtbot):
'close_main_window')
if close_main_window:
main_window.window = None
window.closing(close_immediately=True)
window.close()
window = None
CONF.reset_to_defaults(notification=False)
CONF.reset_manager()
PLUGIN_REGISTRY.reset()
else:
try:
# Close or hide everything we can think of
window.switcher.hide()
window.switcher.on_close()

# Close editor related elements
window.editor.close_all_files()

# Force close all files
while window.editor.editorstacks[0].close_file(force=True):
while window.editor.get_widget().editorstacks[0].close_file(force=True):
pass
for editorwindow in window.editor.editorwindows:
for editorwindow in window.editor.get_widget().editorwindows:
editorwindow.close()
editorstack = window.editor.get_current_editorstack()
if editorstack.switcher_plugin:
editorstack.switcher_plugin.on_close()

window.projects.close_project()

Expand All @@ -501,9 +511,12 @@ def main_window(request, tmpdir, qtbot):
window.ipyconsole.restart()
except Exception:
main_window.window = None
window.closing(close_immediately=True)
window.close()
window = None
CONF.reset_to_defaults(notification=False)
CONF.reset_manager()
PLUGIN_REGISTRY.reset()
return

if os.name == 'nt':
Expand Down Expand Up @@ -550,9 +563,12 @@ def threads_condition():
"\nThread " + str(threads) + ":\n")
traceback.print_stack(frame)
main_window.window = None
window.closing(close_immediately=True)
window.close()
window = None
CONF.reset_to_defaults(notification=False)
CONF.reset_manager()
PLUGIN_REGISTRY.reset()
raise

try:
Expand All @@ -563,9 +579,12 @@ def threads_condition():
subprocesses = [repr(f) for f in proc.children()]
show_diff(init_subprocesses, subprocesses, "processes")
main_window.window = None
window.closing(close_immediately=True)
window.close()
window = None
CONF.reset_to_defaults(notification=False)
CONF.reset_manager()
PLUGIN_REGISTRY.reset()
raise

try:
Expand All @@ -579,9 +598,12 @@ def threads_condition():
except Exception:
show_diff(init_files, files, "files")
main_window.window = None
window.closing(close_immediately=True)
window.close()
window = None
CONF.reset_to_defaults(notification=False)
CONF.reset_manager()
PLUGIN_REGISTRY.reset()
raise


Expand Down
Loading
Loading