Skip to content
This repository

%config magic #923

Merged
merged 10 commits into from over 2 years ago

3 participants

Min RK Brian E. Granger Fernando Perez
Min RK
Owner

should close #903

Adds %config magic, which allows %config Foo.bar = 5 configuration of IPython configurables.

The Magic class keeps a list of configurables which will be updated by the change, so any objects that should be accessible to this magic should be appended to shell.configurables. I started with everything I saw as configurable in InteractiveShell.

Usage

Use just %config to see what classes are available, and %config Class to get the trait info for that class.

When setting values via%config Class.trait = value It is evaluated with user_ns in globals, so you can do arbitrary things like:

In [4]: default = 'png'

In [5]: %config InlineBackendConfig.figure_format = raw_input('what figure format should we use? ') or default

Of course, this magic reveals just how much we don't use traits/config properly. Almost everything is attached to the InteractiveShell object, and has an effect exactly once during an init_foo() method, rather than allowing config propagation via _trait_changed() methods.

For instance, IPCompleter has an omit__names attribute, but the configurable is InteractiveShell.readline_omit__names, which is clearly wrong.

We've done a good job with config in new code, but I think existing code needs a pretty hefty pass to get configurables attached to the right objects, and getting logic like %colors into shell._colors_changed.

Min RK
Owner

Moving discussion from #903 to here (PR), pinging @fperez and @ellisonbg to keep conversation updates linked up.

I've renamed InlineBackendConfig -> InlineBackend (with warning on old name, for any of those still lingering on it).

Here's a quick question: Should we switch the inline figure default back to svg from png? PNG is the default, because it's a good deal sharper, and for figure snobs it does look better than SVG. However, it is less capable, in that the SVG+XHTML export will lack figures in the default state (see #735). Since it's easy to change the figure format, maybe we should change the default to the more capable one, and let the nicer-looking format be configurable?

A possible issue would be that the svg dpi is tuned such that svg and png figures are the same size in the QtConsole, but I find that they are not the same in a browser using the notebook, and the png size is more sensible. It is also true that png is just a much more portable and reliable (if not editable) format.

Min RK
Owner

I updated some docs, to cover using the %config magic to configure the inline backend, and moved the completer configurables to the completer class, where they belong.

Brian E. Granger
Owner

@fperez will probably have thoughts on what image format should be default. I am fine moving to png and it does look nicer in many cases. Also, having it as the default will bring png bugs in matplotlib to light more readily.

There may be some browser tuning we can/should do to make the figure sizes of png/svg the same.

Min RK
Owner

@ellisonbg - I should clarify. The default is png, because it looks better. I'm wondering if we should change it to svg because some functionality (xhtml export) is unavailable with the default.

Fernando Perez
Owner
Brian E. Granger
Owner

@minrk: oops, that was a brain typo, I do realize the default in png. I am fine moving to svg given the support in browsers is much better than the qt console.

Fernando Perez
Owner

@minrk, note that I'm getting a failure in the test suite when I merge this onto master:

======================================================================
FAIL: Doctest: IPython.core.magic.Magic.magic_config
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/fperez/usr/lib/python2.6/site-packages/IPython/testing/plugin/ipdoctest.py", line 265, in runTest
    raise self.failureException(self.format_failure(new.getvalue()))
AssertionError: Failed doctest test for IPython.core.magic.Magic.magic_config
  File "/home/fperez/usr/lib/python2.6/site-packages/IPython/core/magic.py", line 3627, in magic_config

----------------------------------------------------------------------
File "/home/fperez/usr/lib/python2.6/site-packages/IPython/core/magic.py", line 3657, in IPython.core.magic.Magic.magic_config
Failed example:
    get_ipython().magic(u"config IPCompleter")
Exception raised:
    Traceback (most recent call last):
      File "/usr/lib/python2.6/doctest.py", line 1253, in __run
        compileflags, 1) in test.globs
      File "<doctest IPython.core.magic.Magic.magic_config[1]>", line 1, in <module>
        get_ipython().magic(u"config IPCompleter")
      File "/home/fperez/usr/lib/python2.6/site-packages/IPython/core/interactiveshell.py", line 1998, in magic
        result = fn(magic_args)
      File "/home/fperez/usr/lib/python2.6/site-packages/IPython/core/magic.py", line 3707, in magic_config
        help = re.sub(r'^\-\-', '', help, flags=re.MULTILINE)
    TypeError: sub() got an unexpected keyword argument 'flags'

>>  raise self.failureException(self.format_failure(<StringIO.StringIO instance at 0x4482cb0>.getvalue()))

Do you see it too? If not, we can try to debug it together on my box... Problem seen on python 2.6, ubuntu 10.10, 64 bit.

Fernando Perez
Owner

ps - I think if you want to pass flags in a 2.6-compatible manner to a regexp, you must compile it and then use the .sub() method of the compiled regexp. In 2.6, the re module doesn't support flags in the methods. The signature for re.sub changed:

2.6:

re.sub(pattern, repl, string[, count])

2.7:

