[Python-Dev] Re: [Python-checkins] CVS: python/dist/src/Modules _tkinter.c,1.99,1.100
Michael Hudson
mwh21@cam.ac.uk
19 Jun 2000 00:15:25 +0100
"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.