Scanning for thread violations with Tkinter
Question: We are just about to finish a very large update to our application which is
built with python2.5 and Tkinter and the following error has crept in sadly:

    
    
    alloc: invalid block: 06807CE7: 1 0 0
    
    This application has requested the Runtime to terminate it in an unusual way.
    Please contact the application's support team for more information.
    

We've seen this before and it is usually a Tcl Interrupter error caused when a
non GUI thread tries to access TK via Tkinter in anyway (TK not being thread
safe). The error pops up on application close, after the python interrupter is
finished with our code. This error is very hard to reproduce and I'm thinking
I will have to scan all threads in the system to see if they access TK when
they shouldn't.

I'm looking for a magic python trick to help with this. All Tkinter widgets we
use are first subclassed and inherit from out own Widget base class.

With this in mind I'm looking for a way to add the following check to the
beginning of every method in the widget sub classes:

    
    
    import thread
    if thread.get_ident() != TKINTER_GUI_THREAD_ID:
        assert 0, "Invalid thread accessing Tkinter!"
    

Decorators as a partial solution comes to mind. I do not want to add
decorators manually to each method however. Is there a way I can add the
decorator to all methods of a class that inherits from our Widget base class?
Or is there a better way to do all this? Or does anyone have more info about
this error?

    
    
    enter code here
    


Answer: I don't know if your approach is good, as I don't know Tkinter.

But here's a sample of how to decorate all class methods using a metaclass.

    
    
    import functools
    
    # This is the decorator
    def my_decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            print 'calling', func.__name__, 'from decorator'
            return func(*args, **kwargs)
    
        return wrapper
    
    # This is the metaclass
    class DecorateMeta(type):
        def __new__(cls, name, bases, attrs):
            for key in attrs:
                # Skip special methods, e.g. __init__
                if not key.startswith('__') and callable(attrs[key]):
                    attrs[key] = my_decorator(attrs[key])
    
            return super(DecorateMeta, cls).__new__(cls, name, bases, attrs)
    
    # This is a sample class that uses the metaclass
    class MyClass(object):
        __metaclass__ = DecorateMeta
    
        def __init__(self):
            print 'in __init__()'
    
        def test(self):
            print 'in test()'
    
    obj = MyClass()
    obj.test()
    

The metaclass overrides the class creation. It loops through all the
attributes of the class being created and decorates all callable attributes
that have a "regular" name with `my_decorator`.