re.sub(pattern, repl, string[, count, flags])
Min RK
Owner

good catch, I didn't realize it had changed. I'll compile&call.

Min RK
Owner

regex is now compiled, should work on 2.6.

Fernando Perez
Owner

Heads-up @minrk: this one popped a conflict after I just merged the read-only branch... Can you give it a quick rebase? I was about to work on it and saw the conflicts...

added some commits
Min RK move useful update_config method to Configurable from Application
This method should be used whenever updating the config of an object.
It is useful for all configurables, not just Applications.
8706608
Min RK allow using instance values in place of defaults in Configurable.clas…
…s_get_help
66f74cc
Min RK add %config magic for configuring IPython 63ad149
Min RK filter %config class list to exclude classes with no configurable traits 8837523
Min RK Rename InlineBackendConfig -> InlineBackend
include deprecation warning on old name
74b5624
Min RK DisplayFormatter.formatters should not be configurable
it is a dict of instances, which are not allowed in config
f960771
Min RK add reference to `%config InlineBackend` in %pylab docstring
also cleaned up %config and %pylab docstrings to be a little more sphinx-autogen friendly.
7e64be7
Min RK update qtconsole doc with discussion of InlineBackend config 859e6ae
Min RK 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
860949d
Min RK compile sub expr in %config for 2.6 compatibility 1cec181
Min RK
Owner

rebased - tiny conflict with PR #921.

Fernando Perez
Owner

Looks good, ran lots of tests on 2.6 and 2.7, via screen and normal logins. After some initial weird glitching, that went away with a pyc cleanout, all looks good now so I think it's good to merge.

I'm going to leave the image default discussion to happen separately so we don't hold this PR forever, made #944 for that.

Merging now, thanks for the great work! This wil be very useful.

