kuuko pushed a commit to branch master.

commit 4d9c1c929ad2c46f6879d41d4684a1514ead6565
Author: Kai Huuhko <[email protected]>
Date:   Thu Mar 28 16:49:37 2013 +0000

    Handle exceptions in eo cdef functions, don't expose _METHOD_DEPRECATED
    to Python API needlesly, add some code optimizations and TODOs.
---
 efl/elementary/genlist.pyx   |   4 +-
 efl/elementary/label.pyx     |  10 +--
 efl/eo/efl.eo.pyx            | 183 +++++++++++++++++++++++++------------------
 efl/evas/efl.evas_object.pxi |   2 +-
 include/efl.eo.pxd           |  13 +--
 5 files changed, 120 insertions(+), 92 deletions(-)

diff --git a/efl/elementary/genlist.pyx b/efl/elementary/genlist.pyx
index df5a85f..b9def85 100644
--- a/efl/elementary/genlist.pyx
+++ b/efl/elementary/genlist.pyx
@@ -149,7 +149,7 @@ include "widget_header.pxi"
 include "callback_conversions.pxi"
 include "tooltips.pxi"
 
-from efl.eo import _METHOD_DEPRECATED
+from efl.eo cimport _METHOD_DEPRECATED
 
 from object_item cimport    ObjectItem, \
                             _object_item_to_python, \
@@ -317,7 +317,7 @@ class GenlistItemsCount(int):
         self.obj = obj
 
     def __call__(self):
-        _METHOD_DEPRECATED(self.obj, None, "Use items_count instead")
+        _METHOD_DEPRECATED(self.obj, "Use items_count instead.")
         return self.obj._items_count()
 
 cdef class GenlistItemClass(object):
diff --git a/efl/elementary/label.pyx b/efl/elementary/label.pyx
index 173fda4..09c1cb2 100644
--- a/efl/elementary/label.pyx
+++ b/efl/elementary/label.pyx
@@ -56,7 +56,7 @@
 include "widget_header.pxi"
 
 from layout_class cimport LayoutClass
-from efl.eo import _METHOD_DEPRECATED
+from efl.eo cimport _METHOD_DEPRECATED
 
 cimport enums
 
@@ -188,18 +188,18 @@ cdef class Label(LayoutClass):
 
         """
         def __get__(self):
-            _METHOD_DEPRECATED(self, replacement="slide_mode")
+            _METHOD_DEPRECATED(self, "Use slide_mode instead.")
             return elm_label_slide_get(self.obj)
 
         def __set__(self, slide):
-            _METHOD_DEPRECATED(self, replacement="slide_mode")
+            _METHOD_DEPRECATED(self, "Use slide_mode instead.")
             elm_label_slide_set(self.obj, slide)
 
     def slide_set(self, bint slide):
-        _METHOD_DEPRECATED(self, replacement="slide_mode")
+        _METHOD_DEPRECATED(self, "Use slide_mode instead.")
         elm_label_slide_set(self.obj, slide)
     def slide_get(self):
-        _METHOD_DEPRECATED(self, replacement="slide_mode")
+        _METHOD_DEPRECATED(self, "Use slide_mode instead.")
         return elm_label_slide_get(self.obj)
 
     property slide_duration:
diff --git a/efl/eo/efl.eo.pyx b/efl/eo/efl.eo.pyx
index 0b2abe3..48712ab 100644
--- a/efl/eo/efl.eo.pyx
+++ b/efl/eo/efl.eo.pyx
@@ -68,13 +68,15 @@ cdef char *_fruni(object s):
 
     if s is None:
         return NULL
+
     if isinstance(s, unicode):
         unistr = s
         string = unistr.encode('UTF-8')
         c_string = string
         return c_string
     elif isinstance(s, str):
-        return s
+        c_string = s
+        return c_string
     else:
         raise TypeError("Expected str or unicode object, got %s" % 
(type(s).__name__))
 
@@ -87,18 +89,20 @@ cdef const_char *_cfruni(object s):
     """
     cdef:
         const_char *c_string
-        str string
+        bytes string
         unicode unistr
 
     if s is None:
         return NULL
+
     if isinstance(s, unicode):
         unistr = s
         string = unistr.encode('UTF-8')
         c_string = string
         return c_string
     elif isinstance(s, str):
-        return s
+        c_string = s
+        return c_string
     else:
         raise TypeError("Expected str or unicode object, got %s" % 
(type(s).__name__))
 
