C API : Creating a Py_Method object from a C function.

2005-07-11 Thread Hugh Macdonald
I've got a pure python module that parses a certain type of file. It
has a load() function that allows a callback function to be passed for
getting progress information.

In straight python, this works fine.

However, I'm now trying to use this from a C++ program. The current
flow that I'm trying to get is as follows:

C++ calls python interface function, passing a C++ function pointer
Python interface function stores C++ function pointer
Python interface function generates new Py_Object method pointer
pointing to a different C python function. (This different function
calls the stored C++ function pointer)
Python interface function calls python function
Python function calls the python method pointer it was passed
C python function then calls the stored C++ function pointer.


The problem in this workflow is taking the C python function that I've
defined (using the standard "static PyObject *someFunction(PyObject
*self, PyObject *args)" method) and converting this into a Py_Object.
Any ideas?

Py_Method doesn't seem to allow you to generate a new one with your own
pointers inside... and I can't see anything else in the docs that might
allow me to do this...


Thanks for any advice!

--
Hugh Macdonald

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: C API : Creating a Py_Method object from a C function.

2005-07-12 Thread Hugh Macdonald
Thanks Martin - that worked wonderfully


For the record (and for anyone searching for this in future), here's
the code that worked (with names changed to protect my job...)


myPython is the C++/Python interface class containing static methods
which pass on calls to the underlying python module. It's not really
commented, but if you're trying to do this kind of thing, it should
give you what you need.


// myPython.h

#ifndef ___MYPYTHON_H___
#define ___MYPYTHON_H___

#include 

using namespace std;

typedef struct _object PyObject;
typedef void   (*loadCallback)(string message, int progress, void
*callbackData);

staticPyObject *myPython_doLoadCallback(PyObject *self,
PyObject *args);

class myPython {
public:
staticlist *loadDetails(string file, loadCallback
callbackFunc = NULL, void *callbackData = NULL);
staticvoid doLoadCallback(string message, int
progress);
private:
staticPyObject *getResults(char *moduleName, char
*functionName, PyObject *args);

staticloadCallback callbackFunc;
staticvoid *callbackData;
};

#endif // ___MYPYTHON_H___




// myPython.cpp

#include 
#include 

loadCallbackmyPython::callbackFunc = NULL;
void*myPython::callbackData = NULL;

list *myPython::loadDetails(string file, loadCallback
newCallbackFunc, void *newCallbackData)
{
PyObject *pArgs, *pResult;

callbackFunc = newCallbackFunc;
callbackData = newCallbackData;

PyMethodDef *callbackFunctionDef = new PyMethodDef;
callbackFunctionDef->ml_name = "doLoadCallback";
callbackFunctionDef->ml_meth = &myPython_doLoadCallback;
callbackFunctionDef->ml_flags = 1;

PyObject *pyCallbackFunc = PyCFunction_New(callbackFunctionDef,
NULL);

pArgs = Py_BuildValue("(sO)", file.c_str(), pyCallbackFunc);

pResult = getResults("myPythonModule", "loadDetails", pArgs);

if(!pResult)
{
Py_DECREF(pArgs);
return NULL;
}

if(PyList_Check(pResult))
{
// Convert pResult into a list and return that.
}

return NULL;
}

PyObject *myPython_doLoadCallback(PyObject *self, PyObject *args)
{
char *message;
int progress;

if(!PyArg_ParseTuple(args, "si", &message, &progress))
return NULL;

myPython::doLoadCallback(message, progress);

return Py_None;
}

void myPython::doLoadCallback(string message, int progress)
{
if(callbackFunc)
callbackFunc(message, progress, callbackData);
}


-- 
http://mail.python.org/mailman/listinfo/python-list


Reading in external file - error checking and line numbers...

2005-09-07 Thread Hugh Macdonald
I'm writing a tool at the moment that reads in an external file (which
can use any Python syntax)

At the moment, I'm reading the file in using:

scriptLines = open(baseRippleScript).read()
exec scriptLines

However, if I raise an exception in my main code, in a function that is
called from the external script, the stack trace just has:

