From b4c56ca9b0fd44756ead902623659ff708ce6dc1 Mon Sep 17 00:00:00 2001 From: charles <4837704+charlesej@users.noreply.github.com> Date: Wed, 20 Mar 2019 12:02:52 -0400 Subject: [PATCH 1/2] Fix the SystemError when no type specific clipboard content exists --- src_c/scrap.c | 7 ++++++- test/scrap_test.py | 3 --- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src_c/scrap.c b/src_c/scrap.c index 81dfc4a254..5596179f99 100644 --- a/src_c/scrap.c +++ b/src_c/scrap.c @@ -222,7 +222,12 @@ _scrap_get_scrap(PyObject *self, PyObject *args) val = PyDict_GetItemString(_clipdata, scrap_type); break; } - Py_XINCREF(val); + + if (!val) { + Py_RETURN_NONE; + } + + Py_INCREF(val); return val; } diff --git a/test/scrap_test.py b/test/scrap_test.py index 978e066199..60ff248272 100644 --- a/test/scrap_test.py +++ b/test/scrap_test.py @@ -41,9 +41,6 @@ def todo_test_get(self): """Ensures get works as expected.""" self.fail() - # The @unittest.expectedFailure decorator can be removed when issue #915 - # is resolved. - @unittest.expectedFailure def test_get__owned_empty_type(self): """Ensures get works when there is no data of the requested type in the clipboard and the clipboard is owned by the pygame application. From 5b160667f7a3f045ae23eb8c0273a05682f7d133 Mon Sep 17 00:00:00 2001 From: charles <4837704+charlesej@users.noreply.github.com> Date: Thu, 21 Mar 2019 16:20:06 -0400 Subject: [PATCH 2/2] Add dict error checking when getting items --- src_c/scrap.c | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/src_c/scrap.c b/src_c/scrap.c index 5596179f99..b7e4f5404e 100644 --- a/src_c/scrap.c +++ b/src_c/scrap.c @@ -203,7 +203,6 @@ _scrap_get_scrap(PyObject *self, PyObject *args) char *scrap = NULL; PyObject *retval; char *scrap_type; - PyObject *val; unsigned long count; PYGAME_SCRAP_INIT_CHECK(); @@ -212,20 +211,48 @@ _scrap_get_scrap(PyObject *self, PyObject *args) return NULL; if (!pygame_scrap_lost()) { - /* We are still the active one. */ + /* Still own the clipboard. */ + PyObject *scrap_dict = NULL; + PyObject *key = NULL; + PyObject *val = NULL; + switch (_currentmode) { case SCRAP_SELECTION: - val = PyDict_GetItemString(_selectiondata, scrap_type); + scrap_dict = _selectiondata; break; + case SCRAP_CLIPBOARD: default: - val = PyDict_GetItemString(_clipdata, scrap_type); + scrap_dict = _clipdata; break; } - if (!val) { +#if PY3 + key = PyUnicode_FromString(scrap_type); + if (NULL == key) { + return PyErr_Format(PyExc_ValueError, + "invalid scrap data type identifier (%s)", + scrap_type); + } + + val = PyDict_GetItemWithError(scrap_dict, key); + Py_DECREF(key); + + if (NULL == val) { + if (PyErr_Occurred()) { + return PyErr_Format(PyExc_SystemError, + "pygame.scrap internal error (key=%s)", + scrap_type); + } + + Py_RETURN_NONE; + } +#else /* !PY3 */ + val = PyDict_GetItemString(scrap_dict, scrap_type); + if (NULL == val) { Py_RETURN_NONE; } +#endif /* !PY3 */ Py_INCREF(val); return val;