wlav / cppyy

Other
401 stars 41 forks source link

Mocking cppyy code / Reloading newer versions of shared libs #46

Closed ianfhunter closed 2 years ago

ianfhunter commented 2 years ago

I have a function that produces a random output roll_dice() and I want to mock that function so I can test dependent functions. (replacing the equivalent of return rand()%(stop+1-start)+start; with f"return {x};"

I haven't been able to find a way to do this in cppyy. I have tried to reload the module using importlib and repeating the load_libary commands with new versions of my .so file to no avail.

Is there a way to reload cppyy? My mocking system works for the first tests, but everything after this fails.

wlav commented 2 years ago

No, cppyy as a module can not be reloaded as Python will not reload shared libraries (the actual functionality of cppyy is written in C++, not Python). Cling can, up to a limited extend, unload functions (simple redefinition is only available for variables), but until OrcJITv2 comes along that will remain flaky.

Are the to functions to be reloaded JITted (in which case they could be versioned or namespaced) or compiled?

ianfhunter commented 2 years ago

They are currently compiled, but I could convert them to be JIT if there was a mechanism to overwrite defined functions.

However, I'm using a C library which wo'nt support namespacing. However, I think I can work around this by setting some global variables and a wrapper function, just won't be as neat.

ianfhunter commented 2 years ago

This seems to work reasonably well for me. Thanks for replying so promptly!

xayjin commented 2 years ago

Although not quit unstand you request, I have a trick to reload .so file without restart cppyy. The boost::dll::shared_library is useful. First of all: cppyy.include("boost/dll/shared_library.hpp")

  1. load your .so file
  2. get function in .so file
  3. call function
  4. unload .so
  5. get new version .so file
  6. goto step 1