diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index e68233a5a4131e..6def8935a64ef3 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -1688,9 +1688,15 @@ def main(): if prefer_tabs_preference_warning: shell.show_warning(prefer_tabs_preference_warning) - while flist.inversedict: # keep IDLE running while files are open. - root.mainloop() - root.destroy() + try: + while flist.inversedict: # keep IDLE running while files are open. + root.mainloop() + finally: + try: + root.destroy() + finally: + import _tkinter + _tkinter._finalize_tcl() capture_warnings(False) if __name__ == "__main__": diff --git a/Misc/NEWS.d/next/IDLE/2021-05-16-16-24-31.bpo-40452.Nayfdf.rst b/Misc/NEWS.d/next/IDLE/2021-05-16-16-24-31.bpo-40452.Nayfdf.rst new file mode 100644 index 00000000000000..904bc8940d3190 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2021-05-16-16-24-31.bpo-40452.Nayfdf.rst @@ -0,0 +1 @@ +Fix new clipboard content copied from IDLE being gone after exiting IDLE. diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 20e01c79668549..3e70aa0a41ed94 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -3039,6 +3039,24 @@ _tkinter_getbusywaitinterval_impl(PyObject *module) return Tkinter_busywaitinterval; } +/*[clinic input] +_tkinter._finalize_tcl + +Finalize the Tcl interpreter. + +This should be called just before an app exits, to allow Tcl to +execute its own finalization logic. After this, tkinter can no +longer be used, and attempts to do so will result in errors. +[clinic start generated code]*/ + +static PyObject * +_tkinter__finalize_tcl_impl(PyObject *module) +/*[clinic end generated code: output=a7a2a4c67f43bd28 input=e1082c1b262a40aa]*/ +{ + Tcl_FinalizeThread(); + Py_RETURN_NONE; +} + #include "clinic/_tkinter.c.h" static PyMethodDef Tktt_methods[] = @@ -3122,6 +3140,7 @@ static PyMethodDef moduleMethods[] = _TKINTER_CREATE_METHODDEF _TKINTER_SETBUSYWAITINTERVAL_METHODDEF _TKINTER_GETBUSYWAITINTERVAL_METHODDEF + _TKINTER__FINALIZE_TCL_METHODDEF {NULL, NULL} }; diff --git a/Modules/clinic/_tkinter.c.h b/Modules/clinic/_tkinter.c.h index 96c6ee26f426c3..a68f9e11ec947c 100644 --- a/Modules/clinic/_tkinter.c.h +++ b/Modules/clinic/_tkinter.c.h @@ -858,6 +858,28 @@ _tkinter_getbusywaitinterval(PyObject *module, PyObject *Py_UNUSED(ignored)) return return_value; } +PyDoc_STRVAR(_tkinter__finalize_tcl__doc__, +"_finalize_tcl($module, /)\n" +"--\n" +"\n" +"Finalize the Tcl interpreter.\n" +"\n" +"This should be called just before an app exits, to allow Tcl to\n" +"execute its own finalization logic. After this, tkinter can no\n" +"longer be used, and attempts to do so will result in errors."); + +#define _TKINTER__FINALIZE_TCL_METHODDEF \ + {"_finalize_tcl", (PyCFunction)_tkinter__finalize_tcl, METH_NOARGS, _tkinter__finalize_tcl__doc__}, + +static PyObject * +_tkinter__finalize_tcl_impl(PyObject *module); + +static PyObject * +_tkinter__finalize_tcl(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _tkinter__finalize_tcl_impl(module); +} + #ifndef _TKINTER_TKAPP_CREATEFILEHANDLER_METHODDEF #define _TKINTER_TKAPP_CREATEFILEHANDLER_METHODDEF #endif /* !defined(_TKINTER_TKAPP_CREATEFILEHANDLER_METHODDEF) */ @@ -865,4 +887,4 @@ _tkinter_getbusywaitinterval(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF #define _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF #endif /* !defined(_TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF) */ -/*[clinic end generated code: output=2a4e3bf8448604b5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3f82bafa92d88b20 input=a9049054013a1b77]*/