Final comment: adding mention of %config to the main configuration section in the docs is probably a good idea. Since that would be a docs-only patch, just go ahead and commit it any time if you get a chance (and if you can't do it now, let me know and I can take a crack at it later). But I'll merge the code now.

Fernando Perez fperez merged commit b725362 into from
Fernando Perez fperez closed this
Fernando Perez fperez referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 10 unique commits by 1 author.

Oct 28, 2011
Min RK move useful update_config method to Configurable from Application
This method should be used whenever updating the config of an object.
It is useful for all configurables, not just Applications.
8706608
Min RK allow using instance values in place of defaults in Configurable.clas…
…s_get_help
66f74cc
Min RK add %config magic for configuring IPython 63ad149
Min RK filter %config class list to exclude classes with no configurable traits 8837523
Min RK Rename InlineBackendConfig -> InlineBackend
include deprecation warning on old name
74b5624
Min RK DisplayFormatter.formatters should not be configurable
it is a dict of instances, which are not allowed in config
f960771
Min RK add reference to `%config InlineBackend` in %pylab docstring
also cleaned up %config and %pylab docstrings to be a little more sphinx-autogen friendly.
7e64be7
Min RK update qtconsole doc with discussion of InlineBackend config 859e6ae
Min RK 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
860949d
Min RK compile sub expr in %config for 2.6 compatibility 1cec181
This page is out of date. Refresh to see the latest.
55  IPython/config/configurable.py
@@ -138,35 +138,58 @@ def _config_changed(self, name, old, new):
138 138
                         # shared by all instances, effectively making it a class attribute.
139 139
                         setattr(self, k, deepcopy(config_value))
140 140
 
  141
+    def update_config(self, config):
  142
+        """Fire the traits events when the config is updated."""
  143
+        # Save a copy of the current config.
  144
+        newconfig = deepcopy(self.config)
  145
+        # Merge the new config into the current one.
  146
+        newconfig._merge(config)
  147
+        # Save the combined config as self.config, which triggers the traits
  148
+        # events.
  149
+        self.config = newconfig
  150
+
141 151
     @classmethod
142  
-    def class_get_help(cls):
143  
-        """Get the help string for this class in ReST format."""
  152
+    def class_get_help(cls, inst=None):
  153
+        """Get the help string for this class in ReST format.
  154
+        
  155
+        If `inst` is given, it's current trait values will be used in place of
  156
+        class defaults.
  157
+        """
  158
+        assert inst is None or isinstance(inst, cls)
144 159
         cls_traits = cls.class_traits(config=True)
145 160
         final_help = []
146 161
         final_help.append(u'%s options' % cls.__name__)
147 162
         final_help.append(len(final_help[0])*u'-')
148 163
         for k,v in cls.class_traits(config=True).iteritems():
149  
-            help = cls.class_get_trait_help(v)
  164
+            help = cls.class_get_trait_help(v, inst)
150 165
             final_help.append(help)
151 166
         return '\n'.join(final_help)
152 167
 
153 168
     @classmethod
154  
-    def class_get_trait_help(cls, trait):
155  
-        """Get the help string for a single trait."""
  169
+    def class_get_trait_help(cls, trait, inst=None):
  170
+        """Get the help string for a single trait.
  171
+        
  172
+        If `inst` is given, it's current trait values will be used in place of
  173
+        the class default.
  174
+        """
  175
+        assert inst is None or isinstance(inst, cls)
156 176
         lines = []
157 177
         header = "--%s.%s=<%s>" % (cls.__name__, trait.name, trait.__class__.__name__)
158 178
         lines.append(header)
159  
-        try:
160  
-            dvr = repr(trait.get_default_value())
161  
-        except Exception:
162  
-            dvr = None # ignore defaults we can't construct
163  
-        if dvr is not None:
164  
-            if len(dvr) > 64:
165  
-                dvr = dvr[:61]+'...'
166  
-            lines.append(indent('Default: %s'%dvr, 4))
  179
+        if inst is not None:
  180
+            lines.append(indent('Current: %r' % getattr(inst, trait.name), 4))
  181
+        else:
  182
+            try:
  183
+                dvr = repr(trait.get_default_value())
  184
+            except Exception:
  185
+                dvr = None # ignore defaults we can't construct
  186
+            if dvr is not None:
  187
+                if len(dvr) > 64:
  188
+                    dvr = dvr[:61]+'...'
  189
+                lines.append(indent('Default: %s' % dvr, 4))
167 190
         if 'Enum' in trait.__class__.__name__:
168 191
             # include Enum choices
169  
-            lines.append(indent('Choices: %r'%(trait.values,)))
  192
+            lines.append(indent('Choices: %r' % (trait.values,)))
170 193
 
171 194
         help = trait.get_metadata('help')
172 195
         if help is not None:
@@ -175,9 +198,9 @@ def class_get_trait_help(cls, trait):
175 198
         return '\n'.join(lines)
176 199
 
177 200
     @classmethod
178  
-    def class_print_help(cls):
  201
+    def class_print_help(cls, inst=None):
179 202
         """Get the help string for a single trait and print it."""
180  
-        print cls.class_get_help()
  203
+        print cls.class_get_help(inst)
181 204
 
182 205
     @classmethod
183 206
     def class_config_section(cls):
13  IPython/config/tests/test_configurable.py
@@ -53,6 +53,15 @@ class MyConfigurable(Configurable):
53 53
     Default: 1.0
54 54
     The integer b."""
55 55
 
  56
+mc_help_inst=u"""MyConfigurable options
  57
+----------------------
  58
+--MyConfigurable.a=<Int>
  59
+    Current: 5
  60
+    The integer a.
  61
+--MyConfigurable.b=<Float>
  62
+    Current: 4.0
  63
+    The integer b."""
  64
+
56 65
 class Foo(Configurable):
57 66
     a = Int(0, config=True, help="The integer a.")
58 67
     b = Unicode('nope', config=True)
@@ -139,6 +148,10 @@ def test_override2(self):
139 148
     def test_help(self):
140 149
         self.assertEquals(MyConfigurable.class_get_help(), mc_help)
141 150
 
  151
+    def test_help_inst(self):
  152
+        inst = MyConfigurable(a=5, b=4)
  153
+        self.assertEquals(MyConfigurable.class_get_help(inst), mc_help_inst)
  154
+
142 155
 
143 156
 class TestSingletonConfigurable(TestCase):
144 157
 
39  IPython/core/completer.py
@@ -85,7 +85,7 @@
85 85
 from IPython.utils import io
86 86
 from IPython.utils.dir2 import dir2
87 87
 from IPython.utils.process import arg_split
88  
-from IPython.utils.traitlets import CBool
  88
+from IPython.utils.traitlets import CBool, Enum
89 89
 
90 90
 #-----------------------------------------------------------------------------
91 91
 # Globals
@@ -276,8 +276,9 @@ class Completer(Configurable):
276 276
         but can be unsafe because the code is actually evaluated on TAB.
277 277
         """
278 278
     )
  279
+    
279 280
 
280  
-    def __init__(self, namespace=None, global_namespace=None, config=None):
  281
+    def __init__(self, namespace=None, global_namespace=None, config=None, **kwargs):
281 282
         """Create a new completer for the command line.
282 283
 
283 284
         Completer(namespace=ns,global_namespace=ns2) -> completer instance.
@@ -311,7 +312,7 @@ def __init__(self, namespace=None, global_namespace=None, config=None):
311 312
         else:
312 313
             self.global_namespace = global_namespace
313 314
 
314  
-        super(Completer, self).__init__(config=config)
  315
+        super(Completer, self).__init__(config=config, **kwargs)
315 316
 
316 317
     def complete(self, text, state):
317 318
         """Return the next possible completion for 'text'.
@@ -417,10 +418,30 @@ def _greedy_changed(self, name, old, new):
417 418
 
418 419
         if self.readline:
419 420
             self.readline.set_completer_delims(self.splitter.get_delims())
  421
+    
  422
+    merge_completions = CBool(True, config=True,
  423
+        help="""Whether to merge completion results into a single list
  424
+        
  425
+        If False, only the completion results from the first non-empty
  426
+        completer will be returned.
  427
+        """
  428
+    )
  429
