--- gnome-python/pygobject/examples/option.py	1970-01-01 01:00:00.000000000 +0100
+++ gnome-python-new/pygobject/examples/option.py	2006-04-26 12:44:33.000000000 +0200
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+# gnome-python/pygobject/examples/option.py
+
+from gobject.option import OptionGroup, OptionParser, make_option
+
+group = OptionGroup("example", "OptionGroup Example", "Shows all example options",
+    option_list = [
+        make_option("--example", 
+                    action="store_true", 
+                    dest="example", 
+                    help="An example option."),
+    ])
+
+parser = OptionParser("NAMES ...", 
+    description="A simple gobject.option example.",
+    option_list = [
+        make_option("--file", "-f", 
+                    type="filename", 
+                    action="store", 
+                    dest="file",
+                    help="A filename option"),
+        # ...
+    ])
+
+parser.add_option_group(group)
+
+parser.parse_args()
+
+print "group: example ", group.values.example
+print "parser: file", parser.values.file
--- gnome-python/pygobject/examples/Makefile.am	2006-04-26 18:18:46.000000000 +0200
+++ gnome-python-new/pygobject/examples/Makefile.am	2006-04-17 23:05:22.000000000 +0200
@@ -1 +1,2 @@
-EXTRA_DIST = properties.py signal.py
+EXTRA_DIST = properties.py signal.py option.py
+
--- gnome-python/pygobject/gobject/option.py	1970-01-01 01:00:00.000000000 +0100
+++ gnome-python-new/pygobject/gobject/option.py	2006-04-26 12:54:28.000000000 +0200
@@ -0,0 +1,317 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# pygobject - Python bindings for the GObject library
+# Copyright (C) 2006  Johannes Hoelzl
+#
+#   gobject/option.py: GOption command line parser 
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA
+
+"""GOption command line parser
+
+Extends optparse to use the GOptionGroup, GOptionEntry and GOptionContext
+objects. So it is possible to use the gtk, gnome_program and gstreamer command
+line groups and contexts.
+
+Use this interface instead of the raw wrappers of GOptionContext and
+GOptionGroup in gobject.
+"""
+
+import sys
+import optparse
+from optparse import OptionError
+import _gobject as gobject
+
+__all__ = [
+    "OptionError",
+    "Option",
+    "OptionGroup",
+    "OptionParser",
+    "make_option",
+]
+
+class Option(optparse.Option):
+    """Represents a command line option
+
+    To use the extended possibilities of the GOption API Option
+    (and make_option) are extended with new types and attributes.
+
+    Types:
+        filename   The supplied arguments are read as filename, GOption
+                   parses this type in with the GLib filename encoding.
+
+    Attributes:
+        optional_arg  This does not need a arguement, but it can be supplied.
+        hidden        The help list does not show this option
+        in_main       This option apears in the main group, this should only
+                      be used for backwards compatibility.
+
+    Use Option.REMAINING as option name to get all positional arguments.
+
+    NOTE: Every argument to an option is passed as utf-8 coded string, the only
+          exception are options which use the 'filename' type, its arguments
+          are passed as strings in the GLib filename encoding.
+
+    For further help, see optparse.Option.
+    """
+    TYPES = optparse.Option.TYPES + (
+        'filename', 
+    )
+
+    ATTRS = optparse.Option.ATTRS + [
+        'hidden',
+        'in_main',
+        'optional_arg',
+    ]
+
+    REMAINING = '--' + gobject.OPTION_REMAINING
+
+    def __init__(self, *args, **kwargs):
+        optparse.Option.__init__(self, *args, **kwargs)
+        if not self._long_opts:
+            raise ValueError("%s at least one long option name.")
+
+        if len(self._long_opts) < len(self._short_opts):
+            raise ValueError("%s at least more long option names than short option names.")
+        
+        if not self.help:
+            raise ValueError("%s needs a help message.", self._long_opts[0])
+
+    
+    def _set_opt_string(self, opts):
+        if self.REMAINING in opts:
+            self._long_opts.append(self.REMAINING)
+        optparse.Option._set_opt_string(self, opts)
+        if len(self._short_opts) > len(self._long_opts):
+            raise OptionError("goption.Option needs more long option names "
+                              "than short option names")
+
+    def _to_goptionentries(self):
+        flags = 0
+        
+        if self.hidden:
+            self.flags |= gobject.OPTION_FLAG_HIDDEN
+        
+        if self.in_main:
+            self.flags |= gobject.OPTION_FLAG_IN_MAIN
+        
+        if self.takes_value():
+            if self.optional_arg:
+                flags |= gobject.OPTION_FLAG_OPTIONAL_ARG
+        else:
+            flags |= gobject.OPTION_FLAG_NO_ARG
+            
+        if self.type == 'filename':
+            flags |= gobject.OPTION_FLAG_FILENAME
+
+        for (long_name, short_name) in zip(self._long_opts, self._short_opts):
+            yield (long_name[2:], short_name[1], flags, self.help, self.metavar)
+            
+        for long_name in self._long_opts[len(self._short_opts):]:
+            yield (long_name[2:], '\0', flags, self.help, self.metavar)
+
+class OptionGroup(optparse.OptionGroup):
+    """A group of command line options.
+
+    Arguements:
+       name:             The groups name, used to create the --help-{name} option
+       description:      Shown as title of the groups help view
+       help_description: Shown as help to the --help-{name} option
+       option_list:      The options used in this group, must be option.Option()
+       defaults:         A dicitionary of default values
+       pre_hook:         Gets called before the first option is parsed.
+       post_hook:        Gets called after the last option is parsed.
+       error_hook:       Gets called when an error occurs.
+       translation_domain: Sets the translation domain for gettext().
+       translation_func: Translates strings for the user visible strings for
+                         --help output. If you are using gettext(), you only
+                         need to set the translation domain.
+
+    NOTE: This OptionGroup does not exactly map the optparse.OptionGroup
+          interface. There is no parser object to supply, but it is possible
+          to set default values and option_lists. Also the default values and
+          values are not shared with the OptionParser.
+
+    To pass a OptionGroup into a function which expects a GOptionGroup (e.g.
+    gnome_program_init() ). OptionGroup.get_option_group() can be used.
+
+    For further help, see optparse.OptionGroup.
+    """
+    def __init__(self, name, description, help_description="", 
+                 option_list=None, defaults=None,
+                 pre_hook=None, post_hook=None, error_hook=None,
+                 translation_domain=None, translate_func=None):
+        optparse.OptionContainer.__init__(self, Option, 'error', description)
+        self.name = name
+        self.parser = None
+        self.help_description = help_description
+        if defaults:
+            self.defaults = defaults
+        
+        self.values = None
+
+        self.pre_hook = pre_hook
+        self.post_hook = post_hook
+        self.error_hook = error_hook
+        self.translation_domain = translation_domain
+        self.translate_func = translate_func
+        
+        for option in option_list:
+            self.add_option(option)
+    
+    def _create_option_list(self):
+        self.option_list = []
+        self._create_option_mappings()
+        
+    def _to_goptiongroup(self, parser):
+        def callback(option_name, option_value, group):
+            if option_name.startswith('--'):
+                opt = self._long_opt[option_name]
+            else:            
+                opt = self._short_opt[option_name]
+            opt.process(option_name, option_value, self.values, parser)
+                
+        group = gobject.OptionGroup(self.name, self.description, 
+                                    self.help_description, callback)
+        if self.pre_hook or self.post_hook:
+            group.set_parse_hooks(lambda g, arg:self.pre_hook(self), lambda g, arg:self.post_hook(self))
+        if self.error_hook:
+            group.set_error_hook(lambda g, arg:self.error_hook(self))
+        if self.translate_func:
+            group.set_translate_func(lambda s, g, arg: self.translate_func(s, self))
+        if self.translation_domain:
+            group.set_translation_domain(self.translation_domain)
+        
+        entries = []
+        for option in self.option_list:
+            entries.extend(option._to_goptionentries())
+        group.add_entries(entries)
+        
+        return group
+    
+    def get_option_group(self, parser = None):
+        """ Returns the corresponding GOptionGroup object.
+        
+        Can be used as parameter for gnome_program_init(), gtk_init().
+        """
+        self.set_values_to_defaults()
+        return self._to_goptiongroup(parser)
+
+    def set_values_to_defaults(self):
+        for option in self.option_list:
+            default = self.defaults.get(option.dest)
+            if isinstance(default, basestring):
+                opt_str = option.get_opt_string()
+                self.defaults[option.dest] = option.check_value(opt_str, default)
+        self.values = optparse.Values(self.defaults)
+    
+class OptionParser(optparse.OptionParser):
+    """Command line parser with GOption support.
+
+    NOTE: The OptionParser interface is not the exactly the same as the
+          optparse.OptionParser interface. Especially the usage parameter
+          is only used to show the metavar of the arguements.
+
+    Attribues:
+        help_enabled:           The --help, --help-all and --help-{group}
+                                options are enabled (default).
+        ignore_unknown_options: Do not throw a exception when a option is not
+                                knwon, the option will be in the result list.
+    
+    OptionParser.add_option_group() does not only accept OptionGroup instances
+    but also gobject.OptionGroup, which is returned by gtk_get_option_group().
+
+    Only gobject.option.OptionGroup and gobject.option.Option instances should
+    be passed as groups and options.
+
+    For further help, see optparse.OptionParser.
+    """
+    
+    def __init__(self, *args, **kwargs):
+        if 'option_class' not in kwargs:
+            kwargs['option_class'] = Option
+        self.help_enabled = kwargs.pop('help_enabled', True)
+        self.ignore_unknown_options = kwargs.pop('ignore_unknown_options', False)
+        optparse.OptionParser.__init__(self, add_help_option=False, *args, **kwargs)
+        
+    def set_usage(self, usage):
+        if usage is None:
+            self.usage = ''
+        elif usage.startswith("%prog"):
+            self.usage = usage[len("%prog"):]
+        else:
+            self.usage = usage
+
+    def _to_goptioncontext(self, values):
+        if self.description:
+            parameter_string = self.usage + " - " + self.description
+        else:
+            parameter_string = self.usage
+        context = gobject.OptionContext(parameter_string)
+        context.set_help_enabled(self.help_enabled)
+        context.set_ignore_unknown_options(self.ignore_unknown_options)
+        
+        for option_group in self.option_groups:
+            if isinstance(option_group, gobject.OptionGroup):
+                g_group = option_group
+            else:
+                g_group = option_group.get_option_group(self)
+            context.add_group(g_group)
+
+        def callback(option_name, option_value, group):
+            if option_name.startswith('--'):
+                opt = self._long_opt[option_name]
+            else:
+                opt = self._short_opt[option_name]
+            opt.process(option_name, option_value, values, self)
+
+        main_group = gobject.OptionGroup(None, None, None, callback)
+        main_entries = []
+        for option in self.option_list:
+            main_entries.extend(option._to_goptionentries())
+        main_group.add_entries(main_entries)
+        context.set_main_group(main_group)
+
+        return context
+    
+    def add_option_group(self, *args, **kwargs):
+        if isinstance(args[0], basestring):
+            optparse.OptionParser.add_option_group(self,
+                OptionGroup(self, *args, **kwargs))
+            return
+        elif len(args) == 1 and not kwargs:
+            if isinstance(args[0], OptionGroup):
+                if not args[0].parser:
+                    args[0].parser = self
+                if args[0].parser is not self:
+                    raise ValueError("invalid OptionGroup (wrong parser)")
+            if isinstance(args[0], gobject.OptionGroup):
+                self.option_groups.append(args[0])
+                return
+        optparse.OptionParser.add_option_group(self, *args, **kwargs)
+
+    def _get_all_options(self):
+        options = self.option_list[:]
+        for group in self.option_groups:
+            if isinstance(group, optparse.OptionGroup):
+                options.extend(group.option_list)
+        return options
+    
+    def _process_args(self, largs, rargs, values):
+        context = self._to_goptioncontext(values)
+        largs.extend(context.parse([sys.argv[0]] + rargs))
+
+
+make_option = Option
--- gnome-python/pygobject/tests/test_option.py	1970-01-01 01:00:00.000000000 +0100
+++ gnome-python-new/pygobject/tests/test_option.py	2006-04-26 12:47:31.000000000 +0200
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+
+import unittest
+
+from common import gobject
+from gobject import option
+
+class TestOption(unittest.TestCase):
+
+    def setup_group(self):
+        def pre_hook(group):
+            group.events.append('pre')
+        def post_hook(group):
+            group.events.append('post')
+        def error_hook(group):
+            group.events.append('error')
+        group = option.OptionGroup(
+            "unittest", "Unit test options", "Show all unittest options",
+            option_list = [
+                option.make_option("-f", "-u", "--file", "--unit-file",
+                                   type="filename",
+                                   dest="unit_file",
+                                   help="Unit test option"),
+            ], pre_hook = pre_hook, post_hook = post_hook)
+        group.add_option("-t", "--test", 
+                         action="store_false", 
+                         dest="test", 
+                         default=True,
+                         help="Unit test option")
+        group.events = []
+        return group
+
+    def setup_parser(self):
+        parser = option.OptionParser("NAMES...", description="Option unit test")
+        parser.add_option("-t", "--test", help="Unit test option",
+                          action="store_false", dest="test", default=True)
+        return parser
+    
+    def testOption(self):
+        parser = self.setup_parser()
+        group = self.setup_group()
+        parser.add_option_group(group)
+
+        parser.parse_args(["test_option.py", "--test", "-f", "test"])
+        assert group.values.test
+        assert not parser.values.test
+        assert group.values.unit_file == "test"
+        assert group.events == ['pre', 'post']
--- gnome-python/pygobject/gobject/pygobject-private.h	2006-04-26 18:18:46.000000000 +0200
+++ gnome-python-new/pygobject/gobject/pygobject-private.h	2006-04-26 12:11:13.000000000 +0200
@@ -217,4 +217,28 @@ typedef struct
 } PyGPollFD;
 
 
