pony
pony copied to clipboard
Pony and nuitka or pyinstaller
I am trying to make a standalone version of my python 2.7.12 program using the compiler nuitka and I also tried it with the freezer pyinstaller. But they fail on line 200 in pony\utils\utils.py which says:
def import_module(name):
"import_module('a.b.c') -> <module a.b.c>"
mod = sys.modules.get(name)
if mod is not None: return mod
mod = __import__(name) # <------------- line 200
components = name.split('.')
for comp in components[1:]: mod = getattr(mod, comp)
return mod
If I understand correctly, they cannot handle these import statements very well. I think it would be nice if pony is compatible with these tools which requires probably a different implementation of this import_module function. Any chance this will become available or otherwise, maybe some workarounds?
Hm, why not importlib.import_module?
I do not understand what you mean; do I need to replace import_module of pony with this built-in function?
Apparently, the method import_module
is only use in the method _bind
in pony/orm/core.py
.
What I did as a quick fix was to hardcode the import command of the type of database I use, that is sqlite. Of course, this will break as soon as I use another db but works for now. Any change this will
def _bind(self, *args, **kwargs):
# argument 'self' cannot be named 'database', because 'database' can be in kwargs
if self.provider is not None:
throw(TypeError, 'Database object was already bound to %s provider' % self.provider.dialect)
if not args:
throw(TypeError, 'Database provider should be specified as a first positional argument')
provider, args = args[0], args[1:]
if isinstance(provider, type) and issubclass(provider, DBAPIProvider):
provider_cls = provider
else:
if not isinstance(provider, basestring): throw(TypeError)
if provider == 'pygresql': throw(TypeError,
'Pony no longer supports PyGreSQL module. Please use psycopg2 instead.')
# provider_module = import_module('pony.orm.dbproviders.' + provider)
# provider_cls = provider_module.provider_cls
from pony.orm.dbproviders.sqlite import SQLiteProvider as provider_cls # <------ replaced the two commented lines above this line, with this line
self.provider = provider = provider_cls(*args, **kwargs)
This works for pyinstaller, not sure if it works for nuitka as I still have some issues there; those issues may be unrelated to pony though.
Ok, could not resist to try your suggestion (at least what I understood of @andreymal 's suggestion).
In pony/orm/core.py
, when I imported import_module as built-in function instead of the pony\utils\utils.py
version, pyinstaller also works.
In pony/orm/core.py
, I removed the import of import_module
from pony.utils
leading to line 29-30:
from pony.utils import localbase, decorator, cut_traceback, throw, reraise, truncate_repr, get_lambda_args, \
deprecated, parse_expr, is_ident, tostring, strjoin, concat #, <---import_module, is removed here
and added the following line below it:
from importlib import import_module
I think this would be a small change in the source and would suggest to use this for the next release.
I seem to be having a similar issue packaging my own program with PyInstaller. I was able to get around it by manually importing pony.orm.dbproviders.sqlite
, as my program uses SQLite. Are there any plans to address this issue? Perhaps a way of specifying a database provider that requires the provider to imported?
Edit: One can also include pony.orm.dbproviders.sqlite
(or any other database provider) as a PyInstaller hidden import to fix this.
I have the same probleme. I just manually import it: https://github.com/jgirardet/mydevoirs/blob/master/mydevoirs/database/models.py
@jgirardet Thank you! It's not a fix, but you saved my day.