+    omit__names = Enum((0,1,2), default_value=2, config=True,
  430
+        help="""Instruct the completer to omit private method names
  431
+        
  432
+        Specifically, when completing on ``object.<tab>``.
  433
+        
  434
+        When 2 [default]: all names that start with '_' will be excluded.
  435
+        
  436
+        When 1: all 'magic' names (``__foo__``) will be excluded.
  437
+        
  438
+        When 0: nothing will be excluded.
  439
+        """
  440
+    )
420 441
 
421 442
     def __init__(self, shell=None, namespace=None, global_namespace=None,
422  
-                 omit__names=True, alias_table=None, use_readline=True,
423  
-                 config=None):
  443
+                 alias_table=None, use_readline=True,
  444
+                 config=None, **kwargs):
424 445
         """IPCompleter() -> completer
425 446
 
426 447
         Return a completer object suitable for use by the readline library
@@ -438,10 +459,6 @@ def __init__(self, shell=None, namespace=None, global_namespace=None,
438 459
         handle cases (such as IPython embedded inside functions) where
439 460
         both Python scopes are visible.
440 461
 
441  
-        - The optional omit__names parameter sets the completer to omit the
442  
-        'magic' names (__magicname__) for python objects unless the text
443  
-        to be completed explicitly starts with one or more underscores.
444  
-
445 462
         - If alias_table is supplied, it should be a dictionary of aliases
446 463
         to complete.
447 464
 
@@ -463,12 +480,10 @@ def __init__(self, shell=None, namespace=None, global_namespace=None,
463 480
 
464 481
         # _greedy_changed() depends on splitter and readline being defined:
465 482
         Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
466  
-                            config=config)
  483
+                            config=config, **kwargs)
467 484
 
468 485
         # List where completion matches will be stored
469 486
         self.matches = []
470  
-        self.omit__names = omit__names
471  
-        self.merge_completions = shell.readline_merge_completions
472 487
         self.shell = shell.shell
473 488
         if alias_table is None:
474 489
             alias_table = {}
2  IPython/core/formatters.py
@@ -44,7 +44,7 @@ class DisplayFormatter(Configurable):
44 44
 
45 45
     # A dict of formatter whose keys are format types (MIME types) and whose
46 46
     # values are subclasses of BaseFormatter.
47  
-    formatters = Dict(config=True)
  47
+    formatters = Dict()
48 48
     def _formatters_default(self):
49 49
         """Activate the default formatters."""
50 50
         formatter_classes = [
15  IPython/core/interactiveshell.py
@@ -322,8 +322,6 @@ def _exiter_default(self):
322 322
     # The readline stuff will eventually be moved to the terminal subclass
323 323
     # but for now, we can't do that as readline is welded in everywhere.
324 324
     readline_use = CBool(True, config=True)
325  
-    readline_merge_completions = CBool(True, config=True)
326  
-    readline_omit__names = Enum((0,1,2), default_value=2, config=True)
327 325
     readline_remove_delims = Unicode('-/~', config=True)
328 326
     # don't use \M- bindings by default, because they
329 327
     # conflict with 8-bit encodings. See gh-58,gh-88
@@ -379,6 +377,7 @@ def __init__(self, config=None, ipython_dir=None, profile_dir=None,
379 377
         # This is where traits with a config_key argument are updated
380 378
         # from the values on config.
381 379
         super(InteractiveShell, self).__init__(config=config)
  380
+        self.configurables = [self]
382 381
 
383 382
         # These are relatively independent and stateless
384 383
         self.init_ipython_dir(ipython_dir)
@@ -602,9 +601,11 @@ def init_prompts(self):
602 601
 
603 602
     def init_display_formatter(self):
604 603
         self.display_formatter = DisplayFormatter(config=self.config)
  604
+        self.configurables.append(self.display_formatter)
605 605
 
606 606
     def init_display_pub(self):
607 607
         self.display_pub = self.display_pub_class(config=self.config)
  608
+        self.configurables.append(self.display_pub)
608 609
 
609 610
     def init_displayhook(self):
610 611
         # Initialize displayhook, set in/out prompts and printing system
@@ -620,6 +621,7 @@ def init_displayhook(self):
620 621
             ps_out = self.prompt_out,
621 622
             pad_left = self.prompts_pad_left
622 623
         )
  624
+        self.configurables.append(self.displayhook)
623 625
         # This is a context manager that installs/revmoes the displayhook at
624 626
         # the appropriate time.
625 627
         self.display_trap = DisplayTrap(hook=self.displayhook)
@@ -1435,6 +1437,7 @@ def object_inspect(self, oname):
1435 1437
     def init_history(self):
1436 1438
         """Sets up the command history, and starts regular autosaves."""
1437 1439
         self.history_manager = HistoryManager(shell=self, config=self.config)
  1440
+        self.configurables.append(self.history_manager)
1438 1441
 
1439 1442
     #-------------------------------------------------------------------------
1440 1443
     # Things related to exception handling and tracebacks (not debugging)
@@ -1851,11 +1854,11 @@ def init_completer(self):
1851 1854
         self.Completer = IPCompleter(shell=self,
1852 1855
                                      namespace=self.user_ns,
1853 1856
                                      global_namespace=self.user_global_ns,
1854  
-                                     omit__names=self.readline_omit__names,
1855 1857
                                      alias_table=self.alias_manager.alias_table,
1856 1858
                                      use_readline=self.has_readline,
1857 1859
                                      config=self.config,
1858 1860
                                      )
  1861
+        self.configurables.append(self.Completer)
1859 1862
 
1860 1863
         # Add custom completers to the basic ones built into IPCompleter
1861 1864
         sdisp = self.strdispatchers.get('complete_command', StrDispatch())
@@ -2112,6 +2115,7 @@ def getoutput(self, cmd, split=True):
2112 2115
 
2113 2116
     def init_alias(self):
2114 2117
         self.alias_manager = AliasManager(shell=self, config=self.config)
  2118
+        self.configurables.append(self.alias_manager)
2115 2119
         self.ns_table['alias'] = self.alias_manager.alias_table,
2116 2120
 
2117 2121
     #-------------------------------------------------------------------------
@@ -2120,9 +2124,12 @@ def init_alias(self):
2120 2124
 
2121 2125
     def init_extension_manager(self):
2122 2126
         self.extension_manager = ExtensionManager(shell=self, config=self.config)
  2127
+        self.configurables.append(self.extension_manager)
2123 2128
 
2124 2129
     def init_plugin_manager(self):
2125 2130
         self.plugin_manager = PluginManager(config=self.config)
  2131
+        self.configurables.append(self.plugin_manager)
  2132
+        
2126 2133
 
2127 2134
     #-------------------------------------------------------------------------
2128 2135
     # Things related to payloads
@@ -2130,6 +2137,7 @@ def init_plugin_manager(self):
2130 2137
 
2131 2138
     def init_payload(self):
2132 2139
         self.payload_manager = PayloadManager(config=self.config)
  2140
+        self.configurables.append(self.payload_manager)
2133 2141
 
2134 2142
     #-------------------------------------------------------------------------
2135 2143
     # Things related to the prefilter
@@ -2137,6 +2145,7 @@ def init_payload(self):
2137 2145
 
2138 2146
     def init_prefilter(self):
2139 2147
         self.prefilter_manager = PrefilterManager(shell=self, config=self.config)
  2148
+        self.configurables.append(self.prefilter_manager)
2140 2149
         # Ultimately this will be refactored in the new interpreter code, but
2141 2150
         # for now, we should expose the main prefilter method (there's legacy
2142 2151
         # code out there that may rely on this).
136  IPython/core/magic.py
@@ -123,6 +123,8 @@ class Magic:
123 123
     auto_status = ['Automagic is OFF, % prefix IS needed for magic functions.',
124 124
                    'Automagic is ON, % prefix NOT needed for magic functions.']
125 125
 
  126
+
  127
+    configurables = None
126 128
     #......................................................................
127 129
     # some utility functions
128 130
 
@@ -132,6 +134,8 @@ def __init__(self,shell):
132 134
         if profile is None:
133 135
             self.magic_prun = self.profile_missing_notice
134 136
         self.shell = shell
  137
+        if self.configurables is None:
  138
+            self.configurables = []
135 139
 
136 140
         # namespace for holding state we may need
137 141
         self._magic_state = Bunch()
@@ -3451,6 +3455,17 @@ def magic_pylab(self, s):
3451 3455
         It will import at the top level numpy as np, pyplot as plt, matplotlib,
3452 3456
         pylab and mlab, as well as all names from numpy and pylab.
3453 3457
 
  3458
+        If you are using the inline matplotlib backend for embedded figures,
  3459
+        you can adjust its behavior via the %config magic::
  3460
+
  3461
+            # enable SVG figures, necessary for SVG+XHTML export in the qtconsole
  3462
+            In [1]: %config InlineBackend.figure_format = 'svg'
  3463
+            
  3464
+            # change the behavior of closing all figures at the end of each
  3465
+            # execution (cell), or allowing reuse of active figures across
  3466
+            # cells:
  3467
+            In [2]: %config InlineBackend.close_figures = False
  3468
+
3454 3469
         Parameters
3455 3470
         ----------
3456 3471
         guiname : optional
@@ -3461,19 +3476,21 @@ def magic_pylab(self, s):
3461 3476
 
3462 3477
         Examples
3463 3478
         --------
3464  
-        In this case, where the MPL default is TkAgg:
3465  
-        In [2]: %pylab
  3479
+        In this case, where the MPL default is TkAgg::
  3480
+
  3481
+            In [2]: %pylab
3466 3482
 
3467  
-        Welcome to pylab, a matplotlib-based Python environment.
3468  
-        Backend in use: TkAgg
3469  
-        For more information, type 'help(pylab)'.
  3483
+            Welcome to pylab, a matplotlib-based Python environment.
  3484
+            Backend in use: TkAgg
  3485
+            For more information, type 'help(pylab)'.
3470 3486
 
3471  
-        But you can explicitly request a different backend:
3472  
-        In [3]: %pylab qt
  3487
+        But you can explicitly request a different backend::
3473 3488
 
3474  
-        Welcome to pylab, a matplotlib-based Python environment.
3475  
-        Backend in use: Qt4Agg
3476  
-        For more information, type 'help(pylab)'.
  3489
+            In [3]: %pylab qt
  3490
+
  3491
+            Welcome to pylab, a matplotlib-based Python environment.
  3492
+            Backend in use: Qt4Agg
  3493
+            For more information, type 'help(pylab)'.
3477 3494
         """
