diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 6ceced49285c..204a2a844756 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -188,7 +188,6 @@ def switch_backend(newbackend): The name of the backend to use. """ close("all") - if newbackend is rcsetup._auto_backend_sentinel: for candidate in ["macosx", "qt5agg", "qt4agg", "gtk3agg", "gtk3cairo", "tkagg", "wxagg", "agg", "cairo"]: @@ -2349,6 +2348,23 @@ def _autogen_docstring(base): # Set up the backend. switch_backend(rcParams["backend"]) +# We need an extra check here for macosx framework. If we are using MacOSX +# and not using the framework build we throw an ImportError (for back compat). +if dict.__getitem__(rcParams, "backend") == 'MacOSX': + from matplotlib.backends import _macosx + if not _macosx.verify_framework(): + raise ImportError( + "Python is not installed as a framework. The Mac OS X backend " + "will not be able to function correctly if Python is not " + "installed as a framework. See the Python documentation for more " + "information on installing Python as a framework on Mac OS X. " + "Please either reinstall Python as a framework, or try one of " + "the other backends. If you are using (Ana)Conda please install " + "python.app and replace the use of 'python' with 'pythonw'. See " + "'Working with Matplotlib on OSX' in the Matplotlib FAQ for " + "more information.") + + # Just to be safe. Interactive mode can be turned on without # calling `plt.ion()` so register it again here. # This is safe because multiple calls to `install_repl_displayhook` diff --git a/src/_macosx.m b/src/_macosx.m index ce791d1f9d21..f3e3a52c34d5 100644 --- a/src/_macosx.m +++ b/src/_macosx.m @@ -2575,24 +2575,37 @@ static void context_cleanup(const void* info) Timer_new, /* tp_new */ }; -static bool verify_framework(void) +PyObject* +verify_framework(void) { + ProcessSerialNumber oldpsn; + GetFrontProcess(&oldpsn); + +#ifdef COMPILING_FOR_10_6 + NSApp = [NSApplication sharedApplication]; + NSApplicationActivationPolicy activationPolicy = [NSApp activationPolicy]; + switch (activationPolicy) { + case NSApplicationActivationPolicyRegular: + case NSApplicationActivationPolicyAccessory: + { SetFrontProcess(&oldpsn); + return Py_True; + } + case NSApplicationActivationPolicyProhibited: + break; + } +#else ProcessSerialNumber psn; /* These methods are deprecated, but they don't require the app to have started */ if (CGMainDisplayID()!=0 && GetCurrentProcess(&psn)==noErr - && SetFrontProcess(&psn)==noErr) return true; - PyErr_SetString(PyExc_ImportError, - "Python is not installed as a framework. The Mac OS X backend will " - "not be able to function correctly if Python is not installed as a " - "framework. See the Python documentation for more information on " - "installing Python as a framework on Mac OS X. Please either reinstall " - "Python as a framework, or try one of the other backends. If you are " - "using (Ana)Conda please install python.app and replace the use of " - "'python' with 'pythonw'. See 'Working with Matplotlib on OSX' in the " - "Matplotlib FAQ for more information."); - return false; + && SetFrontProcess(&psn)==noErr){ + SetFrontProcess(&oldpsn); + return Py_True; + } +#endif + SetFrontProcess(&oldpsn); + return Py_False; } static struct PyMethodDef methods[] = { @@ -2619,7 +2632,12 @@ static bool verify_framework(void) METH_VARARGS, "Sets the active cursor." }, - {NULL, NULL, 0, NULL} /* sentinel */ + {"verify_framework", + (PyCFunction)verify_framework, + METH_NOARGS, + "Verifies that the framework build is being used." + }, + {NULL, NULL, 0, NULL, NULL} /* sentinel */ }; static struct PyModuleDef moduledef = { @@ -2644,8 +2662,6 @@ static bool verify_framework(void) || PyType_Ready(&TimerType) < 0) return NULL; - if (!verify_framework()) - return NULL; module = PyModule_Create(&moduledef); if (!module)