Hi
I am new to python programming and I am trying to embed some python calls into my C++ program. I made a simple module called 'test.py' which has the following lines :

//---------test.py------------------
message = 'The meaning of life...'

def transform (input):
input = input.replace ('life', 'Python..');
return input.upper()
//--------------------------------------
In c++,
{
Py_Initialize ();
PyRun_SimpleString ("import test");
PyRun_SimpleString ("print test.transform ('life')");
}
//------------------------------------------

When I run this program, I get an error :

'import site' failed; use -v for traceback
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: No module named test
Traceback (most recent call last):
File "<string>", line 1, in <module>
NameError: name 'test' is not defined

Can someone help me out with this? The code works if I go into IDLE and type >>> import test.
What am I doing wrong?

Thanks

**** If it is important, I downloaded and installed python 2.5.2 and I am using it on openSuse 10.2

From the documentation of Py_Initialize(), I think it would be a good idea to try

Py_SetProgramName("path to the python executable");

before the call to Py_Initialize. Also check that your python 2.5.2 library contains a file site.py.

The library does have a file called site.py. Can you tell me why it is important?

Also after using Py_SetProgramName, I am now getting the error :
AttributeError: 'module' object has no attribute

Some progress I guess.

Note that the code in the body of the function transform should be indented. Also, I think it's quite a challenge to begin with python from it's C API. You should experiment with pure python code too :)

Here is the documentation of the site module if you want to understand it's role. However, it's not really important as long as python doesn't complain anymore http://www.python.org/doc/2.5.2/lib/module-site.html.

The function is indented. I think I lost the indentation while pasting it here. Besides if it works in IDLE then that could not be the problem.

You said the error is now 'module' object has no attribute ..., but what's the attribute ?

Sorry, The attribute is 'transform'

AttributeError: 'module' object has no attribute 'transform'

It means that python fails to compute test.transform . There must be an error in your python file.
Try to add this

PyRun_SimpleString ("print test.__file__");

before the other print, to check from which file your module test was imported. I think there is a predefined module test, so you should probably rename your program "mytest.py" for example.

Looks like that was one problem. Anyways, its back to stage 1 after renaming everything to mytest.py

'import site' failed; use -v for traceback
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: No module named mytest
Traceback (most recent call last):
File "<string>", line 1, in <module>
NameError: name 'mytest' is not defined
Traceback (most recent call last):
File "<string>", line 1, in <module>
NameError: name 'mytest' is not defined

It's strange that the "import site failed" reappeared. Did you remove the Py_SetProgramName ?

Nope, its still there.

Py_SetProgramName("mytest.py");
  Py_Initialize ();
  PyRun_SimpleString ("import mytest");
  PyRun_SimpleString ("print mytest.__file__");
  PyRun_SimpleString ("print mytest.transform ('life')");

No the program name in the Py_SetProgramName must be the path of the 'python' executable ! I mean something like /usr/local/bin/python , or wherever your python 2.5 command is.

Well that didnt work either. Can it be a linking error?
When I installed python and linked it to the c++ program, initially it gave me a compiler error because it couldnt find the python library. So I linked it to the library that came with the source.

On my system the python library are here

/usr/lib/python2.5/config/libpython2.5.a
/usr/lib/python2.5/config/libpython2.5.so

check that there is a 'config' directory in your .../lib/python2.5 and link with the library that it contains. Also I suppose that you have different versions of python, so without the Py_SetProgramName, it loads the wrong version of python. Also the documentation says that if there is an environment variable PYTHONHOME, it overrides the call to Py_SetProgramName, so you should remove this variable in that casse. Finally, you say it fails, but is there an error message ? (never say it fails without describing how it fails) :)

I have changed my linking to the library in the config folder. I dont have an env variable called PYTHONHOME, but I did define a variable called PYDIR that is set to the new installation. After compiling, same message :

'import site' failed; use -v for traceback
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: No module named mytest
Traceback (most recent call last):
File "<string>", line 1, in <module>
NameError: name 'mytest' is not defined
Traceback (most recent call last):
File "<string>", line 1, in <module>
NameError: name 'mytest' is not defined

Crazy!

You can try to set the environment variable PYTHONPATH to the directory which contains mytest.py. Otherwise, attach your files to a post, and also try to import just the module 'site' to see if this works.

That worked. I used :

PyRun_SimpleString (import sys; sys.path.append('/dir'));

command to find the directory where mytest.py is stored. And then I added the path to PYTHONPATH in my .cshrc file. Both worked.

I still get the 'import site' failed error once followed by the messages in the module. I am thinking it might be because of the 'import sys' command. Am I correct?

Also is there a way for me to set the path dynamically?
I tried

Py_Initialize ();

  PyRun_SimpleString("import sys; import os; sys.path.append(os.path.abspath(' '))");

  PyRun_SimpleString ("import mytest");
  PyRun_SimpleString ("print mytest.__file__");
  PyRun_SimpleString ("print mytest.transform ('life')");

It didnt work.

You should try to print sys.path to check that it contains the folder of your python library .../lib/python2.5 (and not another python library if you have different pythons). Also directories are searched in the order where they appear in sys.path. So if you want to be sure that a directory is reached first, you can use sys.path.insert(0, "directory") instead of sys.path.append

Yes, but the full path to the "directory" will have to be given. If I am not wrong that will be the same as putting the directory path at the beginning of PYTHONPATH.

I want to know if there is a way Python can find the current directory path of my executable and that way I can just specify the .py folder relative to that path and put it in sys.path.insert ().

sys.executable returns the path where the python executable is stored right?
What I want is something like

os.path.abspath(' ')

to get the current working directory of my executable and not the python executable.

I tried using the command :

sys.path.insert (0, os.path.abspath('')

and it bombed :)

Did you try to insert explicitely the path to your directory instead of calling os.path.abspath ? Also, could you print sys.path and put this in a post, together with the path to your programs ?