85 lines
2.9 KiB
Plaintext
85 lines
2.9 KiB
Plaintext
From: arcege at shore.net (Michael P. Reilly)
|
|
Date: Wed, 28 Apr 1999 19:28:42 GMT
|
|
Subject: running application config files written in Python
|
|
References: <m33e1lcvm7.fsf@froydnj.laptop.rose-hulman.edu>
|
|
Message-ID: <KjJV2.150$pX2.88806@news.shore.net>
|
|
Content-Length: 2668
|
|
X-UID: 950
|
|
|
|
Nathan Froyd <nathan.froyd at rose-hulman.edu> wrote:
|
|
: Say I have an application whose configuration language I want to be
|
|
: Python. I have all my extra types implemented in C. Now what I'm
|
|
: wondering is what's the best way to run that file so that the
|
|
: functions, variables, etc. get imported into the Python interpreter
|
|
: embedded in my program?
|
|
|
|
: Along the same lines, once I have run the file, what's the easiest way
|
|
: to find out if a particular function/variable has been defined? For
|
|
: example, if I always wanted to run the user-defined function
|
|
: `startup_func', how would I go about doing that?
|
|
|
|
You can do this in two ways easily (and other ways less easily).
|
|
|
|
1) Store the configuration files as modules, then import them.
|
|
If you are worried about security, you can import them using rexec.
|
|
|
|
char modulename[] = "app_config";
|
|
PyObject *config_module, *config_dict;
|
|
PyObject *startup_func, *result;
|
|
Py_Initialize();
|
|
|
|
if ((config_module = PyImport_ImportModule(modulename)) != NULL &&
|
|
(config_dict = PyModule_GetDict(config_module)) != NULL) {
|
|
startup_func = PyDict_GetItemString(config_dict, "startup_func");
|
|
/* look for startup function, but ignore if not present */
|
|
result = NULL;
|
|
if (startup_func != NULL && PyCallable_Check(startup_func))
|
|
result = PyObject_CallFunction(startup_func, "");
|
|
if ((startup_func == NULL || result == NULL) &&
|
|
PyErr_Occurred() &&
|
|
!PyErr_ExceptionMatches(PyExc_AttributeError))
|
|
/* ignore AttributeError exceptions */
|
|
PyErr_Print();
|
|
PyErr_Clear();
|
|
Py_XDECREF(startup_func);
|
|
Py_XDECREF(result);
|
|
} else {
|
|
/* the module could not be loaded */
|
|
PyErr_Print();
|
|
Py_Exit(1);
|
|
}
|
|
|
|
All values are stored in the module (accessed thru config_dict). The
|
|
exception handling is more verbose then the next method.
|
|
|
|
2) Run the equivalent of execfile().
|
|
|
|
char filename[] = "app_config.py";
|
|
FILE *app_config;
|
|
|
|
Py_Initialize();
|
|
|
|
app_config = fopen(filename, "r");
|
|
if (PyRun_Simplefile(app_config, filename) == -1) {
|
|
fclose(app_config);
|
|
/* the traceback has already been written to stderr */
|
|
Py_Exit(1);
|
|
}
|
|
fclose(app_config);
|
|
PyRun_SimpleString("try: startup_func()\n\
|
|
except NameError: pass\n");
|
|
|
|
All values are stored in the current namespace (the module __main__,
|
|
and accessed thru the undocumented function PyEval_GetGlobals() or thru
|
|
other PyRun_* calls). If there are exceptions raised, PyRun_* calls
|
|
handle the output; the return value is either -1 for failure, 0 for
|
|
success.
|
|
|
|
I would suggest using method (1). Good luck.
|
|
-Arcege
|
|
|
|
|
|
|
|
|
|
|