@@ -109,16 +113,17 @@ cdef list convert_array_of_strings_to_python_list(char 
**array, int array_length
     Converts an array of strings to a python list.
 
     """
-    cdef char *string
+    cdef:
+        char *string
+        list ret = list()
 
-    ret = []
     for i in range(array_length):
         string = array[i]
         ret.append(_touni(string))
     return ret
 
 
-cdef const_char ** convert_python_list_strings_to_array_of_strings(list 
strings):
+cdef const_char ** convert_python_list_strings_to_array_of_strings(list 
strings) except NULL:
     """
 
     Converts a python list to an array of strings.
@@ -127,12 +132,13 @@ cdef const_char ** 
convert_python_list_strings_to_array_of_strings(list strings)
 
     """
     cdef:
-        const_char **array
+        const_char **array = NULL
         unsigned int arr_len = len(strings)
         const_char *string
         unsigned int str_len
         unsigned int i
 
+    # TODO: Should we just return NULL in this case?
     if len(strings) is 0:
         array = <const_char **>malloc(sizeof(const_char*))
         if not array:
@@ -162,7 +168,7 @@ cdef list 
convert_eina_list_strings_to_python_list(const_Eina_List *lst):
     return ret
 
 
-cdef Eina_List * convert_python_list_strings_to_eina_list(strings):
+cdef Eina_List *convert_python_list_strings_to_eina_list(strings):
     cdef Eina_List *lst = NULL
     for s in strings:
         lst = eina_list_append(lst, strdup(_cfruni(s)))
@@ -170,29 +176,30 @@ cdef Eina_List * 
convert_python_list_strings_to_eina_list(strings):
 
 
 cdef list _object_list_to_python(const_Eina_List *lst):
-    ret = []
+    cdef list ret = list()
     while lst:
         ret.append(object_from_instance(<cEo *>lst.data))
         lst = lst.next
     return ret
 
 
-def _METHOD_DEPRECATED(self, replacement=None, message=None):
+cdef void _METHOD_DEPRECATED(object self, char *message):
+    cdef:
+        object stack
+        tuple caller
+        str msg
+
     stack = traceback.extract_stack()
     caller = stack[-1]
     caller_module, caller_line, caller_name, caller_code = caller
-    if caller_code:
-        msg = "%s:%s %s (class %s) is deprecated." % \
+    if caller_code is not None:
+        msg = "%s:%s %s (class %s) is deprecated. %s" % \
             (caller_module, caller_line, caller_code,
-            self.__class__.__name__ if self else 'None')
+            type(self).__name__, message)
     else:
-        msg = "%s:%s %s.%s() is deprecated." % \
+        msg = "%s:%s %s.%s() is deprecated. %s" % \
             (caller_module, caller_line,
-            self.__class__.__name__ if self else 'None', caller_name)
-    if replacement:
-        msg += " Use %s() instead." % (replacement,)
-    if message:
-        msg += " " + message
+            type(self).__name__, caller_name, message)
 #     log.warn(msg)
     print(msg)
 
@@ -200,56 +207,59 @@ def _METHOD_DEPRECATED(self, replacement=None, 
message=None):
 ######################################################################
 
 
-cdef object object_mapping
 """Object mapping is a dictionary into which object type names can be
 registered. These can be used to find a bindings class for an object using
 the object_from_instance function."""
-object_mapping = dict()
+# TODO: As a further optimization, make this C only, probably Eina Hash table.
+cdef dict object_mapping = dict()
 
 
-cdef _object_mapping_register(char *name, cls):
-#     print("REGISTER: %s => %s" % (name, cls))
+cdef void _object_mapping_register(str name, object cls) except *:
+#    print("REGISTER: %s => %s" % (name, cls))
     if name in object_mapping:
-        raise ValueError("object type name '%s' already registered." % name)
+        raise ValueError("Object type name '%s' already registered." % name)
     object_mapping[name] = cls
 
 
-cdef _object_mapping_unregister(char *name):
+cdef void _object_mapping_unregister(str name):
     object_mapping.pop(name)
 
 
 cdef object object_from_instance(cEo *obj):
     """ Create a python object from a C Eo object pointer. """
-    cdef void *data
-    cdef Eo o
+    cdef:
+        void *data
+        Eo o
+        const_char *cls_name
+        object cls
 
-    if obj == NULL:
+    if obj is NULL:
         return None
 
     eo_do(obj, eo_base_data_get("python-eo", &data))
-    if data != NULL:
+    if data is not NULL:
 #         print("Found: %s" % Eo.__repr__(<Eo>data))
         return <Eo>data
 
-    klass_name = eo_class_name_get(eo_class_get(obj))
-    if klass_name == NULL:
+    cls_name = eo_class_name_get(eo_class_get(obj))
+    if cls_name is NULL:
         raise ValueError("Eo object %#x does not have a type!" % <long>obj)
-#     print("Klass name: %s" % klass_name)
+#     print("Class name: %s" % cls_name)
 
-    klass = object_mapping.get(klass_name, None)
-    if klass == None:
+    cls = object_mapping.get(cls_name, None)
+    if cls is None:
         raise ValueError("Eo object %#x of type %s does not have a mapping!" %
-                         (<long>obj, klass_name))
+                         (<long>obj, cls_name))
 
-#     print "MAPPING OBJECT:", klass_name, "=>", klass
-    o = klass.__new__(klass)
+#     print "MAPPING OBJECT:", cls_name, "=>", cls
+    o = cls.__new__(cls)
     o._set_obj(obj)
     return o
 #
 # TODO extended object mapping (for SmartObject, EdjeExternal, etc)
 #
 #         t = evas_object_type_get(obj)
-#         if t == NULL:
+#         if t is NULL:
 #             raise ValueError("Evas object %#x does not have a type!" %
 #                              <long>obj)
 #         ot = _ctouni(t)
@@ -272,8 +282,13 @@ cdef object object_from_instance(cEo *obj):
 ######################################################################
 
 
-EO_CALLBACK_STOP = 0
-EO_CALLBACK_CONTINUE = 1
+# TODO: Move these to enums.pxd
+cdef:
+    int C_EO_CALLBACK_STOP = 0
+    int C_EO_CALLBACK_CONTINUE = 1
+
+EO_CALLBACK_STOP = C_EO_CALLBACK_STOP
+EO_CALLBACK_CONTINUE = C_EO_CALLBACK_CONTINUE
 
 
 ######################################################################
@@ -288,7 +303,7 @@ cdef Eina_Bool _eo_event_del_cb(void *data, cEo *obj, 
const_Eo_Event_Description
     self.obj = NULL
     Py_DECREF(self)
 
-    return EO_CALLBACK_STOP
+    return C_EO_CALLBACK_STOP
 
 
 cdef class Eo(object):
@@ -303,27 +318,29 @@ cdef class Eo(object):
         self.obj = NULL
         self.data = dict()
 
-    def __init__(self):
-#         print("Eo __init__()")
-        pass
+#    def __init__(self):
+#        print("Eo __init__()")
 
     def __dealloc__(self):
-#         print("Eo __dealloc__(): %s" % Eo.__repr__(self))
+#         print("Eo __dealloc__(): %s" % self.__repr__())
         self.data.clear()
 
     def __str__(self):
         return ("Eo(class=%s, obj=%#x, parent=%#x, refcount=%d)") % \
-                (self.__class__.__name__, <unsigned long>self.obj,
-                 <unsigned long>eo_parent_get(self.obj) if self.obj else 0,
+                (type(self).__name__, <unsigned long>self.obj,
+                 <unsigned long>eo_parent_get(self.obj) if self.obj is not 
NULL else 0,
                  PY_REFCOUNT(self))
 
 
     def __repr__(self):
         return ("Eo(class=%s, obj=%#x, parent=%#x, refcount=%d)") % \
-                (self.__class__.__name__, <unsigned long>self.obj,
-                 <unsigned long>eo_parent_get(self.obj) if self.obj else 0,
+                (type(self).__name__, <unsigned long>self.obj,
+                 <unsigned long>eo_parent_get(self.obj) if self.obj is not 
NULL else 0,
                  PY_REFCOUNT(self))
 
+#
+# TODO
+#
 #     cdef _add_obj(self, Eo_Class *klass, cEo *parent):
 #         cdef cEo *obj
 #         assert self.obj == NULL, "Object must be clean"
@@ -331,49 +348,59 @@ cdef class Eo(object):
 #         self._set_obj(obj)
 #         eo_unref(obj)
 
-    cdef _set_obj(self, cEo *obj):
-        assert self.obj == NULL, "Object must be clean"
-        assert obj != NULL, "Cannot set a NULL object"
+    cdef void _set_obj(self, cEo *obj) except *:
+        assert self.obj is NULL, "Object must be clean"
+        assert obj is not NULL, "Cannot set a NULL object"
 
         self.obj = obj
         eo_do(self.obj, eo_base_data_set("python-eo", <void *>self, NULL))
         eo_do(self.obj, eo_event_callback_add(EO_EV_DEL, _eo_event_del_cb, 
<const_void *>self))
         Py_INCREF(self)
 
-#     cdef _unset_obj(self): # __UNUSED__
-#         if self.obj != NULL:
-#             self.obj = NULL
-#             Py_DECREF(self) ????????????????????'
-        # TODO evas_object_data_del("python-eo") ??
-
-#     def delete(self):
-#         """
-#         Delete object and free it's internal (wrapped) resources.
 #
-#         @note: after this operation the object will be still alive in
-#             Python, but it will be shallow and every operation
-#             will have no effect (and may raise exceptions).
-#         @raise ValueError: if object already deleted.
-#         """
-#         if self.obj == NULL:
-#             raise ValueError("Object already deleted")
-#         print("Eo delete: %s" % Eo.__repr__(self))
-#         eo_del(self.obj)
-
+# TODO: Are these two functions broken somehow?
+#
+#    cdef void _unset_obj(self):
+#        if self.obj is not NULL:
+#            self.obj = NULL
+#        Py_DECREF(self)
+#        eo_do(self.obj, eo_base_data_del("python-eo"))
+#
+#    def delete(self):
+#        """
+#        Delete object and free it's internal (wrapped) resources.
+#
+#        @note: after this operation the object will be still alive in
+#        Python, but it will be shallow and every operation
+#        will have no effect (and may raise exceptions).
+#        @raise ValueError: if object already deleted.
+#        """
+#        if self.obj is NULL:
+#            raise ValueError("Object already deleted")
+#        print("Eo delete: %s" % self.__repr__())
+#        eo_del(self.obj)
+
+    property is_valid:
+        """Whether the Eo C object associated with this python object is 
valid."""
+        def __get__(self):
+            return self.obj is not NULL
+
+    # TODO: Remove this if not needed
     def is_deleted(self):
-        """
-        Check if the Eo object associated with this python object has been
-        deleted, thus leaving the object as shallow.
-        """
         return bool(self.obj == NULL)
 
-
+#
+# TODO: Automate these
+#
+# Call eo_init and put eo_shutdown to atexit, and don't expose in our API.
+#
+# Do the same in other packages as well, making sure the packages main
+# module is always imported.
+#
 def init():
     return eo_init()
 
-
 def shutdown():
     return eo_shutdown()
 
-
 init()
diff --git a/efl/evas/efl.evas_object.pxi b/efl/evas/efl.evas_object.pxi
index da564af..2b94ee3 100644
--- a/efl/evas/efl.evas_object.pxi
+++ b/efl/evas/efl.evas_object.pxi
@@ -188,7 +188,7 @@ cdef class Object(Eo):
                  self.__class__.__name__, name_str, x, y, w, h,
                  r, g, b, a, self.layer_get(), clip, self.visible_get())
 
