diff options
author | Paul Pogonyshev <pogonyshev@gmx.net> | 2008-07-14 18:19:25 +0000 |
---|---|---|
committer | Paul Pogonyshev <paulp@src.gnome.org> | 2008-07-14 18:19:25 +0000 |
commit | eeac05d5cbd42308c33e777aecbf00595256519d (patch) | |
tree | 3400ea9d0fb8e6b62fe317a5e77424164433d221 | |
parent | 5905589cd3e35d4e1fe11f60d56560936be7ae8c (diff) | |
download | pygobject-eeac05d5cbd42308c33e777aecbf00595256519d.tar.gz pygobject-eeac05d5cbd42308c33e777aecbf00595256519d.tar.xz pygobject-eeac05d5cbd42308c33e777aecbf00595256519d.zip |
New class. (MethodDefBase.__init__): Make 'self.ret' a 'ReturnType'
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.
svn path=/trunk/; revision=796
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | codegen/argtypes.py | 11 | ||||
-rw-r--r-- | codegen/definitions.py | 18 | ||||
-rw-r--r-- | codegen/reversewrapper.py | 34 |
4 files changed, 65 insertions, 10 deletions
@@ -1,5 +1,17 @@ 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. + * pygobject-2.0.pc.in: Add 'codegendir' variable. * codegen/pygtk-codegen-2.0.in: Make 'codegendir' refer to PyGObject's codegen, not PyGTK's one --- the latter will be diff --git a/codegen/argtypes.py b/codegen/argtypes.py index 061c6f8..9230193 100644 --- a/codegen/argtypes.py +++ b/codegen/argtypes.py @@ -917,10 +917,19 @@ class ArgMatcher: 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 diff --git a/codegen/definitions.py b/codegen/definitions.py index 617bcbe..5da488b 100644 --- a/codegen/definitions.py +++ b/codegen/definitions.py @@ -31,6 +31,17 @@ class Parameter(object): 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 @@ class MethodDefBase(Definition): 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': diff --git a/codegen/reversewrapper.py b/codegen/reversewrapper.py index ffd50ec..ed48629 100644 --- a/codegen/reversewrapper.py +++ b/codegen/reversewrapper.py @@ -359,6 +359,8 @@ class TypeHandler(object): class ReturnType(TypeHandler): + supports_optional = False + def get_c_type(self): raise NotImplementedError @@ -479,23 +481,39 @@ argtypes.matcher.register_reverse('GObject*', GObjectParam) 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) |