oe7升级到oe8中import的使用
oe 7.0到oe 8.0 切换的时候发现我们系统的很多的module 无法load , import的时候出错, 后来发现oe 8.0自己的addons 也都做了修改在import自己的addons的时候都加了openerp.addons 命名空间, 这是为什么, oe 8.0为什么要这么做,我找出了背后真正的原因:
Openerp 7.0 的时候系统支持两种import 方式一种是import <module> 一种是 import openerp .addons. <module> 这种方式, 我们自己的addons 中使用import 大部分是使用的第一种, 现在将我们的addons 迁移到8.0的时候发现很多Could't load module 的情况, 这是什么原因?
1、 首先需要说明openerp 为什么会由两种import 方式, openerp 没有使用默认的python import 机制, 而是在python的import 机制上做了hook , 做了一个自己的importer, 也就是上面说的两种情况。
2、7.0的两种import方式为什么到8.0的时候只剩下第二种import openerp.addons.<module>这种方式, 却不支持第一种方式了, 这是因为为了方式import 冲突的情况, 比如:python的标准库中一个module 叫resource, 而openerp 中也有这样一个自己的module 如果使用第一种import 方式, 这个时候会出现module 混淆的问题。所以从8.0开始 openerp的 addons 必需添加openrp.addons 命名空间用来加以区分。
3、在oe 7.0 和odoo 8.0中这个差异的具体代码是在哪里实现的呢?
Openerp 7.0 中 server->openerp->modules->module.py 的 AddonsImportHook class 中有这样一个方法:
def find_module(self, module_name, package_path):
module_parts = module_name.split('.')
if len(module_parts) == 3 and module_name.startswith('openerp.addons.'):
return self # We act as a loader too.
# TODO list of loadable modules can be cached instead of always
# calling get_module_path().
if len(module_parts) == 1 and \
get_module_path(module_parts[0],
display_warning=False):
try:
# Check if the bare module name clashes with another module.
f, path, descr = imp.find_module(module_parts[0])
_logger.warning("""
Ambiguous import: the OpenERP module `%s` is shadowed by another
module (available at %s).
To import it, use `import openerp.addons.<module>.`.""" % (module_name, path))
return
except ImportError, e:
# Using `import <module_name>` instead of
# `import openerp.addons.<module_name>` is ugly but not harmful
# and kept for backward compatibility.
return self # We act as a loader too.
而在8.0中这个方法是这样的:
def find_module(self, module_name, package_path):
module_parts = module_name.split('.')
if len(module_parts) == 3 and module_name.startswith('openerp.addons.'):
return self # We act as a loader too.
很明显 8.0中比7.0中少了黄色标注的这一部分, 那黄色的这一部分是做什么用的呢, 它就是兼容import <module>这种 方式的实现。 而在8.0中不再支持这种import
Openerp 7.0 的时候系统支持两种import 方式一种是import <module> 一种是 import openerp .addons. <module> 这种方式, 我们自己的addons 中使用import 大部分是使用的第一种, 现在将我们的addons 迁移到8.0的时候发现很多Could't load module 的情况, 这是什么原因?
1、 首先需要说明openerp 为什么会由两种import 方式, openerp 没有使用默认的python import 机制, 而是在python的import 机制上做了hook , 做了一个自己的importer, 也就是上面说的两种情况。
2、7.0的两种import方式为什么到8.0的时候只剩下第二种import openerp.addons.<module>这种方式, 却不支持第一种方式了, 这是因为为了方式import 冲突的情况, 比如:python的标准库中一个module 叫resource, 而openerp 中也有这样一个自己的module 如果使用第一种import 方式, 这个时候会出现module 混淆的问题。所以从8.0开始 openerp的 addons 必需添加openrp.addons 命名空间用来加以区分。
3、在oe 7.0 和odoo 8.0中这个差异的具体代码是在哪里实现的呢?
Openerp 7.0 中 server->openerp->modules->module.py 的 AddonsImportHook class 中有这样一个方法:
def find_module(self, module_name, package_path):
module_parts = module_name.split('.')
if len(module_parts) == 3 and module_name.startswith('openerp.addons.'):
return self # We act as a loader too.
# TODO list of loadable modules can be cached instead of always
# calling get_module_path().
if len(module_parts) == 1 and \
get_module_path(module_parts[0],
display_warning=False):
try:
# Check if the bare module name clashes with another module.
f, path, descr = imp.find_module(module_parts[0])
_logger.warning("""
Ambiguous import: the OpenERP module `%s` is shadowed by another
module (available at %s).
To import it, use `import openerp.addons.<module>.`.""" % (module_name, path))
return
except ImportError, e:
# Using `import <module_name>` instead of
# `import openerp.addons.<module_name>` is ugly but not harmful
# and kept for backward compatibility.
return self # We act as a loader too.
而在8.0中这个方法是这样的:
def find_module(self, module_name, package_path):
module_parts = module_name.split('.')
if len(module_parts) == 3 and module_name.startswith('openerp.addons.'):
return self # We act as a loader too.
很明显 8.0中比7.0中少了黄色标注的这一部分, 那黄色的这一部分是做什么用的呢, 它就是兼容import <module>这种 方式的实现。 而在8.0中不再支持这种import