[IMP] core: improve python external dependencies check
Use pkg_resources.get_distribution() to check if python external dependencies are installed, instead of trying an import. The import test is preserved as a backwards compatibility measure. This better expresses which python distribution needs to be installed from PyPI and allows declaring a minimum supported version using PEP 440 version specifiers. Closes #25541 closes odoo/odoo#25549 Signed-off-by: Christophe Simonis <chs@odoo.com>
This commit is contained in:
@@ -11,6 +11,6 @@
|
||||
'views/res_config_settings_views.xml',
|
||||
],
|
||||
'external_dependencies' : {
|
||||
'python' : ['ldap'],
|
||||
'python' : ['pyldap'],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,6 @@ Belgian cash register. It allows the communication on with a certified Fiscal
|
||||
Data Module but will not modify the behaviour of the Point of Sale.
|
||||
""",
|
||||
'depends': ['hw_proxy'],
|
||||
'external_dependencies': {'python': ['serial']},
|
||||
'external_dependencies': {'python': ['pyserial']},
|
||||
'installable': False,
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ that would need such functionality.
|
||||
""",
|
||||
'depends': ['hw_proxy'],
|
||||
'external_dependencies': {
|
||||
'python' : ['usb.core','serial','qrcode'],
|
||||
'python' : ['pyusb','pyserial','qrcode'],
|
||||
},
|
||||
'installable': False,
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import importlib
|
||||
import io
|
||||
import logging
|
||||
import os
|
||||
import pkg_resources
|
||||
import shutil
|
||||
import tempfile
|
||||
import zipfile
|
||||
@@ -307,16 +308,33 @@ class Module(models.Model):
|
||||
self.clear_caches()
|
||||
return super(Module, self).unlink()
|
||||
|
||||
@staticmethod
|
||||
def _check_python_external_dependency(pydep):
|
||||
try:
|
||||
pkg_resources.get_distribution(pydep)
|
||||
except pkg_resources.DistributionNotFound as e:
|
||||
try:
|
||||
importlib.import_module(pydep)
|
||||
_logger.warning("python external dependency %s should be replaced by it's PyPI package name", pydep)
|
||||
except ImportError:
|
||||
# backward compatibility attempt failed
|
||||
_logger.warning("DistributionNotFound: %s", e)
|
||||
raise Exception('Python library not installed: %s' % (pydep,))
|
||||
except pkg_resources.VersionConflict as e:
|
||||
_logger.warning("VersionConflict: %s", e)
|
||||
raise Exception('Python library version conflict: %s' % (pydep,))
|
||||
except Exception as e:
|
||||
_logger.warning("get_distribution(%s) failed: %s", pydep, e)
|
||||
raise Exception('Error finding python library %s' % (pydep,))
|
||||
|
||||
|
||||
@staticmethod
|
||||
def _check_external_dependencies(terp):
|
||||
depends = terp.get('external_dependencies')
|
||||
if not depends:
|
||||
return
|
||||
for pydep in depends.get('python', []):
|
||||
try:
|
||||
importlib.import_module(pydep)
|
||||
except ImportError:
|
||||
raise ImportError('No module named %s' % (pydep,))
|
||||
Module._check_python_external_dependency(pydep)
|
||||
|
||||
for binary in depends.get('bin', []):
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user