The OpenERP python code development cycle is to edit your code, restart the server and test it. Restarting the server is necessary, because it's what makes your source code to be reloaded into memory, but it adds an annoying delay in your work pace.
Since python is such a dynamic language, I wonder if there is a way to force a running python interpreter (the app server ) to reload on the fly a code module, so that it can be tested without restarting the app server?
Update: Following down the reload
path suggested by @ecatmur, I got the the code below, but it still doesnt work:
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)
The reload() is used to reload a previously imported module or loaded module. This comes handy in a situation where you repeatedly run a test script during an interactive session, it always uses the first version of the modules we are developing, even we have made changes to the code.
To refresh a web page using the selenium module in Python, we use the refresh() function. This is shown in the code below. The refresh() will refresh the web page, acting just like the refresh button of a web browser or clicking the 'F5' button on your keyboard.
Instead, to restart a process in Python, you must create a new instance of the process with the same configuration and then call the start() function.
In Python, modules are accessed by using the import statement. When you do this, you execute the code of the module, keeping the scopes of the definitions so that your current file(s) can make use of these.
The reload
built-in function will reload a single module. There are various solutions to recursively reload updated packages; see How to re import an updated package while in Python Interpreter?
Part of the issue is that existing objects need to be adjusted to reference the new classes etc. from the reloaded modules; reimport does this reasonably well. In the IPython interactive console I use the autoreload extension, although it's not designed for use outside IPython.
UPDATE: since v8 the Odoo server provides an --auto-reload
option to perform this.
Excellent question, I've often wondered the same. I think the main problem with the code you posted is that it only reloads the OpenERP module's __init__.py
file, not all the individual files. The reimport
module recommended by ecatmur takes care of that, and I also had to unregister the module's report parsers and model classes before reloading everything.
I've posted my module_reload
module on Launchpad. It seems to work for changes to model classes, osv_memory
wizards, and report parsers. It does not work for old-style wizards, and there may be other scenarios that don't work.
Here's the method that reloads the module.
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's 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 {}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With