This page documents some catches, tips and tricks on Python bindings for EFL. It serves the purpose of documenting Frequently Asked Questions (FAQ) and problems on misunderstanding some concepts.

TOC?

Evas

Object Deletion

Evas design states that canvas have a reference to objects, you can later retrieve them by name, position or other means. This extra reference is maintained in Python, so when your Python code looses the last reference, the canvas will still keep its reference.

The catch is that objects need to be explicitly deleted with delete() method. Don't mix this with Python's del, the later will just remove the symbol from current frame, releasing that reference, but other references may still exist, such as the reference from canvas:

del my_rect      # FAIL! just current reference is gone, object is still in canvas.
my_rect.delete() # correct

Another catch is that object might be explicitly deleted by someone else, possibly a behavior of other class or library. In this case, those that still keep Python references will have a shallow object, it's there in Python as wrapper, but it's C counterpart (wrapped) is gone. Using shallow objects should not crash your application, but actions will be void, return values will be bogus (generally 0 or False or None) and some functions may raise exceptions. To handle this situation, one can listen to evas EVAS_CALLBACK_DEL signal:

# define your handler:
def on_my_rect_del(my_rect):
    print "my rect was deleted!"

# connect your handler:
my_rect.on_del_add(on_my_rect_del)

Ecore

Callback Returns

Ecore provide a set of callbacks for timers, idlers, file descriptor handlers and events. The C version defines a return of ECORE_CALLBACK_CANCEL=0 and ECORE_CALLBACK_RENEW=1. These are mapped in Python simply as False and True, but one can return 0 or 1 as well.

The catch is that returning nothing from Python, actually returns None that evaluates to False and thus C version will get ECORE_CALLBACK_CANCEL, not calling your function anymore! So be sure to return True everywhere, one that you miss and your application will not behave as expected.

def my_timer():
    if some_thing():
        return   # WATCH OUT! it will stop running! (maybe desired, use False to make it explicit)
    print "my_timer!"
    if other_thing():
       return True # explicit: keep running
    else:
       return False # explicit: stop running