3478 3495
 
3479 3496
         if Application.initialized():
@@ -3607,4 +3624,103 @@ def magic_notebook(self, s):
3607 3624
             with open(new_fname, 'w') as f:
3608 3625
                 current.write(nb, f, new_format)
3609 3626
 
  3627
+    def magic_config(self, s):
  3628
+        """configure IPython
  3629
+        
  3630
+            %config Class[.trait=value]
  3631
+        
  3632
+        This magic exposes most of the IPython config system. Any
  3633
+        Configurable class should be able to be configured with the simple
  3634
+        line::
  3635
+        
  3636
+            %config Class.trait=value
  3637
+        
  3638
+        Where `value` will be resolved in the user's namespace, if it is an
  3639
+        expression or variable name.
  3640
+        
  3641
+        Examples
  3642
+        --------
  3643
+        
  3644
+        To see what classes are availabe for config, pass no arguments::
  3645
+
  3646
+            In [1]: %config
  3647
+            Available objects for config:
  3648
+                TerminalInteractiveShell
  3649
+                HistoryManager
  3650
+                PrefilterManager
  3651
+                AliasManager
  3652
+                IPCompleter
  3653
+                DisplayFormatter
  3654
+
  3655
+        To view what is configurable on a given class, just pass the class name::
  3656
+
  3657
+            In [2]: %config IPCompleter
  3658
+            IPCompleter options
  3659
+            -----------------
  3660
+            IPCompleter.omit__names=<Enum>
  3661
+                Current: 2
  3662
+                Choices: (0, 1, 2)
  3663
+                Instruct the completer to omit private method names
  3664
+                Specifically, when completing on ``object.<tab>``.
  3665
+                When 2 [default]: all names that start with '_' will be excluded.
  3666
+                When 1: all 'magic' names (``__foo__``) will be excluded.
  3667
+                When 0: nothing will be excluded.
  3668
+            IPCompleter.merge_completions=<CBool>
  3669
+                Current: True
  3670
+                Whether to merge completion results into a single list
  3671
+                If False, only the completion results from the first non-empty completer
  3672
+                will be returned.
  3673
+            IPCompleter.greedy=<CBool>
  3674
+                Current: False
  3675
+                Activate greedy completion
  3676
+                This will enable completion on elements of lists, results of function calls,
  3677
+                etc., but can be unsafe because the code is actually evaluated on TAB.
  3678
+
  3679
+        but the real use is in setting values::
  3680
+
  3681
+            In [3]: %config IPCompleter.greedy = True
  3682
+
  3683
+        and these values are read from the user_ns if they are variables::
  3684
+
  3685
+            In [4]: feeling_greedy=False
  3686
+
  3687
+            In [5]: %config IPCompleter.greedy = feeling_greedy
  3688
+
  3689
+        """
  3690
