-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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: Remove macOS app flow fork in closing Spyder #17732
Conversation
@ccordoba12, after removing the flow control for the macOS app in the artifact from #16409 I was unable to reproduce any segfaults. Perhaps the segfaults were encountered earlier in your development for that PR and incidentally resolved in the same PR after inserting the flow control? Nevertheless, when testing on this PR with local builds, closing the app does not produce any errors or faults and all Python processes are exited. Restarting Spyder from the menubar get much further now, but still fails. The restarting splash screen appears, as well as the new starting splash screen, but then fails with the following error: Traceback (most recent call last):
File "/Users/rclary/Documents/Python/spyder/installers/macOS/dist/Spyder.app/Contents/Resources/lib/python3.9/spyder/app/start.py", line 254, in <module>
main()
File "/Users/rclary/Documents/Python/spyder/installers/macOS/dist/Spyder.app/Contents/Resources/lib/python3.9/spyder/app/start.py", line 250, in main
mainwindow.main(options, args)
File "/Users/rclary/Documents/Python/spyder/installers/macOS/dist/Spyder.app/Contents/Resources/lib/python3.9/spyder/app/mainwindow.py", line 2057, in main
mainwindow = create_window(MainWindow, app, splash, options, args)
File "/Users/rclary/Documents/Python/spyder/installers/macOS/dist/Spyder.app/Contents/Resources/lib/python3.9/spyder/app/utils.py", line 289, in create_window
main.setup()
File "/Users/rclary/Documents/Python/spyder/installers/macOS/dist/Spyder.app/Contents/Resources/lib/python3.9/spyder/app/mainwindow.py", line 923, in setup
mainmenu = self.mainmenu
File "/Users/rclary/Documents/Python/spyder/installers/macOS/dist/Spyder.app/Contents/Resources/lib/python3.9/spyder/app/mainwindow.py", line 1069, in __getattr__
return super().__getattr__(attr)
AttributeError: 'MainWindow' object has no attribute 'mainmenu' |
The restart sequence launches a subprocess that runs Relevant environment variables:
Command:
Output:
I'll investigate further what seems to be causing a problem for the macOS app. Maybe it's an environment variable, or maybe it's something in I also know that the Spyder macOS app can be launched from the command line using |
Okay, the issue seems to be that |
Okay, I've narrowed it down to #17612, the update to |
Okay, it looks like this is not a bug in Working with local builds, I can launch Spyder's Python from the terminal and check entry points. Pre py2app<0.28>> PYTHONHOME=Spyder.app/Contents/Resources
>> Spyder.app/Contents/MacOS/python -c "import pkg_resources; print(list(pkg_resources.iter_entry_points('spyder.plugins')))"
[EntryPoint.parse('terminal = spyder_terminal.terminalplugin:TerminalPlugin'), EntryPoint.parse('appearance = spyder.plugins.appearance.plugin:Appearance'), EntryPoint.parse('application = spyder.plugins.application.plugin:Application'), EntryPoint.parse('breakpoints = spyder.plugins.breakpoints.plugin:Breakpoints'), EntryPoint.parse('completions = spyder.plugins.completion.plugin:CompletionPlugin'), EntryPoint.parse('editor = spyder.plugins.editor.plugin:Editor'), EntryPoint.parse('explorer = spyder.plugins.explorer.plugin:Explorer'), EntryPoint.parse('find_in_files = spyder.plugins.findinfiles.plugin:FindInFiles'), EntryPoint.parse('help = spyder.plugins.help.plugin:Help'), EntryPoint.parse('historylog = spyder.plugins.history.plugin:HistoryLog'), EntryPoint.parse('internal_console = spyder.plugins.console.plugin:Console'), EntryPoint.parse('ipython_console = spyder.plugins.ipythonconsole.plugin:IPythonConsole'), EntryPoint.parse('layout = spyder.plugins.layout.plugin:Layout'), EntryPoint.parse('main_interpreter = spyder.plugins.maininterpreter.plugin:MainInterpreter'), EntryPoint.parse('mainmenu = spyder.plugins.mainmenu.plugin:MainMenu'), EntryPoint.parse('onlinehelp = spyder.plugins.onlinehelp.plugin:OnlineHelp'), EntryPoint.parse('outline_explorer = spyder.plugins.outlineexplorer.plugin:OutlineExplorer'), EntryPoint.parse('plots = spyder.plugins.plots.plugin:Plots'), EntryPoint.parse('preferences = spyder.plugins.preferences.plugin:Preferences'), EntryPoint.parse('profiler = spyder.plugins.profiler.plugin:Profiler'), EntryPoint.parse('project_explorer = spyder.plugins.projects.plugin:Projects'), EntryPoint.parse('pylint = spyder.plugins.pylint.plugin:Pylint'), EntryPoint.parse('run = spyder.plugins.run.plugin:Run'), EntryPoint.parse('shortcuts = spyder.plugins.shortcuts.plugin:Shortcuts'), EntryPoint.parse('statusbar = spyder.plugins.statusbar.plugin:StatusBar'), EntryPoint.parse('toolbar = spyder.plugins.toolbar.plugin:Toolbar'), EntryPoint.parse('tours = spyder.plugins.tours.plugin:Tours'), EntryPoint.parse('variable_explorer = spyder.plugins.variableexplorer.plugin:VariableExplorer'), EntryPoint.parse('workingdir = spyder.plugins.workingdirectory.plugin:WorkingDirectory')]
>> Spyder.app/Contents/MacOS/python -c "import importlib_metadata; print(importlib_metadata.entry_points().select(group='spyder.plugins'))"
[EntryPoint(name='terminal', value='spyder_terminal.terminalplugin:TerminalPlugin', group='spyder.plugins'), EntryPoint(name='appearance', value='spyder.plugins.appearance.plugin:Appearance', group='spyder.plugins'), EntryPoint(name='application', value='spyder.plugins.application.plugin:Application', group='spyder.plugins'), EntryPoint(name='breakpoints', value='spyder.plugins.breakpoints.plugin:Breakpoints', group='spyder.plugins'), EntryPoint(name='completions', value='spyder.plugins.completion.plugin:CompletionPlugin', group='spyder.plugins'), EntryPoint(name='editor', value='spyder.plugins.editor.plugin:Editor', group='spyder.plugins'), EntryPoint(name='explorer', value='spyder.plugins.explorer.plugin:Explorer', group='spyder.plugins'), EntryPoint(name='find_in_files', value='spyder.plugins.findinfiles.plugin:FindInFiles', group='spyder.plugins'), EntryPoint(name='help', value='spyder.plugins.help.plugin:Help', group='spyder.plugins'), EntryPoint(name='historylog', value='spyder.plugins.history.plugin:HistoryLog', group='spyder.plugins'), EntryPoint(name='internal_console', value='spyder.plugins.console.plugin:Console', group='spyder.plugins'), EntryPoint(name='ipython_console', value='spyder.plugins.ipythonconsole.plugin:IPythonConsole', group='spyder.plugins'), EntryPoint(name='layout', value='spyder.plugins.layout.plugin:Layout', group='spyder.plugins'), EntryPoint(name='main_interpreter', value='spyder.plugins.maininterpreter.plugin:MainInterpreter', group='spyder.plugins'), EntryPoint(name='mainmenu', value='spyder.plugins.mainmenu.plugin:MainMenu', group='spyder.plugins'), EntryPoint(name='onlinehelp', value='spyder.plugins.onlinehelp.plugin:OnlineHelp', group='spyder.plugins'), EntryPoint(name='outline_explorer', value='spyder.plugins.outlineexplorer.plugin:OutlineExplorer', group='spyder.plugins'), EntryPoint(name='plots', value='spyder.plugins.plots.plugin:Plots', group='spyder.plugins'), EntryPoint(name='preferences', value='spyder.plugins.preferences.plugin:Preferences', group='spyder.plugins'), EntryPoint(name='profiler', value='spyder.plugins.profiler.plugin:Profiler', group='spyder.plugins'), EntryPoint(name='project_explorer', value='spyder.plugins.projects.plugin:Projects', group='spyder.plugins'), EntryPoint(name='pylint', value='spyder.plugins.pylint.plugin:Pylint', group='spyder.plugins'), EntryPoint(name='run', value='spyder.plugins.run.plugin:Run', group='spyder.plugins'), EntryPoint(name='shortcuts', value='spyder.plugins.shortcuts.plugin:Shortcuts', group='spyder.plugins'), EntryPoint(name='statusbar', value='spyder.plugins.statusbar.plugin:StatusBar', group='spyder.plugins'), EntryPoint(name='toolbar', value='spyder.plugins.toolbar.plugin:Toolbar', group='spyder.plugins'), EntryPoint(name='tours', value='spyder.plugins.tours.plugin:Tours', group='spyder.plugins'), EntryPoint(name='variable_explorer', value='spyder.plugins.variableexplorer.plugin:VariableExplorer', group='spyder.plugins'), EntryPoint(name='workingdir', value='spyder.plugins.workingdirectory.plugin:WorkingDirectory', group='spyder.plugins')] py2app=0.28>> PYTHONHOME=Spyder.app/Contents/Resources
>> Spyder.app/Contents/MacOS/python -c "import pkg_resources; print(list(pkg_resources.iter_entry_points('spyder.plugins')))"
[]
>> Spyder.app/Contents/MacOS/python -c "import importlib_metadata; print(importlib_metadata.entry_points().select(group='spyder.plugins'))"
[EntryPoint(name='terminal', value='spyder_terminal.terminalplugin:TerminalPlugin', group='spyder.plugins'), EntryPoint(name='appearance', value='spyder.plugins.appearance.plugin:Appearance', group='spyder.plugins'), EntryPoint(name='application', value='spyder.plugins.application.plugin:Application', group='spyder.plugins'), EntryPoint(name='breakpoints', value='spyder.plugins.breakpoints.plugin:Breakpoints', group='spyder.plugins'), EntryPoint(name='completions', value='spyder.plugins.completion.plugin:CompletionPlugin', group='spyder.plugins'), EntryPoint(name='editor', value='spyder.plugins.editor.plugin:Editor', group='spyder.plugins'), EntryPoint(name='explorer', value='spyder.plugins.explorer.plugin:Explorer', group='spyder.plugins'), EntryPoint(name='find_in_files', value='spyder.plugins.findinfiles.plugin:FindInFiles', group='spyder.plugins'), EntryPoint(name='help', value='spyder.plugins.help.plugin:Help', group='spyder.plugins'), EntryPoint(name='historylog', value='spyder.plugins.history.plugin:HistoryLog', group='spyder.plugins'), EntryPoint(name='internal_console', value='spyder.plugins.console.plugin:Console', group='spyder.plugins'), EntryPoint(name='ipython_console', value='spyder.plugins.ipythonconsole.plugin:IPythonConsole', group='spyder.plugins'), EntryPoint(name='layout', value='spyder.plugins.layout.plugin:Layout', group='spyder.plugins'), EntryPoint(name='main_interpreter', value='spyder.plugins.maininterpreter.plugin:MainInterpreter', group='spyder.plugins'), EntryPoint(name='mainmenu', value='spyder.plugins.mainmenu.plugin:MainMenu', group='spyder.plugins'), EntryPoint(name='onlinehelp', value='spyder.plugins.onlinehelp.plugin:OnlineHelp', group='spyder.plugins'), EntryPoint(name='outline_explorer', value='spyder.plugins.outlineexplorer.plugin:OutlineExplorer', group='spyder.plugins'), EntryPoint(name='plots', value='spyder.plugins.plots.plugin:Plots', group='spyder.plugins'), EntryPoint(name='preferences', value='spyder.plugins.preferences.plugin:Preferences', group='spyder.plugins'), EntryPoint(name='profiler', value='spyder.plugins.profiler.plugin:Profiler', group='spyder.plugins'), EntryPoint(name='project_explorer', value='spyder.plugins.projects.plugin:Projects', group='spyder.plugins'), EntryPoint(name='pylint', value='spyder.plugins.pylint.plugin:Pylint', group='spyder.plugins'), EntryPoint(name='run', value='spyder.plugins.run.plugin:Run', group='spyder.plugins'), EntryPoint(name='shortcuts', value='spyder.plugins.shortcuts.plugin:Shortcuts', group='spyder.plugins'), EntryPoint(name='statusbar', value='spyder.plugins.statusbar.plugin:StatusBar', group='spyder.plugins'), EntryPoint(name='toolbar', value='spyder.plugins.toolbar.plugin:Toolbar', group='spyder.plugins'), EntryPoint(name='tours', value='spyder.plugins.tours.plugin:Tours', group='spyder.plugins'), EntryPoint(name='variable_explorer', value='spyder.plugins.variableexplorer.plugin:VariableExplorer', group='spyder.plugins'), EntryPoint(name='workingdir', value='spyder.plugins.workingdirectory.plugin:WorkingDirectory', group='spyder.plugins')] Perhaps this issue may resolved by migrating from It is puzzling to me, however, that Spyder starts just fine when built with from spyder.app import start
start.main() but I cannot confirm since it is a built binary inside the app. @ronaldoussoren, is the launch script modified by |
@ccordoba12, I recommend moving forward with this PR as it resolves completely #17729. This PR is necessary, but insufficient, for fixing #17731. I will open another PR to complete the fix for that issue and move the relevant aspects of this conversation to the new PR. |
As you can see, the app segfaults on exit while testing it. Don't you observe the same behavior locally? |
Ahh, I see. That is not a segfault; Spyder.app is working properly but the CI is capturing the ZMQ error when the IPython Console shuts down. This is issue #17615. I was curious why the CI was not capturing that error before. I suggest the following waiting on this PR until either |
@ccordoba12, it looks like the CI for the macOS installer is working with |
Okay, hold on. The full version is failing for some reason... |
I think the reason is PyQt 5.15. I mean, the app fails with that version but works well with 5.12 Edit: I just saw that the Lite app doesn't fail, so I don't know what the cause could be then. |
Okay, so
Subsequent output is Spyder shutting down. However, if Spyder fails to quit after the default delay of 2s, then a hard kill is sent and the process exits with a non-zero status and the CI identifies the failure. This is seen in the logs as
I observed this in all the failed tests, but assumed that it was due to the ZMQ issue. However, I've been able to reproduce the issue locally by setting the delay to 1s. My hypothesis now is that the shutdown time may be a bit flakey and the delay before the hard kill is too short. Maybe PyQt 5.15 resulted in a slight increase in the shutdown time; maybe the full version takes slightly longer than the lite version to shut down; maybe the ZMQ errors also increased the shutdown time; maybe a combination of all these. In any case, the solution may be as simple as increasing the delay to hard kill. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your help with this @mrclary!
Description of Changes
Closing the Spyder application in
mainwindow.py
has a flow control fork for the macOS standalone application. This is removed.Issue(s) Resolved
Fixes #17729
Partial fix for #17731
Affirmation
By submitting this Pull Request or typing my (user)name below,
I affirm the Developer Certificate of Origin
with respect to all commits and content included in this PR,
and understand I am releasing the same under Spyder's MIT (Expat) license.
I certify the above statement is true and correct: @mrclary