File "", line 8, in ?

Ideally, I'd want to be able to avoid throwing exceptions and would
like to, from my main code, print out an error that included the script
name (easily accessible) and the line number (less easily accessible).

Is there a better way of executing an external script that would let me
access at any time the line number from the external script that is
being executed.


More specifically, if a function is called from an external script with
an invalid parameter type, I want to be able to flag it accurately to
the user

Hope this made sense - let me know if I've confused you at all.


--
Hugh Macdonald

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Reading in external file - error checking and line numbers...

2005-09-07 Thread Hugh Macdonald
Thankyou! That was much easier than I expected.

One more thing on a similar note. When raising exceptions, is it
possible to remove a few items from the top of the stack trace?

My stack trace is looking something like:

  File "ripple", line 160, in ?
  File "ripple", line 94, in executeRipple
  File "test.rip", line 8, in ?
dependsOnFrame = new)
  File "ripple", line 133, in __init__
  File "ripple", line 148, in addDependsOnFrame
__main__.RippleError: 'Cannot add frame dependency to non frame-based
node'

I'd like to be able to remove the last two items in the stack so that
it just shows the user:

  File "ripple", line 160, in ?
  File "ripple", line 94, in executeRipple
  File "test.rip", line 8, in ?
dependsOnFrame = new)
__main__.RippleError: 'Cannot add frame dependency to non frame-based
node'

Unfortunately, I don't know how many 'ripple' stack items there will
be...

This is why I'd much rather, if I can, do this without exceptions and
just be able to print out my own error message with the problem line
number marked

Or am I asking too much? ;)

--
Hugh Macdonald

-- 
http://mail.python.org/mailman/listinfo/python-list


Hacking the scope to pieces

2005-05-24 Thread Hugh Macdonald
We're starting to version a number of our python modules here, and I've
written a small function that assists with loading the versioned
modules...

A module would be called something like: myModule_1_0.py

In anything that uses it, though, we want to be able to refer to it
simply as 'myModule', with an environment variable ("MYMODULE_VERSION"
- set to "1.0") that defines the version.

I've written a module called 'moduleLoader' with the follwing function
in:

def loadModule(module, version, v = globals()):
  import compiler
  loadStr = "import %s_%s as %s" % (module, version.replace(".", "_"),
module)
  eval(compiler.compile(loadStr, "/tmp/%s_%s_errors.txt" % (module,
version.replace(".", "_")), "single"))
  v[module] = vars()[module]


The ideal situation with this would be to be able, in whatever script,
to have:

import moduleLoader
moduleLoader.loadModule("myModule", os.getenv("MODULE_VERSION"))


However, this doesn't work. The two options that do work are:

import moduleLoader
moduleLoader.loadModule("myModule", os.getenv("MODULE_VERSION"),
globals())


import moduleLoader
moduleLoader.loadModule("myModule", os.getenv("MODULE_VERSION"))
from moduleLoader import myModule


What I'm after is a way of moduleLoader.loadModule working back up the
scope and placing the imported module in the main global scope. Any
idea how to do this?


--
Hugh Macdonald

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Hacking the scope to pieces

2005-05-24 Thread Hugh Macdonald
I will take a look!

Thanks Skip

--
Hugh

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Hacking the scope to pieces

2005-05-24 Thread Hugh Macdonald
Maybe I misunderstood what you meant, but I couldn't quite manage to
get this one working

My initial hopes about __import__() were that I could define it inside
my new module (moduleLoader) and, when the module is imported, it could
do stuff (like try to hold onto the vars() and globals() from the
importing scope). However, I couldn't get it to import...

The route I've ended up going (which is just about as simple) is just
to return the new module from moduleLoader.loadModule, so my loading
code is:

import moduleLoader
myModule = moduleLoader.loadModule("myModule",
os.getenv("MODULE_VERSION"))

I've also switched over to using 'inp' for this, rather than creating a
compiler string - much nicer

Anyway, thanks Skip

--
Hugh

-- 
http://mail.python.org/mailman/listinfo/python-list