On Wed, 17 Nov 2010, Grant Edwards posted:
Hey, it's the IMAP guy!  Get 'im!

Busted! :p

Alright, here's the full story.

As may be obvious to some, the module is to be a Python interface into c-client. What may not be obvious is that this is for QA automation. The consumers of this module will know Python but not necessarily C and certainly not c-client. Right now the module is called cclient but that will certainly change.

So, I have methods such as cclient.create that in my module look like:

static PyObject *cclient_create(PyObject *self, PyObject *args)
{
    char *mailbox;
    PyObject *ret = NULL;
    if(PyArg_ParseTuple(args, "s", &mailbox))
        ret = Py_BuildValue("i", mail_create(NULL, mailbox));
    return ret;
}

and indeed within Python
        cclient.create("testbox")
creates "testbox" as expected.  A bunch of other methods are the same.

Now, however, I need cclient.open, and expect to do something like:

static PyObject *cclient_create(PyObject *self, PyObject *args)
{
    char *mailbox;
    MAILSTREAM *stream;
    PyObject *ret = NULL;
    if(PyArg_ParseTuple(args, "s", &mailbox) &&
       (stream = mail_open(NULL, mailbox, 0))) {
        ret = ???;
        // set ret to a "cclient stream" object that has "stream" as
        // an instance variable, and a method table, presumably via
        // PyMethodDef, for this "cclient stream" object.
    }
    return ret;
}

So, if in Python, I do something like:
        stream = cclient.open("testbox")
        print stream.uid(1)

I expect that to call an method like

static PyObject *cclient_create(PyObject *self, PyObject *args)
{
    long sequence;
    MAILSTREAM *stream = ???; // get stream from self
    PyObject *ret = NULL;
    if(PyArg_ParseTuple(args, "l", &sequence))
        ret = Py_BuildValue("i", mail_uid(stream, sequence));
    return ret;
}

So, basically, what I'm missing are the two "???" things above, plus how to make this "cclient stream" object call mail_close(stream).

In SmallTalk or Objective C, the method table would be defined as part of a factory object that has a "new" factory method that in my case would take "stream" as an argument and set it as the instance method. Then to get the stream, I'd do something like
        stream = [self getStream];

Have you looked at ctypes?  It's not suitable for all libraries, but
it can often obviate the need to write any C code:
 http://docs.python.org/release/2.6.6/library/ctypes.html#module-ctypes

Hmm. I don't think that it helps, especially as I don't really want to make the consumers of this module know anything about c-client or its calling conventions.

Thanks for any clues...

-- Mark --

http://panda.com/mrc
Democracy is two wolves and a sheep deciding what to eat for lunch.
Liberty is a well-armed sheep contesting the vote.
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to