[Python-checkins] cpython (2.7): Issue #21580: Now Tkinter correctly handles binary "data" and "maskdata"

serhiy.storchaka python-checkins at python.org
Thu Jul 31 06:57:15 CEST 2014


http://hg.python.org/cpython/rev/818989a48e96
changeset:   91947:818989a48e96
branch:      2.7
parent:      91943:6b7f189daa62
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Thu Jul 31 07:48:14 2014 +0300
summary:
  Issue #21580: Now Tkinter correctly handles binary "data" and "maskdata"
configure options of tkinter.PhotoImage.

Added private Tkapp method _createbytearray().

files:
  Lib/lib-tk/Tkinter.py                       |   4 +
  Lib/lib-tk/test/test_tkinter/test_images.py |  11 +--
  Misc/NEWS                                   |   3 +
  Modules/_tkinter.c                          |  28 ++++++++++
  4 files changed, 39 insertions(+), 7 deletions(-)


diff --git a/Lib/lib-tk/Tkinter.py b/Lib/lib-tk/Tkinter.py
--- a/Lib/lib-tk/Tkinter.py
+++ b/Lib/lib-tk/Tkinter.py
@@ -3282,6 +3282,8 @@
         for k, v in cnf.items():
             if hasattr(v, '__call__'):
                 v = self._register(v)
+            elif k in ('data', 'maskdata'):
+                v = self.tk._createbytearray(v)
             options = options + ('-'+k, v)
         self.tk.call(('image', 'create', imgtype, name,) + options)
         self.name = name
@@ -3305,6 +3307,8 @@
                 if k[-1] == '_': k = k[:-1]
                 if hasattr(v, '__call__'):
                     v = self._register(v)
+                elif k in ('data', 'maskdata'):
+                    v = self.tk._createbytearray(v)
                 res = res + ('-'+k, v)
         self.tk.call((self.name, 'config') + res)
     config = configure
diff --git a/Lib/lib-tk/test/test_tkinter/test_images.py b/Lib/lib-tk/test/test_tkinter/test_images.py
--- a/Lib/lib-tk/test/test_tkinter/test_images.py
+++ b/Lib/lib-tk/test/test_tkinter/test_images.py
@@ -151,7 +151,8 @@
         self.assertEqual(image.type(), 'photo')
         self.assertEqual(image.width(), 16)
         self.assertEqual(image.height(), 16)
-        self.assertEqual(image['data'], data)
+        self.assertEqual(image['data'], data if self.wantobjects
+                                        else data.decode('latin1'))
         self.assertEqual(image['file'], '')
         self.assertIn('::img::test', self.root.image_names())
         del image
@@ -160,21 +161,18 @@
     def test_create_from_ppm_file(self):
         self.check_create_from_file('ppm')
 
-    @unittest.skip('issue #21580')
     def test_create_from_ppm_data(self):
         self.check_create_from_data('ppm')
 
     def test_create_from_pgm_file(self):
         self.check_create_from_file('pgm')
 
-    @unittest.skip('issue #21580')
     def test_create_from_pgm_data(self):
         self.check_create_from_data('pgm')
 
     def test_create_from_gif_file(self):
         self.check_create_from_file('gif')
 
-    @unittest.skip('issue #21580')
     def test_create_from_gif_data(self):
         self.check_create_from_data('gif')
 
@@ -182,19 +180,18 @@
     def test_create_from_png_file(self):
         self.check_create_from_file('png')
 
-    @unittest.skip('issue #21580')
     @requires_tcl(8, 6)
     def test_create_from_png_data(self):
         self.check_create_from_data('png')
 
-    @unittest.skip('issue #21580')
     def test_configure_data(self):
         image = tkinter.PhotoImage('::img::test', master=self.root)
         self.assertEqual(image['data'], '')
         with open(self.testfile, 'rb') as f:
             data = f.read()
         image.configure(data=data)
-        self.assertEqual(image['data'], data)
+        self.assertEqual(image['data'], data if self.wantobjects
+                                        else data.decode('latin1'))
         self.assertEqual(image.width(), 16)
         self.assertEqual(image.height(), 16)
 
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -19,6 +19,9 @@
 Library
 -------
 
+- Issue #21580: Now Tkinter correctly handles binary "data" and "maskdata"
+  configure options of tkinter.PhotoImage.
+
 - Issue #19612: subprocess.communicate() now also ignores EINVAL when using at
   least two pipes.
 
diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c
--- a/Modules/_tkinter.c
+++ b/Modules/_tkinter.c
@@ -2939,6 +2939,33 @@
     return Py_None;
 }
 
+/* Convert Python string or any buffer compatible object to Tcl byte-array
+ * object.  Use it to pass binary data (e.g. image's data) to Tcl/Tk commands.
+ */
+static PyObject *
+Tkapp_CreateByteArray(PyObject *self, PyObject *args)
+{
+    Py_buffer view;
+    Tcl_Obj* obj;
+    PyObject *res = NULL;
+
+    if (!PyArg_ParseTuple(args, "s*:_createbytearray", &view))
+        return NULL;
+
+    if (view.len >= INT_MAX) {
+        PyErr_SetString(PyExc_OverflowError, "string is too long");
+        return NULL;
+    }
+    obj = Tcl_NewByteArrayObj(view.buf, (int)view.len);
+    if (obj == NULL) {
+        PyBuffer_Release(&view);
+        return Tkinter_Error(self);
+    }
+    res = newPyTclObject(obj);
+    PyBuffer_Release(&view);
+    return res;
+}
+
 
 /**** Tkapp Method List ****/
 
@@ -2981,6 +3008,7 @@
     {"quit",                   Tkapp_Quit, METH_VARARGS},
     {"interpaddr",         Tkapp_InterpAddr, METH_VARARGS},
     {"loadtk",                 Tkapp_TkInit, METH_NOARGS},
+    {"_createbytearray",       Tkapp_CreateByteArray, METH_VARARGS},
     {NULL,                     NULL}
 };
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list