Re: Python bindings -- I'm stepping back from them
Malcolm Tredinnick <[email protected]> Thu, 13 Mar 2003 19:55:37 +1100
| Newsgroups | gmane.comp.gnome.apps.mr-project.devel |
|---|---|
| Message-ID | <[email protected]> |
--envbJBWh7q8WU6mo
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
On Thu, Mar 13, 2003 at 01:53:53AM +0100, Mikael Hallendal wrote:
[...]
> We are not finished though and I really think that having your bindings
> (are they finished?) will help even if there are conflicts. For example
> we have mostly done the really easy parts yet and the more complex
> functions still needs doing. I for one have not much knowledge in
> wrapping C libraries in Python and wouldn't mind glancing on your code
> (or be able to just copy them in).
>
> You think it would be possible to send your stuff to the list?
I have sorted out a fair bit of my stuff and attached it to this mail.
That might save you some time. I'm not going to commit it directly,
because I still don't know where you are up to.
There are still a couple of problems here. In particular, I am not sure
why mrp_interval_new is not being wrapped, even though I have provided
data for it. I wanted to make MrpInterval a proper type, but I cannot
currently create one (the idea is to make the tp_init slot in
PyMrpInterval_Type be a pointer to _wrap_mrp_interval_new). The Interval
type is probably a bit incomplete at the moment, because this
constructor issue was driving me up the wall. I think I'm doing
something really dumb, but I cannot see it right at the moment.
Also, I think there are a couple of FIXMEs in the code where I got bored
and left something for later.
During this work, I came across a couple of points that need to be
considered:
- Calling mrproject.Application() more than once should _not_
segfault. The solution may be to have a check in
mrp_application_new() (in libmrproject) and just return if the
application has already been initialised.
- I suspect that mrp_application_get_all_file_readers() and
mrp_application_get_all_file_writers() should be private
functions. They return lists of MrpFileReader and
MrpFileWriter structures, respectively, but these structures
are not declared in any public header file. Since no functions
take such lists as input, the return values of these two
functions seems to be completely useless outside of
libmrproject.
- There problably should be non-varargs versions of
mrp_object_set and mrp_object_get. This is a problem common to
most non-C language bindings: everywhere you have a varargs
function, you also have something like mrp_object_setv that
takes a list for the bindings to use. We need to wrap these
functions eventually, because otherwise there is no convenient
way to access custom parameters of MrpObject instances.
Cheers,
Malcolm
--
I've got a mind like a... a... what's that thing called?
--envbJBWh7q8WU6mo
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="python.patch"
Index: mrproject.override
===================================================================
RCS file: /cvs/gnome/libmrproject/python/mrproject.override,v
retrieving revision 1.3
diff -u -r1.3 mrproject.override
--- mrproject.override 12 Mar 2003 22:08:15 -0000 1.3
+++ mrproject.override 13 Mar 2003 08:40:42 -0000
@@ -6,6 +6,181 @@
#include "pygobject.h"
#include <mrproject/mrproject.h>
#include <mrproject/mrp-storage-module.h>
+
+/* ------------- MrpDay ------------- */
+
+typedef struct {
+ PyObject_HEAD
+ MrpDay *day;
+} PyMrpDay;
+
+staticforward PyTypeObject PyMrpDay_Type;
+
+static PyObject *
+pymrp_day_new (MrpDay *day)
+{
+ PyMrpDay *self;
+
+ self = (PyMrpDay *) PyObject_NEW (PyMrpDay, &PyMrpDay_Type);
+ if (self == NULL) {
+ return NULL;
+ }
+ self->day = day;
+
+ return (PyObject *) self;
+}
+
+static void
+pymrp_day_dealloc (PyMrpDay *self)
+{
+ g_free (self->day);
+ PyObject_DEL(self);
+}
+
+static PyTypeObject PyMrpDay_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "mrproject.Day", /* tp_name */
+ sizeof(PyMrpDay), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)pymrp_day_dealloc, /* tp_dealloc */
+ (printfunc)0, /* tp_print */
+ (getattrfunc)0, /* tp_getattr */
+ (setattrfunc)0, /* tp_setattr */
+ (cmpfunc)0, /* tp_compare */
+ (reprfunc)0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)0, /* tp_hash */
+ (ternaryfunc)0, /* tp_call */
+ (reprfunc)0, /* tp_str */
+ (getattrofunc)0, /* tp_getattro */
+ (setattrofunc)0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ NULL, /* Documentation string */
+ (traverseproc)0, /* tp_traverse */
+ (inquiry)0, /* tp_clear */
+ (richcmpfunc)0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc)0, /* tp_iter */
+ (iternextfunc)0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ (PyTypeObject *)0, /* tp_base */
+ (PyObject *)0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)0, /* tp_init */
+ (allocfunc)0, /* tp_alloc */
+ (newfunc)0, /* tp_new */
+ 0, /* tp_free */
+ (inquiry)0, /* tp_is_gc */
+ (PyObject *)0, /* tp_bases */
+};
+
+/* ------------- MrpInterval ------------- */
+
+typedef struct {
+ PyObject_HEAD
+ MrpInterval *interval;
+} PyMrpInterval;
+
+staticforward PyTypeObject PyMrpInterval_Type;
+
+static PyObject *
+pymrp_interval_new (MrpInterval *interval)
+{
+ PyMrpInterval *self;
+
+ self = (PyMrpInterval *) PyObject_NEW (PyMrpInterval,
+ &PyMrpInterval_Type);
+ if (self == NULL) {
+ return NULL;
+ }
+ self->interval = interval;
+
+ return (PyObject *) self;
+}
+
+static void
+pymrp_interval_dealloc (PyMrpInterval *self)
+{
+ g_free (self->interval);
+ PyObject_DEL(self);
+}
+
+static PyObject *
+pymrp_interval_copy (PyMrpInterval *self)
+{
+ return pymrp_interval_new ( mrp_interval_copy (self->interval));
+}
+
+
+static PyMethodDef pymrp_interval_methods[] = {
+ { "copy", (PyCFunction) pymrp_interval_copy, METH_NOARGS },
+ { NULL, NULL, 0 }
+};
+
+static PyTypeObject PyMrpInterval_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "mrproject.Interval", /* tp_name */
+ sizeof(PyMrpInterval), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)pymrp_interval_dealloc, /* tp_dealloc */
+ (printfunc)0, /* tp_print */
+ (getattrfunc)0, /* tp_getattr */
+ (setattrfunc)0, /* tp_setattr */
+ (cmpfunc)0, /* tp_compare */
+ (reprfunc)0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)0, /* tp_hash */
+ (ternaryfunc)0, /* tp_call */
+ (reprfunc)0, /* tp_str */
+ (getattrofunc)0, /* tp_getattro */
+ (setattrofunc)0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ NULL, /* Documentation string */
+ (traverseproc)0, /* tp_traverse */
+ (inquiry)0, /* tp_clear */
+ (richcmpfunc)0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc)0, /* tp_iter */
+ (iternextfunc)0, /* tp_iternext */
+ pymrp_interval_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ (PyTypeObject *)0, /* tp_base */
+ (PyObject *)0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)0, /* tp_init */
+ (allocfunc)0, /* tp_alloc */
+ (newfunc)0, /* tp_new */
+ 0, /* tp_free */
+ (inquiry)0, /* tp_is_gc */
+ (PyObject *)0, /* tp_bases */
+};
+%%
+init
+ PyMrpDay_Type.tp_alloc = PyType_GenericAlloc;
+ PyMrpDay_Type.tp_new = PyType_GenericNew;
+ if (PyType_Ready(&PyMrpDay_Type) < 0)
+ return;
+ PyMrpInterval_Type.tp_alloc = PyType_GenericAlloc;
+ PyMrpInterval_Type.tp_new = PyType_GenericNew;
+ if (PyType_Ready(&PyMrpInterval_Type) < 0)
+ return;
%%
modulename mrproject
%%
@@ -15,10 +190,17 @@
*_get_type
*_valist
mrp_string_list_*
+%%
+ignore
mrp_object_set
mrp_object_get
mrp_calendar_set_days
mrp_calendar_set_default_days
+ mrp_error_quark
+ mrp_time_from_tm
+ mrp_param_spec_time
+ mrp_interval_ref
+ mrp_interval_unref
%%
override mrp_task_get_assignments noargs
static PyObject *
@@ -124,4 +306,229 @@
Py_DECREF(obj);
}
return py_list;
+}
+%%
+override mrp_day_add kwargs
+static PyObject *
+_wrap_mrp_day_add (PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = {"project", "name", "description", NULL};
+ PyGObject *project;
+ gchar *name, *description;
+ MrpDay *day;
+
+ if (!PyArg_ParseTupleAndKeywords (args, kwargs, "O!ss:mrp_day_add",
+ kwlist, &PyMrpProject_Type, &project,
+ &name, &description)) {
+ return NULL;
+ }
+
+ day = mrp_day_add (MRP_PROJECT (project->obj), name, description);
+ return pymrp_day_new (day);
+}
+%%
+override mrp_day_get_all kwargs
+static PyObject *
+_wrap_mrp_day_get_all (PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = {"project", NULL};
+ PyGObject *project;
+ GList *days, *l;
+ PyObject *tuple;
+ gint i;
+
+ if (!PyArg_ParseTupleAndKeywords (args, kwargs, "O!:mrp_day_get_all",
+ kwlist, &PyMrpProject_Type,
+ &project)) {
+ return NULL;
+ }
+
+ days = mrp_day_get_all (MRP_PROJECT (project->obj));
+ tuple = PyTuple_New (g_list_length (days));
+ for (l = days, i = 0; l; l = l->next, ++i) {
+ PyTuple_SET_ITEM (tuple, i, pymrp_day_new (l->data));
+ }
+ return tuple;
+}
+%%
+override mrp_day_remove kwargs
+static PyObject *
+_wrap_mrp_day_remove (PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = {"project", "day", NULL};
+ PyGObject *project;
+ PyMrpDay *day;
+
+ if (!PyArg_ParseTupleAndKeywords (args, kwargs, "O!O!:mrp_day_remove",
+ kwlist, &PyMrpProject_Type, &project,
+ &PyMrpDay_Type, &day)) {
+ return NULL;
+ }
+ mrp_day_remove (MRP_PROJECT (project->obj), day->day);
+ Py_INCREF (Py_None);
+ return Py_None;
+}
+%%
+override mrp_day_get_work noargs
+static PyObject *
+_wrap_mrp_day_get_work (PyObject *self)
+{
+ return pymrp_day_new (mrp_day_get_work ());
+}
+%%
+override mrp_day_get_nonwork noargs
+static PyObject *
+_wrap_mrp_day_get_nonwork (PyObject *self)
+{
+ return pymrp_day_new (mrp_day_get_nonwork ());
+}
+%%
+override mrp_day_get_use_base noargs
+static PyObject *
+_wrap_mrp_day_get_use_base (PyObject *self)
+{
+ return pymrp_day_new (mrp_day_get_use_base ());
+}
+%%
+override mrp_resource_compare
+static PyObject *
+_wrap_mrp_resource_compare (PyObject *self, PyObject *args)
+{
+ PyGObject *lhs, *rhs;
+
+ if (!PyArg_ParseTuple (args, "O!O!:mrp_resource_compare",
+ &PyMrpResource_Type, &lhs,
+ &PyMrpResource_Type, &rhs)) {
+ return NULL;
+ }
+ return PyInt_FromLong (mrp_resource_compare (lhs->obj, rhs->obj));
+}
+%%
+override mrp_task_compare
+static PyObject *
+_wrap_mrp_task_compare (PyObject *self, PyObject *args)
+{
+ PyGObject *lhs, *rhs;
+
+ if (!PyArg_ParseTuple (args, "O!O!:mrp_task_compare",
+ &PyMrpTask_Type, &lhs, &PyMrpTask_Type, &rhs)) {
+ return NULL;
+ }
+ return PyInt_FromLong (mrp_task_compare (lhs->obj, rhs->obj));
+}
+%%
+override mrp_interval_new kwargs
+static PyObject *
+_wrap_mrp_interval_new (PyMrpInterval *self, PyObject *args, PyObject *kwargs)
+{
+ /* FIXME: Why doesn't this method get created????? */
+ static char *kwlist[] = {"start", "end", NULL};
+ glong start, end;
+ PyObject *interval;
+
+ if (!PyArg_ParseTupleKeywords (args, kwargs, "ll:mrp_interval_new",
+ kwlist, &start, &end)) {
+ return NULL;
+ }
+
+ interval = (PyMrpInterval *) PyObject_NEW (PyMrpInterval,
+ &PyMrpInterval_Type);
+ interval->interval = mrp_interval_new (start, end);
+ return interval;
+}
+%%
+override mrp_calendar_day_set_intervals kwargs
+static PyObject *
+_wrap_mrp_calendar_day_set_intervals (PyGObject *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = {"day", "intervals", NULL};
+ PyMrpDay *day;
+ PyObject *intervals;
+/*
+ PyMrpInterval *interval;
+ GList *l;
+ gint i;
+*/
+
+ if (!PyArg_ParseTupleAndKeywords (args, kwargs,
+ "O!O:mrp_calendar_day_set_intervals",
+ kwlist, &PyMrpDay_Type, &day,
+ &intervals)) {
+ return NULL;
+ }
+ if (!PySequence_Check (intervals)) {
+ PyErr_SetString(PyExc_TypeError, "intervals argument must be a "
+ "sequence");
+ Py_DECREF (day);
+ Py_DECREF (intervals);
+ return NULL;
+ }
+
+ /* FIXME -- implement! */
+
+ Py_INCREF (Py_None);
+ return Py_None;
+}
+%%
+override mrp_calendar_day_get_total_work kwargs
+static PyObject *
+_wrap_mrp_calendar_day_get_total_work (PyGObject *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = {"day", NULL};
+ PyMrpDay *day;
+ gint work;
+
+ if (!PyArg_ParseTupleAndKeywords (args, kwargs,
+ "O!:mrp_calendar_day_get_total_work",
+ kwlist, &PyMrpDay_Type, &day)) {
+ return NULL;
+ }
+ work = mrp_calendar_day_get_total_work (MRP_CALENDAR (self->obj),
+ day->day);
+ return PyInt_FromLong (work);
+}
+%%
+override mrp_calendar_get_day kwargs
+static PyObject *
+_wrap_mrp_calendar_get_day (PyGObject *self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = {"date", "check_ancestors", NULL};
+ glong date;
+ PyObject *check;
+ gboolean check_ancestors;
+ MrpDay *day;
+
+ if (!PyArg_ParseTupleAndKeywords (args, kwargs,
+ "lO:mrp_calendar_get_day",
+ kwlist, &date, &check)) {
+ return NULL;
+ }
+ check_ancestors = PyObject_IsTrue (check);
+ day = mrp_calendar_get_day (MRP_CALENDAR (self->obj), date,
+ check_ancestors);
+ return pymrp_day_new (day);
+}
+%%
+override mrp_calendar_get_default_day kwargs
+static PyObject *
+_wrap_mrp_calendar_get_default_day (PyGObject *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = {"week_day", NULL};
+ gint week_day;
+ MrpDay *day;
+
+ if (!PyArg_ParseTupleAndKeywords (args, kwargs,
+ "i:mrp_calendar_get_default_day",
+ kwlist, &week_day)) {
+ return NULL;
+ }
+
+ day = mrp_calendar_get_default_day (MRP_CALENDAR (self->obj), week_day);
+ return pymrp_day_new (day);
}
--envbJBWh7q8WU6mo
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
_______________________________________________
Mrproject-devel mailing list
[email protected]
http://lists.codefactory.se/cgi-bin/mailman/listinfo/mrproject-devel
--envbJBWh7q8WU6mo--