+        from IPython.config.loader import Config
  3691
+        # get list of class names for configurables that have someting to configure:
  3692
+        classnames = [ c.__class__.__name__ for c in self.configurables if c.__class__.class_traits(config=True) ]
  3693
+        line = s.strip()
  3694
+        if not line:
  3695
+            # print available configurable names
  3696
+            print "Available objects for config:"
  3697
+            for name in classnames:
  3698
+                print "    ", name
  3699
+            return
  3700
+        elif line in classnames:
  3701
+            # `%config TerminalInteractiveShell` will print trait info for
  3702
+            # TerminalInteractiveShell
  3703
+            c = self.configurables[classnames.index(line)]
  3704
+            cls = c.__class__
  3705
+            help = cls.class_get_help(c)
  3706
+            # strip leading '--' from cl-args:
  3707
+            help = re.sub(re.compile(r'^--', re.MULTILINE), '', help)
  3708
+            print help
  3709
+            return
  3710
+        elif '=' not in line:
  3711
+            raise UsageError("Invalid config statement: %r, should be Class.trait = value" % line)
  3712
+            
  3713
+        
  3714
+        # otherwise, assume we are setting configurables.
  3715
+        # leave quotes on args when splitting, because we want
  3716
+        # unquoted args to eval in user_ns
  3717
+        cfg = Config()
  3718
+        exec "cfg."+line in locals(), self.user_ns
  3719
+        
  3720
+        for configurable in self.configurables:
  3721
+            try:
  3722
+                configurable.update_config(cfg)
  3723
