From 860949dd7b03739a30e2eddda49a4a9abd3b83b3 2011-10-29 04:07:51 From: MinRK Date: 2011-10-29 04:07:51 Subject: [PATCH] move completer configurables to IPCompleter where they belong * InteractiveShell.readline_omit__names -> IPCompleter.omit__names * InteractiveShell.readline_merge_completions -> IPCompleter.merge_completions add test for IPCompleter.omit__names, which also covers IPCompleter as a configurable. update %config doctest to match, and replace Completer with IPCompleter in TerminalIPythonApp.classes --- diff --git a/IPython/core/completer.py b/IPython/core/completer.py index 91c0ff0..aa3ecec 100644 --- a/IPython/core/completer.py +++ b/IPython/core/completer.py @@ -85,7 +85,7 @@ from IPython.utils import generics from IPython.utils import io from IPython.utils.dir2 import dir2 from IPython.utils.process import arg_split -from IPython.utils.traitlets import CBool +from IPython.utils.traitlets import CBool, Enum #----------------------------------------------------------------------------- # Globals @@ -276,8 +276,9 @@ class Completer(Configurable): but can be unsafe because the code is actually evaluated on TAB. """ ) + - def __init__(self, namespace=None, global_namespace=None, config=None): + def __init__(self, namespace=None, global_namespace=None, config=None, **kwargs): """Create a new completer for the command line. Completer(namespace=ns,global_namespace=ns2) -> completer instance. @@ -311,7 +312,7 @@ class Completer(Configurable): else: self.global_namespace = global_namespace - super(Completer, self).__init__(config=config) + super(Completer, self).__init__(config=config, **kwargs) def complete(self, text, state): """Return the next possible completion for 'text'. @@ -417,10 +418,30 @@ class IPCompleter(Completer): if self.readline: self.readline.set_completer_delims(self.splitter.get_delims()) + + merge_completions = CBool(True, config=True, + help="""Whether to merge completion results into a single list + + If False, only the completion results from the first non-empty + completer will be returned. + """ + ) + omit__names = Enum((0,1,2), default_value=2, config=True, + help="""Instruct the completer to omit private method names + + Specifically, when completing on ``object.``. + + When 2 [default]: all names that start with '_' will be excluded. + + When 1: all 'magic' names (``__foo__``) will be excluded. + + When 0: nothing will be excluded. + """ + ) def __init__(self, shell=None, namespace=None, global_namespace=None, - omit__names=True, alias_table=None, use_readline=True, - config=None): + alias_table=None, use_readline=True, + config=None, **kwargs): """IPCompleter() -> completer Return a completer object suitable for use by the readline library @@ -438,10 +459,6 @@ class IPCompleter(Completer): handle cases (such as IPython embedded inside functions) where both Python scopes are visible. - - The optional omit__names parameter sets the completer to omit the - 'magic' names (__magicname__) for python objects unless the text - to be completed explicitly starts with one or more underscores. - - If alias_table is supplied, it should be a dictionary of aliases to complete. @@ -463,12 +480,10 @@ class IPCompleter(Completer): # _greedy_changed() depends on splitter and readline being defined: Completer.__init__(self, namespace=namespace, global_namespace=global_namespace, - config=config) + config=config, **kwargs) # List where completion matches will be stored self.matches = [] - self.omit__names = omit__names - self.merge_completions = shell.readline_merge_completions self.shell = shell.shell if alias_table is None: alias_table = {} diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index 0c2d662..535eed4 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -322,8 +322,6 @@ class InteractiveShell(SingletonConfigurable, Magic): # The readline stuff will eventually be moved to the terminal subclass # but for now, we can't do that as readline is welded in everywhere. readline_use = CBool(True, config=True) - readline_merge_completions = CBool(True, config=True) - readline_omit__names = Enum((0,1,2), default_value=2, config=True) readline_remove_delims = Unicode('-/~', config=True) # don't use \M- bindings by default, because they # conflict with 8-bit encodings. See gh-58,gh-88 @@ -1856,7 +1854,6 @@ class InteractiveShell(SingletonConfigurable, Magic): self.Completer = IPCompleter(shell=self, namespace=self.user_ns, global_namespace=self.user_global_ns, - omit__names=self.readline_omit__names, alias_table=self.alias_manager.alias_table, use_readline=self.has_readline, config=self.config, diff --git a/IPython/core/magic.py b/IPython/core/magic.py index 3954407..9f891b7 100644 --- a/IPython/core/magic.py +++ b/IPython/core/magic.py @@ -3657,6 +3657,19 @@ Defaulting color scheme to 'NoColor'""" In [2]: %config IPCompleter IPCompleter options ----------------- + IPCompleter.omit__names= + Current: 2 + Choices: (0, 1, 2) + Instruct the completer to omit private method names + Specifically, when completing on ``object.``. + When 2 [default]: all names that start with '_' will be excluded. + When 1: all 'magic' names (``__foo__``) will be excluded. + When 0: nothing will be excluded. + IPCompleter.merge_completions= + Current: True + Whether to merge completion results into a single list + If False, only the completion results from the first non-empty completer + will be returned. IPCompleter.greedy= Current: False Activate greedy completion diff --git a/IPython/core/tests/test_completer.py b/IPython/core/tests/test_completer.py index 371603f..34cdff0 100644 --- a/IPython/core/tests/test_completer.py +++ b/IPython/core/tests/test_completer.py @@ -13,6 +13,7 @@ import unittest import nose.tools as nt # our own packages +from IPython.config.loader import Config from IPython.core import completer from IPython.external.decorators import knownfailureif from IPython.utils.tempdir import TemporaryDirectory @@ -205,3 +206,27 @@ def test_greedy_completions(): _,c = ip.complete('.',line='a[0].') nt.assert_true('a[0].real' in c, "Should have completed on a[0]: %s"%c) +def test_omit__names(): + # also happens to test IPCompleter as a configurable + ip = get_ipython() + ip._hidden_attr = 1 + c = ip.Completer + ip.ex('ip=get_ipython()') + cfg = Config() + cfg.IPCompleter.omit__names = 0 + c.update_config(cfg) + s,matches = c.complete('ip.') + nt.assert_true('ip.__str__' in matches) + nt.assert_true('ip._hidden_attr' in matches) + cfg.IPCompleter.omit__names = 1 + c.update_config(cfg) + s,matches = c.complete('ip.') + nt.assert_false('ip.__str__' in matches) + nt.assert_true('ip._hidden_attr' in matches) + cfg.IPCompleter.omit__names = 2 + c.update_config(cfg) + s,matches = c.complete('ip.') + nt.assert_false('ip.__str__' in matches) + nt.assert_false('ip._hidden_attr' in matches) + del ip._hidden_attr + \ No newline at end of file diff --git a/IPython/frontend/terminal/ipapp.py b/IPython/frontend/terminal/ipapp.py index d42b240..22b5ea4 100755 --- a/IPython/frontend/terminal/ipapp.py +++ b/IPython/frontend/terminal/ipapp.py @@ -35,7 +35,7 @@ from IPython.config.loader import ( from IPython.config.application import boolean_flag, catch_config_error from IPython.core import release from IPython.core import usage -from IPython.core.completer import Completer +from IPython.core.completer import IPCompleter from IPython.core.crashhandler import CrashHandler from IPython.core.formatters import PlainTextFormatter from IPython.core.application import ( @@ -199,7 +199,7 @@ class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp): TerminalInteractiveShell, ProfileDir, PlainTextFormatter, - Completer, + IPCompleter, ] subcommands = Dict(dict(