I am using boost.python to wrap a C++ class 'A' which takes a string as constructor. I then have a function 'fun(A& arg)' which takes a reference to an 'A' as parameter. I would like to have a python wrapper for 'fun' which is such that if I pass a variable which is a reference to a python string, this reference is first automatically converted to a reference to an 'A'.
An example might help. On the python side, I would like to be able to do this:
a = 'some string'
fun(a)
and then have 'a' actually be (a reference to) an 'A', not (a reference to) the original string. I want to do this because I would like to be able to avoid writing this as
a = A('some string')
fun(a)
(you may have good reasons to doubt that this is a relevant saver, but let's just assume that it matters for me).
Is anything like this possible? If not using boost.python, perhaps directly using the Python-C API?
Note: I am aware of the fact that if I would write
fun('some string')
there is no way for the reference to the string to be converted to be a reference to some other type.
This is possible, but the solution may be dependent on the Python implementation.
For example, in Python 2.7, the
inspect
module andsys.settrace()
can be used to modifylocals()
on a specific frame. This can also be accomplished in the Python/C API, but it is often far more manageable to manipulate Python frames within Python.In the below
example.py
, theupdate_locals()
function will update thelocals()
in a given frame:Interactive usage:
The
x
variable referenced theint(42)
object, but theexample.update_locals()
function changedx
to referencestr('3.14')
object.With being able to modify the caller's frame, the next step is to monkey patch the C++
fun()
in Python to construct an instance ofA
if the argument is an instance ofstr
, then delegate to the C++fun(A&)
function and update the caller's frame.In example below, a C++
Spam
type andfun(Spam&)
function are exposed to the_example
Python module.A higher level
example
module will monkey patch_example.fun()
to construct aSpam
object if the argument provided tofun()
is an instance ofstr
and manipulate the caller's frame in a similar manner as demonstrated above:Interactive usage:
Note that the frame manipulation in the above example only modifies's
fun()
's caller's frame and not the entire stack.For that to work
fun(a)
would have to modify the originala
object reference. Whatfun(a)
actually gets is a local copy of object referencea
, not the originala
object reference passed as an argument.In other words, Python does not work like that, you would need to call it as
a = fun(a)
to be able to change referencea
(not the object it refers to).