+            except Exception as e:
  3724
+                error(e)
  3725
+
3610 3726
 # end Magic
25  IPython/core/tests/test_completer.py
@@ -13,6 +13,7 @@
13 13
 import nose.tools as nt
14 14
 
15 15
 # our own packages
  16
+from IPython.config.loader import Config
16 17
 from IPython.core import completer
17 18
 from IPython.external.decorators import knownfailureif
18 19
 from IPython.utils.tempdir import TemporaryDirectory
@@ -205,3 +206,27 @@ def test_greedy_completions():
205 206
     _,c = ip.complete('.',line='a[0].')
206 207
     nt.assert_true('a[0].real' in c, "Should have completed on a[0]: %s"%c)
207 208
 
  209
+def test_omit__names():
  210
+    # also happens to test IPCompleter as a configurable
  211
+    ip = get_ipython()
  212
+    ip._hidden_attr = 1
  213
+    c = ip.Completer
  214
+    ip.ex('ip=get_ipython()')
  215
+    cfg = Config()
  216
+    cfg.IPCompleter.omit__names = 0
  217
+    c.update_config(cfg)
  218
+    s,matches = c.complete('ip.')
  219
+    nt.assert_true('ip.__str__' in matches)
  220
+    nt.assert_true('ip._hidden_attr' in matches)
  221
+    cfg.IPCompleter.omit__names = 1
  222
+    c.update_config(cfg)
  223
+    s,matches = c.complete('ip.')
  224
+    nt.assert_false('ip.__str__' in matches)
  225
+    nt.assert_true('ip._hidden_attr' in matches)
  226
+    cfg.IPCompleter.omit__names = 2
  227
+    c.update_config(cfg)
  228
+    s,matches = c.complete('ip.')
  229
+    nt.assert_false('ip.__str__' in matches)
  230
+    nt.assert_false('ip._hidden_attr' in matches)
  231
+    del ip._hidden_attr
  232
+    
4  IPython/frontend/terminal/ipapp.py
@@ -35,7 +35,7 @@
35 35
 from IPython.config.application import boolean_flag, catch_config_error
36 36
 from IPython.core import release
37 37
 from IPython.core import usage
38  
-from IPython.core.completer import Completer
  38
+from IPython.core.completer import IPCompleter
39 39
 from IPython.core.crashhandler import CrashHandler
40 40
 from IPython.core.formatters import PlainTextFormatter
41 41
 from IPython.core.application import (
@@ -199,7 +199,7 @@ def _classes_default(self):
199 199
             TerminalInteractiveShell,
200 200
             ProfileDir,
201 201
             PlainTextFormatter,
202  
-            Completer,
  202
+            IPCompleter,
203 203
         ]
204 204
 
