Re: [Python-checkins] CVS: python/dist/src/Modules _tkinter.c,1.99,1.100
"A.M. Kuchling" <akuchling@users.sourceforge.net> writes:
Update of /cvsroot/python/python/dist/src/Modules In directory slayer.i.sourceforge.net:/tmp/cvs-serv10064/Modules
Modified Files: _tkinter.c Log Message: Patch from /F: this patch adds a fast _flatten function to the _tkinter module, and imports it from Tkinter.py (if available).
this speeds up canvas operations like create_line and create_polygon. for example, a create_line with 5000 vertices runs about 50 times faster with this patch in place.
Unfortunately this introduces another Way To Make Python Core: [mwh21@atrus build]$ ./python Python 1.6a2 (#4, Jun 18 2000, 23:57:36) [GCC 2.95.1 19990816/Linux (release)] on linux2 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam Copyright 1995-2000 Corporation for National Research Initiatives (CNRI)
import Tkinter l = [] l.append(l) Tkinter._flatten(l) Segmentation fault (core dumped)
Here's a simple solution: Index: _tkinter.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_tkinter.c,v retrieving revision 1.100 diff -u -r1.100 _tkinter.c --- _tkinter.c 2000/06/18 18:45:50 1.100 +++ _tkinter.c 2000/06/18 23:13:22 @@ -2001,13 +2001,16 @@ } static int -_flatten1(FlattenContext* context, PyObject* item) +_flatten1(FlattenContext* context, PyObject* item, int depth) { /* add tuple or list to argument tuple (recursively) */ int i, size; - if (PyList_Check(item)) { + if (depth > 1000) { + PyErr_SetString(PyExc_ValueError,"nesting too deep in _flatten"); + return 0; + } else if (PyList_Check(item)) { size = PyList_GET_SIZE(item); /* preallocate (assume no nesting) */ if (context->size + size > context->maxsize && !_bump(context, size)) @@ -2016,7 +2019,7 @@ for (i = 0; i < size; i++) { PyObject *o = PyList_GET_ITEM(item, i); if (PyList_Check(o) || PyTuple_Check(o)) { - if (!_flatten1(context, o)) + if (!_flatten1(context, o, depth + 1)) return 0; } else if (o != Py_None) { if (context->size + 1 > context->maxsize && !_bump(context, 1)) @@ -2033,7 +2036,7 @@ for (i = 0; i < size; i++) { PyObject *o = PyTuple_GET_ITEM(item, i); if (PyList_Check(o) || PyTuple_Check(o)) { - if (!_flatten1(context, o)) + if (!_flatten1(context, o, depth + 1)) return 0; } else if (o != Py_None) { if (context->size + 1 > context->maxsize && !_bump(context, 1)) @@ -2068,7 +2071,7 @@ context.size = 0; - if (!_flatten1(&context, item)) + if (!_flatten1(&context, item,0)) return NULL; if (_PyTuple_Resize(&context.tuple, context.size, 0)) "seems to work"; I've not tested it for performance, but I can't believe this is too hard a hit. Cheers, M.
michael wrote:
this patch adds a fast _flatten function to the _tkinter module, and imports it from Tkinter.py (if available).
Unfortunately this introduces another Way To Make Python Core:
well, there are lots of way to dump core through Tkinter/Tk, so I convinced myself that it wasn't really worth the effort to prevent it in _flatten... either way, the patch looks okay to me. </F>
participants (2)
-
Fredrik Lundh
-
Michael Hudson