From cc3fb61803b2b3272a25f8f84f598e72bd9dfe45 Mon Sep 17 00:00:00 2001 From: Tal Einat <532281+taleinat@users.noreply.github.com> Date: Sun, 16 May 2021 16:16:44 +0300 Subject: [PATCH 1/5] bpo-40452: IDLE: fix clipboard being cleared upon exit --- Lib/idlelib/pyshell.py | 2 ++ .../2021-05-16-16-24-31.bpo-40452.Nayfdf.rst | 1 + Modules/_tkinter.c | 19 +++++++++++++++ Modules/clinic/_tkinter.c.h | 24 ++++++++++++++++++- 4 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/IDLE/2021-05-16-16-24-31.bpo-40452.Nayfdf.rst diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index 4e7440038ac997..6c7ca5fe224a7c 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -1698,6 +1698,8 @@ def main(): root.mainloop() root.destroy() capture_warnings(False) + import _tkinter + _tkinter.finalize_tcl() if __name__ == "__main__": 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..a8df04cc12f92c --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2021-05-16-16-24-31.bpo-40452.Nayfdf.rst @@ -0,0 +1 @@ +fix IDLE clearing the clipboard upon exit diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 3a0e5def0cf3c1..17e6bd4bf1f80c 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -3275,6 +3275,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=aae15057169190f2 input=23f70c6ef17beaf6]*/ +{ + Tcl_FinalizeThread(); + Py_RETURN_NONE; +} + #include "clinic/_tkinter.c.h" static PyMethodDef Tktt_methods[] = @@ -3359,6 +3377,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 9718986838fbb3..95c9e123ccc10b 100644 --- a/Modules/clinic/_tkinter.c.h +++ b/Modules/clinic/_tkinter.c.h @@ -860,6 +860,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) */ @@ -867,4 +889,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=ab311480dd044fe4 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e1cdf39065b75d72 input=a9049054013a1b77]*/ From a4d77bad6e96a1bb82065b3a38daf8d122e1177e Mon Sep 17 00:00:00 2001 From: Tal Einat <532281+taleinat@users.noreply.github.com> Date: Sun, 16 May 2021 23:36:56 +0300 Subject: [PATCH 2/5] rename to _tkinter._finalize_tcl --- Lib/idlelib/pyshell.py | 2 +- Modules/_tkinter.c | 8 ++++---- Modules/clinic/_tkinter.c.h | 16 ++++++++-------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index 6c7ca5fe224a7c..f467d3a7e27cb0 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -1699,7 +1699,7 @@ def main(): root.destroy() capture_warnings(False) import _tkinter - _tkinter.finalize_tcl() + _tkinter._finalize_tcl() if __name__ == "__main__": main() diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 17e6bd4bf1f80c..ba389585d3db53 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -3276,7 +3276,7 @@ _tkinter_getbusywaitinterval_impl(PyObject *module) } /*[clinic input] -_tkinter.finalize_tcl +_tkinter._finalize_tcl Finalize the Tcl interpreter. @@ -3286,8 +3286,8 @@ 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=aae15057169190f2 input=23f70c6ef17beaf6]*/ +_tkinter__finalize_tcl_impl(PyObject *module) +/*[clinic end generated code: output=a7a2a4c67f43bd28 input=e1082c1b262a40aa]*/ { Tcl_FinalizeThread(); Py_RETURN_NONE; @@ -3377,7 +3377,7 @@ static PyMethodDef moduleMethods[] = _TKINTER_CREATE_METHODDEF _TKINTER_SETBUSYWAITINTERVAL_METHODDEF _TKINTER_GETBUSYWAITINTERVAL_METHODDEF - _TKINTER_FINALIZE_TCL_METHODDEF + _TKINTER__FINALIZE_TCL_METHODDEF {NULL, NULL} }; diff --git a/Modules/clinic/_tkinter.c.h b/Modules/clinic/_tkinter.c.h index 95c9e123ccc10b..2ff632c5bb80f7 100644 --- a/Modules/clinic/_tkinter.c.h +++ b/Modules/clinic/_tkinter.c.h @@ -860,8 +860,8 @@ _tkinter_getbusywaitinterval(PyObject *module, PyObject *Py_UNUSED(ignored)) return return_value; } -PyDoc_STRVAR(_tkinter_finalize_tcl__doc__, -"finalize_tcl($module, /)\n" +PyDoc_STRVAR(_tkinter__finalize_tcl__doc__, +"_finalize_tcl($module, /)\n" "--\n" "\n" "Finalize the Tcl interpreter.\n" @@ -870,16 +870,16 @@ PyDoc_STRVAR(_tkinter_finalize_tcl__doc__, "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__}, +#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); +_tkinter__finalize_tcl_impl(PyObject *module); static PyObject * -_tkinter_finalize_tcl(PyObject *module, PyObject *Py_UNUSED(ignored)) +_tkinter__finalize_tcl(PyObject *module, PyObject *Py_UNUSED(ignored)) { - return _tkinter_finalize_tcl_impl(module); + return _tkinter__finalize_tcl_impl(module); } #ifndef _TKINTER_TKAPP_CREATEFILEHANDLER_METHODDEF @@ -889,4 +889,4 @@ _tkinter_finalize_tcl(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=e1cdf39065b75d72 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4723a5061500f152 input=a9049054013a1b77]*/ From 6d098ac16ae64fe090709fc1f8491d5cba813319 Mon Sep 17 00:00:00 2001 From: Tal Einat <532281+taleinat@users.noreply.github.com> Date: Mon, 17 May 2021 10:57:45 +0300 Subject: [PATCH 3/5] reword NEWS entry as per CR Co-authored-by: Terry Jan Reedy --- Misc/NEWS.d/next/IDLE/2021-05-16-16-24-31.bpo-40452.Nayfdf.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index a8df04cc12f92c..904bc8940d3190 100644 --- 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 @@ -1 +1 @@ -fix IDLE clearing the clipboard upon exit +Fix new clipboard content copied from IDLE being gone after exiting IDLE. From bb4835c3e6abb10e61bd2618da40565a46a27e95 Mon Sep 17 00:00:00 2001 From: Tal Einat <532281+taleinat@users.noreply.github.com> Date: Wed, 19 May 2021 12:17:00 +0300 Subject: [PATCH 4/5] use try/finally to ensure pyshell cleanups are executed Signed-off-by: Tal Einat <532281+taleinat@users.noreply.github.com> --- Lib/idlelib/pyshell.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index f467d3a7e27cb0..bc30fcf78f82a3 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -1694,12 +1694,16 @@ 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) - import _tkinter - _tkinter._finalize_tcl() if __name__ == "__main__": main() From f3afda8a780de39771398be3c86499da15a82d62 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin Date: Sun, 9 Apr 2023 19:10:00 +0400 Subject: [PATCH 5/5] Run Argument Clinic --- Modules/clinic/_tkinter.c.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/clinic/_tkinter.c.h b/Modules/clinic/_tkinter.c.h index c2c06f9d3185f9..a68f9e11ec947c 100644 --- a/Modules/clinic/_tkinter.c.h +++ b/Modules/clinic/_tkinter.c.h @@ -887,4 +887,4 @@ _tkinter__finalize_tcl(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]*/