embedding, getargs/mkvalue asymmetry

Mark Lutz (mlutz@KaPRE.COM)
Wed, 8 Feb 1995 12:10:49 +0700

More puzzlings from the trenches... :-)

The new 'O!', 'O?', and 'O&' formats in getargs aren't supported
in mkvalue; is this still true in 1.2? Believe it or not, I've
found a need for something like this.

I've got a routine for calling an embedded Python function by
module/function name; the format and address of the result is
passed in (for getargs: Python->C), and a format for the arg-list
is passed with a varargs list of C items (for mkvalue: C->Python).

The idea is to automate function object fetch, call_object, and
both getargs and mkvalue calls to do data conversion to/from Python
form. The module containing the function is automatically imported
(or reloaded...) if needed:

int
run_function(char *modname, char *funcname,
char *resfmt, void *cresult, // getargs
char *argfmt, ... /*arg, arg...*/ ) // mkvalue

Here's the problem: I'd like to use 'O&' to handle conversions to
and from a Python class instance wrapper around a C++ instance:

Some C module:
CThing result;
Account acct;
Company comp;

status = run_function("postStuff", "validateAccount",
"O&", FromThing, &result,
"(O&sO&)", ToThing, acct, user, ToThing, comp);

postStuff.py:
def validateAccount(acct, user, comp): # Thing, str, Thing
<use stuff passed in>
<return a Thing>

which won't work (only the FromThing part works). There's ways
to work around this, but I'd rather not hack-up my copy of
modsupport.c, with 1.2 looming; the fix would be very similar
to getargs.c.

BTW, I'm curious if anyone else has been doing embedding this
way (calling functions by module/function name, etc.). Python's
embedding utilities don't seem as well-structured as its extending
tools; I'd be interested in any ideas on what sort of higher-level
embedding API functions might be desirable.

I've got similar functions to get/set global (module-scope)
variables in a named module (which defaults to __main__):

int
get_global(char *modname, char *varname,
char *valfmt, void *cval) // getargs

int
set_global(char *modname, char *varname,
char *valfmt, ... /*cval*/) // mkvalue

and run a passed-in string in a given module, after setting global
variable's values in the module from a vargargs list automatically:

int
run_text(char *modname, char *codestring,
char *resfmt, void *cresult,
... /* name, fmt, val, name, fmt, val,... */ )

For instance:
int xval, yval, intres, status;

status = run_text("__main__", "(X + Y) > 1000",
"i", &intres,
"X", "i", xval, "Y", "i", yval);

These also need to be able to use 'O&' for C->Python conversions
(mkvalue). run_text() is a superset of run_string(), and may be
too complicated as is...

Anyone think these sorts of interfaces would be useful as standard
things? Right now, there's a lot of low-level programming needed
to call embedded Python code.

Mark L.