Подтвердить что ты не робот

Принудительный интерпретатор python для перезагрузки модуля кода

Цикл разработки кода Python OpenERP - это отредактировать код, перезапустить сервер и протестировать его. Перезапуск сервера необходим, потому что это то, что заставляет ваш исходный код перезагружаться в память, но он добавляет раздражающую задержку в вашем рабочем темпе.

Поскольку python - такой динамический язык, мне интересно, есть ли способ заставить запущенный интерпретатор python (сервер приложений) перезагрузить "на лету" модуль кода, чтобы его можно было протестировать без перезапуска сервера приложений?

Update: После использования пути reload, предложенного @ecatmur, я получил код ниже, но он все еще не работает:

class module(osv.osv):
    _inherit = "ir.module.module"

    def action_reload(self, cr, uid, ids, context=None):
        for obj in self.browse(cr, uid, ids, context=context):
            modulename = 'openerp.addons.' + obj.name
            tmp = __import__(modulename)
            pycfile = tmp.__file__
            modulepath = string.replace(pycfile, ".pyc", ".py")
            code=open(modulepath, 'rU').read()
            compile(code, modulename, "exec")
            execfile(modulepath)
            reload( sys.modules[modulename] )
        openerp.modules.registry.RegistryManager.delete(cr.dbname)
        openerp.modules.registry.RegistryManager.new(cr.dbname)
4b9b3361

Ответ 1

ОБНОВЛЕНИЕ: поскольку v8 сервер Odoo предоставляет параметр --auto-reload для выполнения этого.

Отличный вопрос, я часто задавался вопросом. Я думаю, что основная проблема с кодом, который вы опубликовали, заключается в том, что он перезагружает только файл модуля __init__.py OpenERP, а не все отдельные файлы. Модуль reimport, рекомендованный ecatmur, позаботится об этом, и мне также пришлось отменить регистрацию парсеров и классов моделей до перезагрузки.

Я разместил свой module_reload модуль на Launchpad. Кажется, он работает для изменений классов моделей, мастеров osv_memory и синтаксических агентов отчетов. Это не работает для мастеров старого стиля, и могут быть другие сценарии, которые не работают.

Здесь метод, который перезагружает модуль.

def button_reload(self, cr, uid, ids, context=None):
    for module_record in self.browse(cr, uid, ids, context=context):
        #Remove any report parsers registered for this module.
        module_path = 'addons/' + module_record.name
        for service_name, service in Service._services.items():
            template = getattr(service, 'tmpl', '')
            if template.startswith(module_path):
                Service.remove(service_name)

        #Remove any model classes registered for this module
        MetaModel.module_to_models[module_record.name] = []                    

        #Reload all Python modules from the OpenERP module directory.
        modulename = 'openerp.addons.' + module_record.name
        root = __import__(modulename)
        module = getattr(root.addons, module_record.name)

        reimport(module)
    RegistryManager.delete(cr.dbname)
    RegistryManager.new(cr.dbname)
    return {}

Ответ 2

reload встроенная функция перезагрузит один модуль. Существуют различные решения для рекурсивной перезагрузки обновленных пакетов; см. Как повторно импортировать обновленный пакет в Python Interpreter?

Часть проблемы заключается в том, что существующие объекты должны быть скорректированы для ссылки на новые классы и т.д. из перезагруженных модулей; reimport делает это достаточно хорошо. В интерактивной консоли IPython я использую расширение autoreload, хотя он не предназначен для использования вне IPython.

Ответ 4

Если вы просто занимаетесь разработкой, перезагрузите его в порядке, но если вы находитесь в развертывании, вам следует избегать таких трюков, потому что они никогда не будут работать в течение 100% времени. Всегда будут какие-то тонкости, где изменения не будут распространяться. Например, если какой-то код копирует объект, а не просто использует ссылки на него, он будет оставаться неизменным после перезагрузки. И наоборот, если ссылка не распространяется правильно, то сравнение is завершится неудачно, когда ожидается, что он будет работать, потому что один из объектов будет из "старого" неизданного модуля. Единственный 100% -ный способ пожара - перезагрузить все, что по сути является перезапуском сервера.

Даже если вы просто делаете разработку, вы будете иногда сталкиваться с ложными ошибками, которые являются лишь побочными эффектами неполной перезагрузки. Если вам не придётся попробовать выполнить чистый перезапуск, вы можете потратить много времени, пытаясь отследить ошибку phantom. Поэтому, если вы закончите делать это, держите это в глубине своего разума.

Ответ 5

встроенная функция перезагрузки перезагружает модуль или пакет. Однако в контексте OpenERP вам нужно немного больше, так как перезагрузка приложения OpenERP требует обработки файлов XML и т.д. Но я согласен, что иметь это в OpenERP было бы хорошо.