summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabien Meghazi <fme@odoo.com>2016-09-19 14:00:45 +0200
committerFabien Meghazi <fme@odoo.com>2016-09-19 16:35:10 +0200
commit4e546cdb0d5746ab5c3de7c53ba898dcb895f42b (patch)
tree34bca36d05439a4a12dda4491711f195678240ab
parente04b44dad1df732cf0bf09eb4ece825cb5432c67 (diff)
[ADD] shell: add support for more REPLs in shell mode
-rw-r--r--odoo/cli/shell.py47
-rw-r--r--odoo/tools/config.py9
2 files changed, 49 insertions, 7 deletions
diff --git a/odoo/cli/shell.py b/odoo/cli/shell.py
index 082ade3f948..cf7b5ffbce2 100644
--- a/odoo/cli/shell.py
+++ b/odoo/cli/shell.py
@@ -2,16 +2,22 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import code
+import logging
import os
import signal
import sys
import odoo
+from odoo.tools import config
from . import Command
+_logger = logging.getLogger(__name__)
+
+
def raise_keyboard_interrupt(*a):
raise KeyboardInterrupt()
+
class Console(code.InteractiveConsole):
def __init__(self, locals=None, filename="<console>"):
code.InteractiveConsole.__init__(self, locals, filename)
@@ -24,10 +30,13 @@ class Console(code.InteractiveConsole):
readline.set_completer(rlcompleter.Completer(locals).complete)
readline.parse_and_bind("tab: complete")
+
class Shell(Command):
"""Start odoo in an interactive shell"""
+ supported_shells = ['ipython', 'ptpython', 'bpython', 'python']
+
def init(self, args):
- odoo.tools.config.parse_config(args)
+ config.parse_config(args)
odoo.cli.server.report_configuration()
odoo.service.server.start(preload=[], stop=True)
signal.signal(signal.SIGINT, raise_keyboard_interrupt)
@@ -40,11 +49,41 @@ class Shell(Command):
print 'No environment set, use `odoo.py shell -d dbname` to get one.'
for i in sorted(local_vars):
print '%s: %s' % (i, local_vars[i])
- Console(locals=local_vars).interact()
+
+ preferred_interface = config.options.get('shell_interface')
+ if preferred_interface:
+ shells_to_try = [preferred_interface, 'python']
+ else:
+ shells_to_try = self.supported_shells
+
+ for shell in shells_to_try:
+ try:
+ return getattr(self, shell)(local_vars)
+ except ImportError:
+ pass
+ except Exception:
+ _logger.warning("Could not start '%s' shell." % shell)
+ _logger.debug("Shell error:", exc_info=True)
+
+ def ipython(self, local_vars):
+ from IPython import start_ipython
+ start_ipython(argv=[], user_ns=local_vars)
+
+ def ptpython(self, local_vars):
+ from ptpython.repl import embed
+ embed({}, local_vars)
+
+ def bpython(self, local_vars):
+ from bpython import embed
+ embed(local_vars)
+
+ def python(self, local_vars):
+ Console(locals=local_vars).interact()
def shell(self, dbname):
local_vars = {
- 'openerp': odoo
+ 'openerp': odoo,
+ 'odoo': odoo,
}
with odoo.api.Environment.manage():
if dbname:
@@ -61,5 +100,5 @@ class Shell(Command):
def run(self, args):
self.init(args)
- self.shell(odoo.tools.config['db_name'])
+ self.shell(config['db_name'])
return 0
diff --git a/odoo/tools/config.py b/odoo/tools/config.py
index a4cbd9a0439..eddc34b5b78 100644
--- a/odoo/tools/config.py
+++ b/odoo/tools/config.py
@@ -77,7 +77,7 @@ class configmanager(object):
# Not exposed in the configuration file.
self.blacklist_for_save = set([
'publisher_warranty_url', 'load_language', 'root_path',
- 'init', 'save', 'config', 'update', 'stop_after_init', 'dev_mode'
+ 'init', 'save', 'config', 'update', 'stop_after_init', 'dev_mode', 'shell_interface'
])
# dictionary mapping option destination (keys in self.options) to MyOptions.
@@ -236,6 +236,9 @@ class configmanager(object):
group.add_option('--dev', dest='dev_mode', type="string",
help="Enable developer mode. Param: List of options separated by comma. "
"Options : all, [pudb|wdb|ipdb|pdb], reload, qweb, werkzeug, xml")
+ group.add_option('--shell-interface', dest='shell_interface', type="string",
+ help="Specify a preferred REPL to use in shell mode. Supported REPLs are: "
+ "[ipython|ptpython|bpython|python]")
group.add_option("--stop-after-init", action="store_true", dest="stop_after_init", my_default=False,
help="stop the server after its initialization")
group.add_option("--osv-memory-count-limit", dest="osv_memory_count_limit", my_default=False,
@@ -370,7 +373,7 @@ class configmanager(object):
'db_maxconn', 'import_partial', 'addons_path',
'xmlrpc', 'syslog', 'without_demo',
'dbfilter', 'log_level', 'log_db',
- 'log_db_level', 'geoip_database', 'dev_mode'
+ 'log_db_level', 'geoip_database', 'dev_mode', 'shell_interface'
]
for arg in keys:
@@ -389,7 +392,7 @@ class configmanager(object):
# if defined but None take the configfile value
keys = [
'language', 'translate_out', 'translate_in', 'overwrite_existing_translations',
- 'dev_mode', 'smtp_ssl', 'load_language',
+ 'dev_mode', 'shell_interface', 'smtp_ssl', 'load_language',
'stop_after_init', 'logrotate', 'without_demo', 'xmlrpc', 'syslog',
'list_db', 'proxy_mode',
'test_file', 'test_enable', 'test_commit', 'test_report_directory',