[Python-Dev] Best practice for new namespace (from C/API) (original) (raw)
Campbell Barton ideasman42 at gmail.com
Thu Jul 29 00:11:39 CEST 2010
- Previous message: [Python-Dev] Compiling Free Cad on Rhel5
- Next message: [Python-Dev] Best practice for new namespace (from C/API)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Hi, I'm writing because I'm working on a project where the user can run scripts that don't reference a file but use internal application text data. Otherwise we are not doing anything tricky, only that the scripts should each run independently (no cruft left from the previous scripts namespace, sharing sys.modules etc is fine).
Something which is unclear to me even after looking over pythonrun.c is the correct way to setup a namespace.
For years we have been doing this and it seemed to work fine... PyObject d = PyDict_New(); // new namespace PyDict_SetItemString(d, "builtins", PyEval_GetBuiltins()); PyDict_SetItemString(d, "file", PyString_FromString(filename)); // fake, avoids sys.argv[0] being used for warnings. / --- snip ---*/ PyEval_EvalCode(compiled_text, d, d);
Recently a developer reported a bug where pickle wasn't working, it turns out that in a few places python expects the main modules namespace to match that if the running script: _pickle.c's save_global() in this case
eg:
spam = 10 print(import("main").dict["spam"]) ... 10
Once I found this was the problem it was simple to use main's namespace however there are still things that are not clear about exactly how this should be done.
Simplified code... PyObject item, dict= PyModule_GetDict(PyImport_AddModule("main")); PyDict_Clear(dict); PyDict_SetItemString(dict, "builtins", PyImport_AddModule("builtins")); item = PyUnicode_FromString( "main" ); PyDict_SetItemString( dict, "name", item ); Py_DECREF(item); PyDict_SetItemString(d, "file", PyString_FromString(filename)); // fake, avoids sys.argv[0] being used for warnings. / --- snip ---/ PyEval_EvalCode(compiled_text, dict, dict);
Still this leaves me with the following questions...
- Whats the best way to manage the namespace for running multiple scripts one after another? clear and initialize main's dict each time?, keep a copy and restore it after each run?
- should the original main namespace be restored after running a script?
- pickle expects: import("main").dict == the current namespace, is this apart of the python spec or just something specific to pickle?
- PyDict_SetItemString(d, "builtins", PyEval_GetBuiltins()) acts differently to PyDict_SetItemString(dict, "builtins", PyImport_AddModule("builtins")), using the PyEval_GetBuiltins() dict adds every member of builtins when running: print(import("main").dict.keys()), rather then just showing builtins.
--
- Campbell
- Previous message: [Python-Dev] Compiling Free Cad on Rhel5
- Next message: [Python-Dev] Best practice for new namespace (from C/API)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]