Mailing List Archive

embedding
I've been reading through my docs for hours, and I can't seem to find an
answer to this.. How do you create an object in the main namespace and
how do you get the value of an object in the main namespace? Without
using PyRun*

thanks

Patrick


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
embedding [ In reply to ]
vysteric@my-deja.com wrote:
: I've been reading through my docs for hours, and I can't seem to find an
: answer to this.. How do you create an object in the main namespace and
: how do you get the value of an object in the main namespace? Without
: using PyRun*

: thanks

: Patrick

Hi Patrick,

I'm surprised that noone has answered this before now. You will want
to first import the module, then access attributes of it.

PyObject *module__main__;
PyObject *MyName, *whom;

module__main__ = PyImport_ImportModule("__main__");
/* try:...except:...*/
if (module__main__ == NULL)
return NULL;
MyName = PyString_FromString("Arcege");

if (PyObject_SetAttrString(module__main__, "person_name", MyName) == -1) {
/* an exception */
Py_DECREF(module__main__);
Py_DECREF(MyName);
return NULL;
}
Py_DECREF(MyName);

whom = PyObject_GetAttrString(module__main__, "person_name");
if (whom == NULL) {
Py_DECREF(module__main__);
return NULL;
}
PyObject_Print(whom, stdout, Py_PRINT_RAW);
Py_DECREF(module__main__);

This is roughly equivalent to:
import __main__
__main__.person_name = "Arcege"
print __main__.person_name

I use this a good deal to get access to other modules in my own code.

But, if you mean: "How can I create an object in the global namespace?"
That is slightly different; for this you can use PyEval_GetGlobals().
This returns a dictionary, on which you can then use
PyDict_GetItemString() and PyDict_SetItemString().

-Arcege
embedding [ In reply to ]
>But, if you mean: "How can I create an object in the global namespace?"
>That is slightly different; for this you can use PyEval_GetGlobals().

>This returns a dictionary, on which you can then use
>PyDict_GetItemString() and PyDict_SetItemString().


BUT PyEval_GetGlobals will return null it it is not called from within
Python. This will never be the case when extending Python, but when Python
is embedded, it may happen. This is because PyRun_* define the global
scope, so if you're not somehow inside a PyRun_ thing (e.g. module called
from python called from embedder), there are no globals.

In an embedded-python situation, if you decide that all of your PyRun_*
calls are going to use __main__ as the global namespace,
PyModule_GetDict(PyImport_AddModule("__main__")) will do it.
embedding [ In reply to ]
The following (excerpted, no error-checking)
PyObject* mod = PyImport_AddModule("__main__");
PyObject* mdict = PyModule_GetDict(mod);
PyObject* obj = get_a_python_object();
PyDict_SetItemString(mdict, "YOUR NAME HERE", pyd);

This seems simpler than Reilly's method. So is my code wrong, or (gasp) is
there More Than One Way To Do It?
/r$
embedding [ In reply to ]
Rich Salz <salzr@certco.com> wrote:
: The following (excerpted, no error-checking)
: PyObject* mod = PyImport_AddModule("__main__");
: PyObject* mdict = PyModule_GetDict(mod);
: PyObject* obj = get_a_python_object();
: PyDict_SetItemString(mdict, "YOUR NAME HERE", pyd);

: This seems simpler than Reilly's method. So is my code wrong, or (gasp) is
: there More Than One Way To Do It?
: /r$

More than one way to do it in Python? "Ni!" to you. ;) Yes, there is
more than one way to do it. I don't think it's simplier myself, but
that's just me.

It is the (exact) difference between:
mod = __import__("__main__")
setattr(mod, "YOUR NAME HERE", obj)

and:
mod = __import__("__main__")
mdict = mod.__dict__
mdict['YOUR NAME HERE'] = obj

Using the attribute interface is preferable to digging into the
internals. (I won't get into spaces in namespace names.)

-Arcege