+/* pygoption.c */
+extern PyTypeObject PyGOptionContext_Type;
+extern PyTypeObject PyGOptionGroup_Type;
+
+typedef struct {
+    PyObject_HEAD
+    GOptionGroup *group;
+    gboolean other_owner, is_in_context;
+    PyObject *callback, *pre_hook_cb, *post_hook_cb, *error_hook_cb, 
+             *translate_func_cb;
+    GSList *strings; /* all strings added with the entries, are freed on 
+                        GOptionGroup.destroy() */
+} PyGOptionGroup;
+
+typedef struct {
+    PyObject_HEAD
+    PyGOptionGroup *main_group;
+    GOptionContext *context;
+} PyGOptionContext;
+
+PyObject * pyg_option_context_new (GOptionContext * context);
+PyObject * pyg_option_group_new (GOptionGroup * group);
+GOptionGroup *pyg_option_group_transfer_group(PyGOptionGroup *self);
+
 #endif
--- gnome-python/pygobject/gobject/pygoptioncontext.c	1970-01-01 01:00:00.000000000 +0100
+++ gnome-python-new/pygobject/gobject/pygoptioncontext.c	2006-04-26 12:39:03.000000000 +0200
@@ -0,0 +1,332 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * pygtk- Python bindings for the GTK toolkit.
+ * Copyright (C) 2006  Johannes Hoelzl
+ *
+ *   pygoptioncontext.c: GOptionContext wrapper
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include "pygobject-private.h"
+
+static int
+pyg_option_context_init(PyGOptionContext *self, 
+                        PyObject *args,
+                        PyObject *kwargs)
+{
+    char *parameter_string;
+    if (!PyArg_ParseTuple(args, "s:gobject.GOptionContext.__init__",
+                          &parameter_string))
+        return -1;
+    
+    self->context = g_option_context_new(parameter_string);
+    return 0;
+}
+
+static void
+pyg_option_context_dealloc(PyGOptionContext *self)
+{
+    Py_CLEAR(self->main_group);
+    
+    if (self->context != NULL)
+    {
+        GOptionContext *tmp = self->context;
+        self->context = NULL;
+        g_option_context_free(tmp);
+    }
+
+    PyObject_Del(self);
+}
+
+static PyObject *
+pyg_option_context_parse(PyGOptionContext *self, 
+                         PyObject *args, 
+                         PyObject *kwargs)
+{
+    static char *kwlist[] = { "argv", NULL };
+    PyObject *arg;
+    PyObject *new_argv, *argv;
+    gssize argv_length, pos;
+    char **argv_content, **original;
+    GError *error = NULL;
+    gboolean result;
+    
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:GOptionContext.parse", 
+                                     kwlist, &argv))
+        return NULL;
+    
+    if (!PyList_Check(argv))
+    {
+        PyErr_SetString(PyExc_TypeError, 
+                        "GOptionContext.parse expects a list of strings.");
+        return NULL;
+    }
+    
+    argv_length = PyList_Size(argv);
+    if (argv_length == -1)
+    {
+        PyErr_SetString(PyExc_TypeError, 
+                        "GOptionContext.parse expects a list of strings.");
+        return NULL;
+    }
+    
+    argv_content = g_new(char*, argv_length + 1);
+    argv_content[argv_length] = NULL;
+    for (pos = 0; pos < argv_length; pos++)
+    {
+        arg = PyList_GetItem(argv, pos);
+        argv_content[pos] = g_strdup(PyString_AsString(arg));
+        if (argv_content[pos] == NULL)
+        {
+            g_strfreev(argv_content);
+            return NULL;
+        }
+    }
+    original = g_strdupv(argv_content);
+    
+    pyg_begin_allow_threads;
+    result = g_option_context_parse(self->context, &argv_length, &argv_content,
+                                    &error);
+    pyg_end_allow_threads;
+
+    if (!result)
+    {
+        g_free(argv_content);
+        g_strfreev(original);
+        pyg_error_check(&error);
+        return NULL;
+    }
+    
+    new_argv = PyList_New(g_strv_length(argv_content));
+    for (pos = 0; pos < argv_length; pos++)
+    {
+        arg = PyString_FromString(argv_content[pos]);
+        PyList_SetItem(new_argv, pos, arg);
+    }
+    
+    g_strfreev(original);
+    g_free(argv_content);
+    return new_argv;
+}
+
+static PyObject *
+pyg_option_context_set_help_enabled(PyGOptionContext *self, 
+                                    PyObject *args,
+                                    PyObject *kwargs)
+{
+    static char *kwlist[] = { "help_enable", NULL };
+    PyObject *help_enabled;
+    if (! PyArg_ParseTupleAndKeywords(args, kwargs, 
+                                      "O:GOptionContext.set_help_enabled", 
+                                      kwlist, &help_enabled))
+        return NULL;
+    g_option_context_set_help_enabled(self->context, PyObject_IsTrue(help_enabled));
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+pyg_option_context_get_help_enabled(PyGOptionContext *self)
+{
+    return PyBool_FromLong(g_option_context_get_help_enabled(self->context));
+}
+
+static PyObject *
+pyg_option_context_set_ignore_unknown_options(PyGOptionContext *self, 
+                                              PyObject *args,
+                                              PyObject *kwargs)
+{
+    static char *kwlist[] = { "ignore_unknown_options", NULL };
+    PyObject *ignore_unknown_options;
+    if (! PyArg_ParseTupleAndKeywords(args, kwargs, 
+                                "O:GOptionContext.set_ignore_unknown_options", 
+                                kwlist, &ignore_unknown_options))
+        return NULL;
+    g_option_context_set_ignore_unknown_options(self->context, 
+                            PyObject_IsTrue(ignore_unknown_options));
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+pyg_option_context_get_ignore_unknown_options(PyGOptionContext *self)
+{
+    return PyBool_FromLong(
+        g_option_context_get_ignore_unknown_options(self->context));
+}
+
+static PyObject *
+pyg_option_context_set_main_group(PyGOptionContext *self, 
+                                  PyObject *args, 
+                                  PyObject *kwargs)
+{
+    static char *kwlist[] = { "group", NULL };
+    GOptionGroup *g_group;
+    PyObject *group;
+    if (! PyArg_ParseTupleAndKeywords(args, kwargs, 
+                                      "O:GOptionContext.set_main_group", 
+                                      kwlist, &group))
+        return NULL;
+    if (PyObject_IsInstance(group, (PyObject*) &PyGOptionGroup_Type) != 1) {
+        PyErr_SetString(PyExc_TypeError, 
+                        "GOptionContext.set_main_group expects a GOptionGroup.");
+        return NULL;
+    }
+    g_group = pyg_option_group_transfer_group((PyGOptionGroup*) group);
+    if (g_group == NULL)
+    {
+        PyErr_SetString(PyExc_RuntimeError, "Group is already in a OptionContext.");
+        return NULL;
+    }
+
+    g_option_context_set_main_group(self->context, g_group);
+    Py_INCREF(group);
+    self->main_group = (PyGOptionGroup*) group;
+    
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+pyg_option_context_get_main_group(PyGOptionContext *self)
+{
+    if (self->main_group == NULL)
+    {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }        
+    Py_INCREF(self->main_group);
+    return (PyObject*) self->main_group;
+}
+
+static PyObject *
+pyg_option_context_add_group(PyGOptionContext *self, 
+                             PyObject *args, 
+                             PyObject *kwargs)
+{
+    static char *kwlist[] = { "group", NULL };
+    GOptionGroup *g_group;
+    PyObject *group;
+    if (! PyArg_ParseTupleAndKeywords(args, kwargs, 
+                                      "O:GOptionContext.add_group", 
+                                      kwlist, &group))
+        return NULL;
+    if (PyObject_IsInstance(group, (PyObject*) &PyGOptionGroup_Type) != 1) {
+        PyErr_SetString(PyExc_TypeError,
+                        "GOptionContext.add_group expects a GOptionGroup.");
+        return NULL;
+    }
+    g_group = pyg_option_group_transfer_group((PyGOptionGroup*) group);
+    if (g_group == NULL)
+    {
+        PyErr_SetString(PyExc_RuntimeError, 
+                        "Group is already in a OptionContext.");
+        return NULL;
+    }
+    Py_INCREF(group);
+    g_option_context_add_group(self->context, g_group);
+    
+    Py_INCREF(Py_None);
+    return Py_None;
+} 
+
+static int
+pyg_option_context_compare(PyGOptionContext *self, PyGOptionContext *context)
+{
+    if (self->context == context->context) return 0;
+    if (self->context > context->context)
+        return 1;
+    return -1;
+}
+
+static PyMethodDef pyg_option_context_methods[] = {
+    { "parse", (PyCFunction)pyg_option_context_parse, METH_VARARGS | METH_KEYWORDS },
+    { "set_help_enabled", (PyCFunction)pyg_option_context_set_help_enabled, METH_VARARGS | METH_KEYWORDS },
+    { "get_help_enabled", (PyCFunction)pyg_option_context_get_help_enabled, METH_NOARGS },
+    { "set_ignore_unknown_options", (PyCFunction)pyg_option_context_set_ignore_unknown_options, METH_VARARGS | METH_KEYWORDS },
+    { "get_ignore_unknown_options", (PyCFunction)pyg_option_context_get_ignore_unknown_options, METH_NOARGS },
+    { "set_main_group", (PyCFunction)pyg_option_context_set_main_group, METH_VARARGS | METH_KEYWORDS },
+    { "get_main_group", (PyCFunction)pyg_option_context_get_main_group, METH_NOARGS },
+    { "add_group", (PyCFunction)pyg_option_context_add_group, METH_VARARGS | METH_KEYWORDS },
+    { NULL, NULL, 0 },
+};
+
+PyTypeObject PyGOptionContext_Type = {
+    PyObject_HEAD_INIT(NULL)
+    0,
+    "gobject.OptionContext",
+    sizeof(PyGMainContext),
+    0,
+    /* methods */
+    (destructor)pyg_option_context_dealloc,
+    (printfunc)0,
+    (getattrfunc)0,
+    (setattrfunc)0,
+    (cmpfunc)pyg_option_context_compare,
+    (reprfunc)0,
+    0,
+    0,
+    0,
+    (hashfunc)0,
+    (ternaryfunc)0,
+    (reprfunc)0,
+    (getattrofunc)0,
+    (setattrofunc)0,
+    0,
+    Py_TPFLAGS_DEFAULT,
+    NULL,
+    (traverseproc)0,
+    (inquiry)0,
+    (richcmpfunc)0,
+    0,
+    (getiterfunc)0,
+    (iternextfunc)0,
+    pyg_option_context_methods,
+    0,
+    0,
+    NULL,
+    NULL,
+    (descrgetfunc)0,
+    (descrsetfunc)0,
+    0,
+    (initproc)pyg_option_context_init,
+};
+
+/**
+ * pyg_option_context_new:
+ * @context: a GOptionContext
+ *
+ * Returns: A new GOptionContext wrapper.
+ */
+PyObject * 
+pyg_option_context_new (GOptionContext *context)
+{
+    PyGOptionContext *self;
+
+    self = (PyGOptionContext *)PyObject_NEW(PyGOptionContext,
+					    &PyGOptionContext_Type);
+    if (self == NULL)
+	return NULL;
+
+    self->context = context;
+    self->main_group = NULL;
+    
+    return (PyObject *)self;
+}
--- gnome-python/pygobject/gobject/pygoptiongroup.c	1970-01-01 01:00:00.000000000 +0100
+++ gnome-python-new/pygobject/gobject/pygoptiongroup.c	2006-04-26 12:36:22.000000000 +0200
@@ -0,0 +1,551 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * pygtk- Python bindings for the GTK toolkit.
+ * Copyright (C) 2006  Johannes Hoelzl
+ *
+ *   pygoptiongroup.c: GOptionContext and GOptionGroup wrapper
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include "pygobject-private.h"
+
+static gboolean
+check_if_owned(PyGOptionGroup *self)
+{
+    if (self->other_owner)
+    {
+        PyErr_SetString(PyExc_ValueError, "The GOptionGroup was not created by "
+                        "gobject.OptionGroup(), so operation is not possible.");
+        return TRUE;
+    }
+    return FALSE;
+}
+
+static gboolean
+call_parse_func(PyGOptionGroup *self,
+                GOptionContext *context,
+                PyObject *cb,
+                GError **error)
+{
+    PyObject *ret;
+    PyGILState_STATE state;
+   
+    state = pyg_gil_state_ensure();
+  
+    ret = PyObject_CallFunction(PyTuple_GetItem(cb, 0), "OO", self, 
+                                PyTuple_GetItem(cb, 1));
+
+    if (ret == NULL)
+        PyErr_Print();
+
+    pyg_gil_state_release(state);
+
+    if (ret == NULL)
+        return FALSE;
+      
+    Py_DECREF(ret);
+    return TRUE;
+}
+
+static gboolean
+pre_hook(GOptionContext *context,
+         GOptionGroup *group,
+         PyGOptionGroup *pyg,
+         GError **error)
+{
+    return call_parse_func(pyg, context, pyg->pre_hook_cb, error);
+}
+
+static gboolean
+post_hook(GOptionContext *context,
+          GOptionGroup *group,
+          PyGOptionGroup *pyg,
+          GError **error)
+{
+    return call_parse_func(pyg, context, pyg->post_hook_cb, error);
+}
+
+static void
+error_hook(GOptionContext *context, 
+           GOptionGroup *group,
+           PyGOptionGroup *pyg,
+           GError **error)
+{
+    call_parse_func(pyg, context, pyg->error_hook_cb, error);
+}
+
+static void destroy_g_group(PyGOptionGroup *self)
+{
+    GOptionGroup *group = self->group;
+    self->group = NULL;
+    if (group != NULL)
+    {
+        if (self->is_in_context)
+        {
+            Py_DECREF(self);
+        }
+        
+        Py_CLEAR(self->callback);
+        Py_CLEAR(self->pre_hook_cb);
+        Py_CLEAR(self->post_hook_cb);
+        Py_CLEAR(self->error_hook_cb);
+        Py_CLEAR(self->translate_func_cb);
+        
+        g_slist_foreach(self->strings, (GFunc) g_free, NULL);
+        g_slist_free(self->strings);
+    }
+}
+
+static int
+pyg_option_group_init(PyGOptionGroup *self, PyObject *args, PyObject *kwargs)
+{
+    static char *kwlist[] = { "name", "description", "help_description", 
+                              "callback", NULL };
+    char *name, *description, *help_description;
+    PyObject *callback;
+    
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "zzzO:GOptionGroup.__init__",
+                                     kwlist, &name, &description, 
+                                     &help_description, &callback))
+        return -1;
+    
+    self->group = g_option_group_new(name, description, help_description,
+                                     self, (GDestroyNotify) destroy_g_group);
+    self->other_owner = FALSE;
+    self->is_in_context = FALSE;
+    
+    Py_INCREF(callback);
+    self->callback = callback;
+    
+    return 0;
+}
+
+static void
+pyg_option_group_dealloc(PyGOptionGroup *self)
+{
+    if (!self->other_owner)
+    {
+        if (self->group != NULL)
+        {
+            GOptionGroup *tmp = self->group;
+            self->group = NULL;
+            g_option_group_free(tmp);
+        }
+    }
+
+    PyObject_Del(self);
+}
+
+static gboolean 
+arg_func(const gchar *option_name,
+         const gchar *value,
+         PyGOptionGroup *self,
+         GError *error)
+{
+    PyObject *ret;
+    PyGILState_STATE state;
+
+    state = pyg_gil_state_ensure();
+  
+    if (value == NULL)
+        ret = PyObject_CallFunction(self->callback, "sOO", 
+                                    option_name, Py_None, self);
+    else
+        ret = PyObject_CallFunction(self->callback, "ssO", 
+                                    option_name, value, self);
+    
+    if (ret == NULL)
+        PyErr_Print();
+
+    pyg_gil_state_release(state);
+
+    if (ret == NULL)
+        return FALSE;
+
+    Py_DECREF(ret);
+    return TRUE;      
+}
+
+static PyObject *
+pyg_option_group_add_entries(PyGOptionGroup *self, PyObject *args, 
+                             PyObject *kwargs)
+{
+    static char *kwlist[] = { "entries", NULL };
+    gssize entry_count, pos;
+    PyObject *entry_tuple, *list;
+    GOptionEntry *entries;
+    
+    if (check_if_owned(self)) return NULL;
+    
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:GOptionGroup.add_entries",
+                                     kwlist, &list))
+        return NULL;
+    
+    if (!PyList_Check(list))
+    {
+        PyErr_SetString(PyExc_TypeError, 
+                        "GOptionGroup.add_entries expected a list of entries");
+        return NULL;
+    }
+
+    entry_count = PyList_Size(list);
+    if (entry_count == -1)
+    {
+        PyErr_SetString(PyExc_TypeError, 
+                        "GOptionGroup.add_entries expected a list of entries");
+        return NULL;
+    }
+    
+    entries = g_new0(GOptionEntry, entry_count + 1);
+    for (pos = 0; pos < entry_count; pos++)
+    {
+        gchar *long_name, *description, *arg_description;
+        entry_tuple = PyList_GetItem(list, pos);
+        if (!PyTuple_Check(entry_tuple))
+        {
+            PyErr_SetString(PyExc_TypeError, "GOptionGroup.add_entries "
+                                             "expected a list of entries");
+            g_free(entries);
+            return NULL;
+        }
+        if (!PyArg_ParseTuple(entry_tuple, "scisz",
+            &long_name,
+            &(entries[pos].short_name),
+            &(entries[pos].flags),
+            &description,
+            &arg_description))
+        {
+            PyErr_SetString(PyExc_TypeError, "GOptionGroup.add_entries "
+                                             "expected a list of entries");
+            g_free(entries);
+            return NULL;
+        }
+        long_name = g_strdup(long_name);
+        self->strings = g_slist_prepend(self->strings, long_name);
+        entries[pos].long_name = long_name;
+
+        description = g_strdup(description);
+        self->strings = g_slist_prepend(self->strings, description);
+        entries[pos].description = description;
+
+        arg_description = g_strdup(arg_description);
+        self->strings = g_slist_prepend(self->strings, arg_description);
+        entries[pos].arg_description = arg_description;
+        
+        entries[pos].arg = G_OPTION_ARG_CALLBACK;
+        entries[pos].arg_data = arg_func;
+    }
+    
+    g_option_group_add_entries(self->group, entries);
+    
+    g_free(entries);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+
+static PyObject *
+pyg_option_group_set_parse_hooks(PyGOptionGroup *self, PyObject *args,
+                                 PyObject *kwargs)
+{
+    static char *kwlist[] = { "pre_hook", "post_hook", "user_data", NULL };
+    PyObject *pre, *post, *hook_args = Py_None;
+    GOptionParseFunc pre_hook_func = NULL, post_hook_func = NULL;
+    if (check_if_owned(self)) return NULL;
+    
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+                                     "OO|O:GOptionGroup.set_parse_hooks", 
+                                     kwlist, &pre, &post, &hook_args))
+        return NULL;
+    
+    if (!(PyCallable_Check(pre) || pre == Py_None) || 
+        !(PyCallable_Check(post) || post == Py_None))
+    {
+        PyErr_SetString(PyExc_TypeError, "gobject.GOptionGroup.set_parse_hooks "
+                                         "expects two callables.");
+        return NULL;
+    }
+
+    g_option_group_set_parse_hooks(self->group, NULL, NULL);
+        
+    Py_CLEAR(self->pre_hook_cb);
+    if(pre)
+    {
+        self->pre_hook_cb = Py_BuildValue("(OO)", pre, hook_args);
+        pre_hook_func = (GOptionParseFunc) pre_hook;
+    }
+
+    Py_CLEAR(self->post_hook_cb);
+    if(post)
+    {
+        self->post_hook_cb = Py_BuildValue("(OO)", post, hook_args);
+        post_hook_func = (GOptionParseFunc) post_hook;
+    }
+    
+    g_option_group_set_parse_hooks(self->group, pre_hook_func, post_hook_func);
+    
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+pyg_option_group_set_error_hook(PyGOptionGroup *self, PyObject *args, 
+                                PyObject *kwargs)
+{
+    static char *kwlist[] = { "error_hook", "user_data", NULL };
+    PyObject *error, *arg = Py_None;
+    if (check_if_owned(self)) return NULL;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, 
+                                     "O|O:GOptionGroup.set_error_hook", 
+                                     kwlist, &error, &arg))
+        return NULL;
+
+    if (!(PyCallable_Check(error) || error == Py_None))
+    {
+        PyErr_SetString(PyExc_TypeError, "gobject.GOptionGroup.set_error_hook "
+                                         "expects a callable.");
+        return NULL;
+    }
+
+    g_option_group_set_error_hook(self->group, NULL);
+
+    Py_CLEAR(self->error_hook_cb);
+    if (error != Py_None)
+    {
+        self->error_hook_cb = Py_BuildValue("(OO)", error, arg);
+        g_option_group_set_error_hook(self->group, (GOptionErrorFunc) error_hook);
+    }
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static gchar *
+translate_func(const gchar *str,
+               PyGOptionGroup *self)
+{
+    PyObject *ret, *cb;
+    gchar *result;
+    PyGILState_STATE state;
+
+    state = pyg_gil_state_ensure();
+   
+    cb = self->translate_func_cb;
+   
+    ret = PyObject_CallFunction(PyTuple_GetItem(cb, 0), "sOO", 
+                                str, self, PyTuple_GetItem(cb, 1));
+
+    if (ret == NULL)
+        PyErr_Print();
+
+    pyg_gil_state_release(state);
+
+    if (ret == NULL)
+        return NULL;
+   
+    result = g_strdup(PyString_AsString(ret));
+    Py_DECREF(ret);
+   
+    return result;
+}
+
+static PyObject *
+pyg_option_group_set_translate_func(PyGOptionGroup *self, PyObject *args, 
+                                    PyObject *kwargs)
+{
+    static char *kwlist[] = { "translate_func", "user_data", NULL };
+    PyObject *translate, *arg = Py_None;
+    if (check_if_owned(self)) return NULL;
+
+    if (self->group == NULL)
+    {
+        PyErr_SetString(PyExc_RuntimeError, 
+                        "The corresponding GOptionGroup was already freed, "
+                        "probably through the release of GOptionContext");
+        return NULL;
+    }
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, 
+                                     "O|O:GOptionGroup.set_translate_func", 
+                                     kwlist, &translate, &arg))
+        return NULL;
+
+    if (!(PyCallable_Check(translate) || translate == Py_None))
+    {
+        PyErr_SetString(PyExc_TypeError, 
+                 "gobject.GOptionGroup.set_translate_func expects a callable.");
+        return NULL;
+    }
+
+    g_option_group_set_translate_func(self->group, NULL, NULL, NULL);
+
+    Py_CLEAR(self->translate_func_cb);
+    if (translate != Py_None)
+    {
+        self->translate_func_cb = Py_BuildValue("(OO)", translate, arg);
+        g_option_group_set_translate_func(self->group, 
+                                          (GTranslateFunc) translate_func, 
+                                          self, NULL);
+    }
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+pyg_option_group_set_translation_domain(PyGOptionGroup *self, 
+                                        PyObject *args, 
+                                        PyObject *kwargs)
+{
+    static char *kwlist[] = { "domain", NULL };
+    char *domain;
+    if (check_if_owned(self)) return NULL;
+
+    if (self->group == NULL)
+    {
+        PyErr_SetString(PyExc_RuntimeError, 
+                        "The corresponding GOptionGroup was already freed, "
+                        "probably through the release of GOptionContext");
+        return NULL;
+    }
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, 
+                                     "z:GOptionGroup.set_translate_domain", 
+                                     kwlist, &domain))
+        return NULL;
+    g_option_group_set_translation_domain(self->group, domain);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static int
+pyg_option_group_compare(PyGOptionGroup *self, PyGOptionGroup *group)
+{
+    if (self->group == group->group) return 0;
+    if (self->group > group->group)
+        return 1;
+    return -1;
+}
+
+static PyMethodDef pyg_option_group_methods[] = {
+    { "add_entries", (PyCFunction)pyg_option_group_add_entries, METH_VARARGS | METH_KEYWORDS },
+    { "set_parse_hooks", (PyCFunction)pyg_option_group_set_parse_hooks, METH_VARARGS | METH_KEYWORDS },
+    { "set_error_hook", (PyCFunction)pyg_option_group_set_error_hook, METH_VARARGS | METH_KEYWORDS },
+    { "set_translate_func", (PyCFunction)pyg_option_group_set_translate_func, METH_VARARGS | METH_KEYWORDS },
+    { "set_translation_domain", (PyCFunction)pyg_option_group_set_translation_domain, METH_VARARGS | METH_KEYWORDS },
+    { NULL, NULL, 0 },
+};
+
+PyTypeObject PyGOptionGroup_Type = {
+    PyObject_HEAD_INIT(NULL)
+    0,
+    "gobject.OptionGroup",
+    sizeof(PyGOptionGroup),
+    0,
+    /* methods */
+    (destructor)pyg_option_group_dealloc,
+    (printfunc)0,
+    (getattrfunc)0,
+    (setattrfunc)0,
+    (cmpfunc)pyg_option_group_compare,
+    (reprfunc)0,
+    0,
+    0,
+    0,
+    (hashfunc)0,
+    (ternaryfunc)0,
+    (reprfunc)0,
+    (getattrofunc)0,
+    (setattrofunc)0,
+    0,
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+    NULL,
+    (traverseproc)0,
+    (inquiry)0,
+    (richcmpfunc)0,
+    0,
+    (getiterfunc)0,
+    (iternextfunc)0,
+    pyg_option_group_methods,
+    0,
+    0,
+    NULL,
+    NULL,
+    (descrgetfunc)0,
+    (descrsetfunc)0,
+    0,
+    (initproc)pyg_option_group_init,
+};
+
+/**
+ * pyg_option_group_transfer_group:
+ * @group: a GOptionGroup wrapper
+ *
+ * This is used to transfer the GOptionGroup to a GOptionContext. After this
+ * is called, the calle must handle the release of the GOptionGroup.
+ *
+ * When #NULL is returned, the GOptionGroup was already transfered.
+ *
+ * Returns: Either #NULL or the wrapped GOptionGroup.
+ */
+GOptionGroup *
+pyg_option_group_transfer_group(PyGOptionGroup *self)
+{
+    if (self->is_in_context) return NULL;
+    self->is_in_context = TRUE;
+    
+    /* Here we increase the reference count of the PyGOptionGroup, because now
+     * the GOptionContext holds an reference to us (it is the userdata passed
+     * to g_option_group_new().
+     *
+     * The GOptionGroup is freed with the GOptionContext.
+     *
+     * We set it here because if we would do this in the init method we would
+     * hold two references and the PyGOptionGroup would never be freed.
+     */
+    Py_INCREF(self);
+    
+    return self->group;
+}
+
+/**
+ * pyg_option_group_new:
+ * @group: a GOptionGroup
+ *
+ * The returned GOptionGroup can't be used to set any hooks, translation domains
+ * or add entries. It's only intend is, to use for GOptionContext.add_group().
+ *
+ * Returns: the GOptionGroup wrapper.
+ */
+PyObject * 
+pyg_option_group_new (GOptionGroup *group)
+{
+    PyGOptionGroup *self;
+
+    self = (PyGOptionGroup *)PyObject_NEW(PyGOptionGroup,
+					  &PyGOptionGroup_Type);
+    if (self == NULL)
+	return NULL;
+
+    self->group = group;
+    self->other_owner = TRUE;
+    self->is_in_context = FALSE;
+        
+    return (PyObject *)self;
+}
--- gnome-python/pygobject/gobject/gobjectmodule.c	2006-04-12 00:58:37.000000000 +0200
+++ gnome-python-new/pygobject/gobject/gobjectmodule.c	2006-04-18 23:16:32.000000000 +0200
@@ -3101,6 +3101,9 @@ init_gobject(void)
     REGISTER_TYPE(d, PyGTimeout_Type, "Timeout");
     REGISTER_TYPE(d, PyGPollFD_Type, "PollFD");
 
