pygobject r796 - in trunk: . codegen



Author: paulp
Date: Mon Jul 14 18:19:25 2008
New Revision: 796
URL: http://svn.gnome.org/viewvc/pygobject?rev=796&view=rev

Log:
2008-07-14  Paul Pogonyshev  <pogonyshev gmx net>

	* codegen/definitions.py (ReturnType): New class.
	(MethodDefBase.__init__): Make 'self.ret' a 'ReturnType' instance,
	not string.  Accept 'optional' flag.

	* codegen/argtypes.py (ArgMatcher.get_reverse_ret): Test if
	'ptype' has true 'optional' attribute and copy it to 'props' then.

	* codegen/reversewrapper.py (ReturnType.support_optional): New
	class field, False by default.
	(GObjectReturn.support_optional, GObjectReturn.write_decl)
	(GObjectReturn.write_conversion): Support optional return.


Modified:
   trunk/ChangeLog
   trunk/codegen/argtypes.py
   trunk/codegen/definitions.py
   trunk/codegen/reversewrapper.py

Modified: trunk/codegen/argtypes.py
==============================================================================
--- trunk/codegen/argtypes.py	(original)
+++ trunk/codegen/argtypes.py	Mon Jul 14 18:19:25 2008
@@ -917,10 +917,19 @@
                 return registry['GBoxed'], props
             else:
                 raise ArgTypeNotFoundError("No ArgType for %s" % (ptype,))
+
     def get_reverse(self, ptype):
         return self._get_reverse_common(ptype, self.reverse_argtypes)
+
     def get_reverse_ret(self, ptype):
-        return self._get_reverse_common(ptype, self.reverse_rettypes)
+        ret, props = self._get_reverse_common(ptype, self.reverse_rettypes)
+        if hasattr(ptype, 'optional') and ptype.optional:
+            if ret.supports_optional:
+                props['optional'] = True
+            else:
+                raise ArgTypeNotFoundError("Unsupported 'optional' for %s"
+                                           % (ptype,))
+        return ret, props
 
     def object_is_a(self, otype, parent):
         if otype == None: return 0

Modified: trunk/codegen/definitions.py
==============================================================================
--- trunk/codegen/definitions.py	(original)
+++ trunk/codegen/definitions.py	Mon Jul 14 18:19:25 2008
@@ -31,6 +31,17 @@
         if old.pnull is not None:
             self.pnull = old.pnull
 
+# We currently subclass 'str' to make impact on the rest of codegen as
+# little as possible.  Later we can subclass 'object' instead, but
+# then we must find and adapt all places which expect return types to
+# be strings.
+class ReturnType(str):
+    def __new__(cls, *args, **kwds):
+        return str.__new__(cls, *args[:1])
+    def __init__(self, type_name, optional=False):
+        str.__init__(self, type_name)
+        self.optional = optional
+
 # Parameter for property based constructors
 class Property(object):
     def __init__(self, pname, optional, argname):
@@ -297,7 +308,12 @@
             elif arg[0] == 'gtype-id':
                 self.typecode = arg[1]
             elif arg[0] == 'return-type':
-                self.ret = arg[1]
+                type_name = arg[1]
+                optional = False
+                for prop in arg[2:]:
+                    if prop[0] == 'optional':
+                        optional = True
+                self.ret = ReturnType(type_name, optional)
             elif arg[0] == 'caller-owns-return':
                 self.caller_owns_return = arg[1] in ('t', '#t')
             elif arg[0] == 'unblock-threads':

Modified: trunk/codegen/reversewrapper.py
==============================================================================
--- trunk/codegen/reversewrapper.py	(original)
+++ trunk/codegen/reversewrapper.py	Mon Jul 14 18:19:25 2008
@@ -359,6 +359,8 @@
 
 class ReturnType(TypeHandler):
 
+    supports_optional = False
+
     def get_c_type(self):
         raise NotImplementedError
 
@@ -479,23 +481,39 @@
 
 class GObjectReturn(ReturnType):
 
+    supports_optional = True
+
     def get_c_type(self):
         return self.props.get('c_type', 'GObject *')
 
     def write_decl(self):
-        self.wrapper.add_declaration("%s retval;" % self.get_c_type())
+        if not self.props.get('optional'):
+            self.wrapper.add_declaration("%s retval;" % self.get_c_type())
+        else:
+            self.wrapper.add_declaration("%s retval = NULL;" % self.get_c_type())
 
     def write_error_return(self):
         self.wrapper.write_code("return NULL;")
 
     def write_conversion(self):
-        self.wrapper.write_code(
-            code=None,
-            failure_expression="!PyObject_TypeCheck(py_retval, &PyGObject_Type)",
-            failure_exception='PyErr_SetString(PyExc_TypeError, "retval should be a GObject");')
-        self.wrapper.write_code("retval = (%s) pygobject_get(py_retval);"
-                                % self.get_c_type())
-        self.wrapper.write_code("g_object_ref((GObject *) retval);")
+        if not self.props.get('optional'):
+            self.wrapper.write_code(
+                code=None,
+                failure_expression="!PyObject_TypeCheck(py_retval, &PyGObject_Type)",
+                failure_exception='PyErr_SetString(PyExc_TypeError, "retval should be a GObject");')
+            self.wrapper.write_code("retval = (%s) pygobject_get(py_retval);"
+                                    % self.get_c_type())
+            self.wrapper.write_code("g_object_ref((GObject *) retval);")
+        else:
+            self.wrapper.write_code(
+                code=None,
+                failure_expression="py_retval != Py_None && !PyObject_TypeCheck(py_retval, &PyGObject_Type)",
+                failure_exception='PyErr_SetString(PyExc_TypeError, "retval should be None or a GObject");')
+            self.wrapper.write_code("if (py_retval != Py_None) {\n"
+                                    "    retval = (%s) pygobject_get(py_retval);\n"
+                                    "    g_object_ref((GObject *) retval);\n"
+                                    "}\n"
+                                    % self.get_c_type())
 
 argtypes.matcher.register_reverse_ret('GObject*', GObjectReturn)
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]