-    cdef _set_obj(self, Evas_Object *obj):
+    cdef void _set_obj(self, Evas_Object *obj) except *:
         Eo._set_obj(self, obj)
         evas_object_event_callback_add(obj, EVAS_CALLBACK_FREE,
                                        obj_free_cb, <void *>self)
diff --git a/include/efl.eo.pxd b/include/efl.eo.pxd
index e3a7c3b..41dbc9a 100644
--- a/include/efl.eo.pxd
+++ b/include/efl.eo.pxd
@@ -22,18 +22,18 @@ from libc.string cimport const_char
 
 cdef class Eo(object):
     cdef cEo *obj
-    cdef readonly data
+    cdef readonly dict data
 
-    cdef _set_obj(self, cEo *obj)
-#    cdef _unset_obj(self)
+    cdef void _set_obj(self, cEo *obj) except *
+#    cdef void *_unset_obj(self)
 #    cdef _add_obj(self, Eo_Class *klass, cEo *parent)
 
 
 cdef int PY_REFCOUNT(object o)
 
 cdef object object_from_instance(cEo *obj)
-cdef _object_mapping_register(char *name, klass)
-cdef _object_mapping_unregister(char*name)
+cdef void _object_mapping_register(str name, object cls) except *
+cdef void _object_mapping_unregister(str name)
 
 cdef unicode _touni(char* s)
 cdef char* _fruni(s)
@@ -41,7 +41,8 @@ cdef unicode _ctouni(const_char *s)
 cdef const_char *_cfruni(s)
 
 cdef list convert_array_of_strings_to_python_list(char **array, int 
array_length)
-cdef const_char ** convert_python_list_strings_to_array_of_strings(list 
strings)
+cdef const_char ** convert_python_list_strings_to_array_of_strings(list 
strings) except NULL
 cdef list convert_eina_list_strings_to_python_list(const_Eina_List *lst)
 cdef Eina_List * convert_python_list_strings_to_eina_list(strings)
 cdef list _object_list_to_python(const_Eina_List *lst)
+cdef void _METHOD_DEPRECATED(object self, char *message)

-- 

------------------------------------------------------------------------------
Own the Future-Intel&reg; Level Up Game Demo Contest 2013
Rise to greatness in Intel's independent game demo contest.
Compete for recognition, cash, and the chance to get your game 
on Steam. $5K grand prize plus 10 genre and skill prizes. 
Submit your demo by 6/6/13. http://p.sf.net/sfu/intel_levelupd2d

Reply via email to