Commit ae4ccb13 authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #21580: Now Tkinter correctly handles binary "data" and "maskdata"

configure options of tkinter.PhotoImage.

Added private Tkapp method _createbytearray().
parent 7fb2f915
......@@ -3282,6 +3282,8 @@ class Image:
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 @@ class Image:
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
......
......@@ -151,7 +151,8 @@ class PhotoImageTest(unittest.TestCase):
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 @@ class PhotoImageTest(unittest.TestCase):
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 @@ class PhotoImageTest(unittest.TestCase):
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)
......
......@@ -19,6 +19,9 @@ Core and Builtins
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.
......
......@@ -2939,6 +2939,33 @@ Tkapp_WillDispatch(PyObject *self, PyObject *args)
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 @@ static PyMethodDef Tkapp_methods[] =
{"quit", Tkapp_Quit, METH_VARARGS},
{"interpaddr", Tkapp_InterpAddr, METH_VARARGS},
{"loadtk", Tkapp_TkInit, METH_NOARGS},
{"_createbytearray", Tkapp_CreateByteArray, METH_VARARGS},
{NULL, NULL}
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment