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.

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

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 ?

This question has already been answered. Start a new discussion instead.