+    REGISTER_TYPE(d, PyGOptionContext_Type, "OptionContext");
+    REGISTER_TYPE(d, PyGOptionGroup_Type, "OptionGroup");
+
     /* glib version */
     tuple = Py_BuildValue ("(iii)", glib_major_version, glib_minor_version,
 			   glib_micro_version);
@@ -3167,7 +3170,21 @@ init_gobject(void)
     addint(IO_FLAG_GET_MASK);
     addint(IO_FLAG_SET_MASK);
 
+    addint(OPTION_FLAG_HIDDEN);
+    addint(OPTION_FLAG_IN_MAIN);
+    addint(OPTION_FLAG_REVERSE);
+    addint(OPTION_FLAG_NO_ARG);
+    addint(OPTION_FLAG_FILENAME);
+    addint(OPTION_FLAG_OPTIONAL_ARG);
+    addint(OPTION_FLAG_NOALIAS);
+ 
+    addint(OPTION_ERROR_UNKNOWN_OPTION);
+    addint(OPTION_ERROR_BAD_VALUE);
+    addint(OPTION_ERROR_FAILED);
+ 
 #undef addint
+  
+    PyModule_AddStringConstant(m, "OPTION_REMAINING", G_OPTION_REMAINING);
 
     PyModule_AddIntConstant(m, "SPAWN_LEAVE_DESCRIPTORS_OPEN",
 			    G_SPAWN_LEAVE_DESCRIPTORS_OPEN);
--- gnome-python/pygobject/gobject/Makefile.am	2006-04-26 18:18:46.000000000 +0200
+++ gnome-python-new/pygobject/gobject/Makefile.am	2006-04-17 23:05:22.000000000 +0200
@@ -9,7 +9,7 @@ pkgpyexecdir = $(pyexecdir)/gtk-2.0
 
 # gobject python scripts
 pygobjectdir = $(pkgpyexecdir)/gobject
-pygobject_PYTHON = __init__.py
+pygobject_PYTHON = __init__.py option.py
 pygobject_LTLIBRARIES = _gobject.la 
 
 
@@ -36,7 +36,9 @@ _gobject_la_SOURCES = \
 	pygpointer.c \
 	pygiochannel.c \
 	pygsource.c \
-	pygtype.c
+	pygtype.c \
+	pygoptioncontext.c \
+	pygoptiongroup.c
 
 if PLATFORM_WIN32
 _gobject_la_CFLAGS += -DPLATFORM_WIN32
