Skip to content

Commit

Permalink
- For multi Python module setups, clean previously parsed module
Browse files Browse the repository at this point in the history
  functions in __main__'s dictionary, if any, so that only current
  module functions are registered.
  • Loading branch information
gthess committed Oct 16, 2023
1 parent 122dd6c commit e4510c7
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 0 deletions.
3 changes: 3 additions & 0 deletions doc/Changelog
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
- Expose the configured listening and outgoing interfaces, if any, as
a list of strings in the Python 'config_file' class instead of the
current Swig object proxy; fixes #79.
- For multi Python module setups, clean previously parsed module
functions in __main__'s dictionary, if any, so that only current
module functions are registered.

13 October 2023: George
- Better fix for infinite loop when reading multiple lines of input on
Expand Down
30 changes: 30 additions & 0 deletions pythonmod/pythonmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,34 @@ struct pythonmod_qstate {
PyObject* data;
};

/* The dict from __main__ could have remnants from a previous script
* invocation, in a multi python module setup. Usually this is fine since newer
* scripts will update their values. The obvious erroneous case is when mixing
* python scripts that make use of both 'init' and 'init_standard'. This
* results in 'init_standard' to persist on following scripts that don't use it
* (thus not replacing it). This is also problematic in case where a script
* does not define a required function but a previously loaded script did. The
* current solution is to make sure to clean offensive remnants that influence
* further parsing of the individual scripts.
*/
static void
clean_python_function_objects(PyObject* dict) {
const char* function_names[] = {
"init",
"init_standard",
"deinit",
"operate",
"inform_super"
};
size_t i;

for(i=0; i<sizeof(function_names)/sizeof(function_names[0]); i++) {
if(PyDict_GetItemString(dict, function_names[i]) != NULL) {
PyDict_DelItemString(dict, function_names[i]);
}
}
};

/* Generated */
#ifndef S_SPLINT_S
#include "pythonmod/interface.h"
Expand Down Expand Up @@ -418,6 +446,8 @@ int pythonmod_init(struct module_env* env, int id)
Py_XINCREF(pe->module);
pe->dict = PyModule_GetDict(pe->module);
Py_XINCREF(pe->dict);
clean_python_function_objects(pe->dict);

pe->data = PyDict_New();
/* add the script filename to the global "mod_env" for trivial access */
fname = PyString_FromString(pe->fname);
Expand Down

0 comments on commit e4510c7

Please sign in to comment.