upbge icon indicating copy to clipboard operation
upbge copied to clipboard

Binary Python modules are not re-imported

Open vlad0337187 opened this issue 5 years ago • 14 comments

Hello.

After you stop game engine and start it again, all text Python modules are re-loaded. So if I made some changes to code, new actual code will be launched.

But this doesn't apply to binary Python modules, they aren't reloaded. Even if you compiled a new version, you need to close and re-open Blender itself to see actual changes.

Only if you import that module from some python code, you can make imp.reload(binary_module_name), but if you specified binary module name in Python controller directly - you can't reload it until Blender restart.

Here video with steps to reproduce: https://youtu.be/EYFQExAyjLE

(I wrote binary module in Nim there, but same applies if you'll write it in Cython, for example)

Hope, it can be fixed easily =)

System: Linux Mint 19 x64 Cinnamon UPBGE: 0.2.4

Best regards, Vladislav

vlad0337187 avatar Nov 03 '18 12:11 vlad0337187

I'm not an expert, but I believe it works properly.

Masterblop avatar Nov 03 '18 13:11 Masterblop

Interesting issue! Although not sure if that is an issue caused by the way Python internalize modules...

paul-marechal avatar Nov 03 '18 15:11 paul-marechal

I wonder if we can unload the module using PY?

BluePrintRandom avatar Nov 03 '18 17:11 BluePrintRandom

import sys
del sys.modules['ModuleName']

also see -

in Python 3, reload was moved to the imp module. In 3.4, imp was deprecated in favor of importlib, and reload was added to the latter. When targeting 3 or later, either reference the appropriate module when calling reload or import it.

BluePrintRandom avatar Nov 03 '18 17:11 BluePrintRandom

Maybe the changes would happen somewhere around this method, although I wouldn't know how to make the BGE reload the module if it already exists...

Am on Windows so I have no idea how to reproduce.


Edit: https://docs.python.org/3/c-api/import.html#c.PyImport_GetModule So maybe just checking that before importing, and if not nullptr then reload it I guess?

@panzergame would that make sense?

paul-marechal avatar Nov 03 '18 18:11 paul-marechal

If you launch blenderplayer works?

lordloki avatar Nov 03 '18 18:11 lordloki

@lordloki given that it will be a new process at each launch, I would assume that it will work (because it will reload the Python interpreter each time)

paul-marechal avatar Nov 03 '18 18:11 paul-marechal

@lordloki , @marechal-p , just checked with standalone player. All works as expected =)

vlad0337187 avatar Nov 09 '18 01:11 vlad0337187

Hm.. Seems there are problems with reloading binary modules in Python itself. I'm not sure that approach from PR would work. https://bugs.python.org/issue1144263

Made such function to perform "force" reloading: https://pastebin.com/tfquvGd0 But It works on linux, I didn't tested it on Windows. Not sure it could be easily re-writen to C and be merged with UPBGE core code.

vlad0337187 avatar Nov 09 '18 03:11 vlad0337187

@vlad1777d This way can you point to a Python script that would delegate the call from the BGE to your native .so module ?

I was thinking that in scripts importing native modules, we could have a require function (similar to the way JS works in a node env) that would basically do the correct import/reload?

from loader import require
native = require('some_native_module')

paul-marechal avatar Nov 09 '18 12:11 paul-marechal

@marechal-p , yes, I think so.

vlad0337187 avatar Nov 10 '18 01:11 vlad0337187

@marechal-p I saw that sys.meta_path is used to find modules. Did you try this already ?

panzergame avatar Nov 10 '18 10:11 panzergame

@panzergame never tried, but sys.meta_path just holds a list of finders for modules. What was your idea?

paul-marechal avatar Nov 10 '18 13:11 paul-marechal

I though about registering a finder at the beginning of the list which always failed but register the import calls. But i'm absolutely sure that's a terrible way.

panzergame avatar Nov 10 '18 19:11 panzergame