205 205
     subcommands = Dict(dict(
6  IPython/lib/pylabtools.py
@@ -253,10 +253,12 @@ def import_pylab(user_ns, backend, import_all=True, shell=None):
253 253
         # function that will pick up the results for display.  This can only be
254 254
         # done with access to the real shell object.
255 255
         #
256  
-        from IPython.zmq.pylab.backend_inline import InlineBackendConfig
  256
+        from IPython.zmq.pylab.backend_inline import InlineBackend
257 257
 
258  
-        cfg = InlineBackendConfig.instance(config=shell.config)
  258
+        cfg = InlineBackend.instance(config=shell.config)
259 259
         cfg.shell = shell
  260
+        if cfg not in shell.configurables:
  261
+            shell.configurables.append(cfg)
260 262
 
261 263
         if backend == backends['inline']:
262 264
             from IPython.zmq.pylab.backend_inline import flush_figures
19  IPython/zmq/pylab/backend_inline.py
@@ -18,13 +18,24 @@
18 18
 from IPython.core.displaypub import publish_display_data
19 19
 from IPython.lib.pylabtools import print_figure, select_figure_format
20 20
 from IPython.utils.traitlets import Dict, Instance, CaselessStrEnum, CBool
  21
+from IPython.utils.warn import warn
  22
+
21 23
 #-----------------------------------------------------------------------------
22 24
 # Configurable for inline backend options
23 25
 #-----------------------------------------------------------------------------
24  
-
  26
+# inherit from InlineBackendConfig for deprecation purposes
25 27
 class InlineBackendConfig(SingletonConfigurable):
  28
+    pass
  29
+
  30
+class InlineBackend(InlineBackendConfig):
26 31
     """An object to store configuration of the inline backend."""
27 32
 
  33
+    def _config_changed(self, name, old, new):
  34
+        # warn on change of renamed config section
  35
+        if new.InlineBackendConfig != old.InlineBackendConfig:
  36
+            warn("InlineBackendConfig has been renamed to InlineBackend")
  37
+        super(InlineBackend, self)._config_changed(name, old, new)
  38
+
28 39
     # The typical default figure size is too large for inline use,
29 40
     # so we shrink the figure size to 6x4, and tweak fonts to
30 41
     # make that fit.  This is configurable via Global.pylab_inline_rc,
@@ -83,7 +94,7 @@ def show(close=None):
83 94
       removed from the internal list of figures.
84 95
     """
85 96
     if close is None:
86  
-        close = InlineBackendConfig.instance().close_figures
  97
+        close = InlineBackend.instance().close_figures
87 98
     for figure_manager in Gcf.get_all_fig_managers():
88 99
         send_figure(figure_manager.canvas.figure)
89 100
     if close:
@@ -129,7 +140,7 @@ def flush_figures():
129 140
     if not show._draw_called:
130 141
         return
131 142
     
132  
-    if InlineBackendConfig.instance().close_figures:
  143
+    if InlineBackend.instance().close_figures:
133 144
         # ignore the tracking, just draw and close all figures
134 145
         return show(True)
135 146
     
@@ -149,7 +160,7 @@ def send_figure(fig):
149 160
     # big blank spaces in the qt console
150 161
     if not fig.axes:
151 162
         return
152  
-    fmt = InlineBackendConfig.instance().figure_format
  163
+    fmt = InlineBackend.instance().figure_format
153 164
     data = print_figure(fig, fmt)
154 165
     mimetypes = { 'png' : 'image/png', 'svg' : 'image/svg+xml' }
155 166
     mime = mimetypes[fmt]
67  docs/source/interactive/qtconsole.txt
@@ -120,6 +120,56 @@ calling :func:`display`, you can specify ``--pylab=inline`` when you start the
120 120
 console, and each time you make a plot, it will show up in your document, as if
121 121
 you had called :func:`display(fig)`.
122 122
 
  123
+The inline backend can use either SVG or PNG figures (PNG being the default).
  124
+To switch between them, set the ``InlineBackend.figure_format`` configurable
  125
+in a config file, or via the ``%config`` magic:
  126
+
  127
+.. sourcecode:: ipython
  128
+
  129
+    In [10]: %config InlineBackend.figure_format = 'svg'
  130
+
  131
+.. note::
  132
+
  133
+    Changing the inline figure format also affects calls to :func:`display` above,
  134
+    even if you are not using the inline backend for all figures.
  135
+
  136
+By default, IPython closes all figures at the completion of each execution. This means you
  137
+don't have to manually close figures, which is less convenient when figures aren't attached
  138
+to windows with an obvious close button.  It also means that the first matplotlib call in
  139
+each cell will always create a new figure:
  140
+
  141
+.. sourcecode:: ipython
  142
+
  143
+    In [11]: plot(range(100))
  144
+    <single-line plot>
  145
+    
  146
+    In [12]: plot([1,3,2])
  147
+    <another single-line plot>
  148
+
  149
+
  150
+However, it does prevent the list of active figures surviving from one input cell to the
  151
+next, so if you want to continue working with a figure, you must hold on to a reference to
  152
+it:
  153
+
  154
+.. sourcecode:: ipython
  155
+
  156
+    In [11]: fig = gcf()
  157
+       ....: fig.plot(rand(100))
  158
+    <plot>
  159
+    In [12]: fig.title('Random Title')
  160
+    <redraw plot with title>
  161
+
  162
+This behavior is controlled by the :attr:`InlineBackend.close_figures` configurable, and
  163
+if you set it to False, via %config or config file, then IPython will *not* close figures,
  164
+and tools like :func:`gcf`, :func:`gca`, :func:`getfigs` will behave the same as they
  165
+do with other backends.  You will, however, have to manually close figures:
  166
+
  167
+.. sourcecode:: ipython
  168
+
  169
+    # close all active figures:
  170
+    In [13]: [ fig.close() for fig in getfigs() ]
  171
+
  172
+
123 173
 
124 174
 .. _saving:
125 175
 
@@ -132,6 +182,22 @@ will be PNG in HTML, or inlined as SVG in XHTML. PNG images have the option to
132 182
 be either in an external folder, as in many browsers' "Webpage, Complete"
133 183
 option, or inlined as well, for a larger, but more portable file.
134 184
 
  185
+.. note::
  186
+
  187
+    Export to SVG+XHTML requires that you are using SVG figures, which is *not*
  188
+    the default.  To switch the inline figure format to use SVG during an active
  189
+    session, do:
  190
+    
  191
+    .. sourcecode:: ipython
  192
+    
  193
+        In [10]: %config InlineBackend.figure_format = 'svg'
  194
+    
  195
+    Or, you can add the same line (c.Inline... instead of %config Inline...) to
  196
+    your config files.
  197
+    
  198
+    This will only affect figures plotted after making this call
  199
+
  200
+
135 201
 The widget also exposes the ability to print directly, via the default print
136 202
 shortcut or context menu.
137 203
 
@@ -146,6 +212,7 @@ See these examples of :download:`png/html<figs/jn.html>` and
146 212
 :download:`svg/xhtml <figs/jn.xhtml>` output. Note that syntax highlighting
147 213
 does not survive export. This is a known issue, and is being investigated.
148 214
 
  215
+
149 216
 Colors and Highlighting
150 217
 =======================
151 218
 
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.