Kasper Peeters wrote:
I could in principle decide to make these settings a proper Python object, and ask the user to create one and pass it along at every C-function call.
I would make the C functions methods of the object holding the settings. Your nested function example would then look something like this: def fun(): cpp = Cpp() cpp.set_some_flag() cpp.cfun(...) def fun2(): cpp2 = Cpp(cpp) cpp2.set_some_other_flag() cpp2.fun(...)
Hence my question: how can I ask, purely on the C side, for Python to pull objects into the local frame?
You can't. Firstly, it's not possible to add locals to a frame that didn't exist when the bytecode was compiled. The compiler figures out how many locals there are, allocates them in an array, and generates bytecodes that reference them by their array index. I'm not sure how you think you're adding a local from C code. If you're using PyEval_GetLocals(), that only gives you a dict containing a *copy* of the locals; modifying that dict doesn't change the locals in the function's frame. Secondly, the way references to outer scopes is implemented is by effectively passing the referenced variables as implicit parameters. If the bytecode of the nested function doesn't reference a given variable in the outer function, it doesn't get passed in. Again, this is determined when the bytecode is compiled and can't be changed at run time.
Final note: I am actually trying to make this look as close as possible to an older custom-built language, which didn't require passing the settings object either, so it's kinda important to make the user feel 'at home'.
I doubt it's worth the extreme level of hackery that would be required to make it work, though. I think it would be better to provide a clean, pythonic API that makes the scope of the options explicit, rather than try to mimic another language's dubious implicit scoping features. -- Greg -- https://mail.python.org/mailman/listinfo/python-list