1 """Implementation of configuration-related magic functions. 2 """ 3 #----------------------------------------------------------------------------- 4 # Copyright (c) 2012 The IPython Development Team. 5 # 6 # Distributed under the terms of the Modified BSD License. 7 # 8 # The full license is in the file COPYING.txt, distributed with this software. 9 #----------------------------------------------------------------------------- 10 11 #----------------------------------------------------------------------------- 12 # Imports 13 #----------------------------------------------------------------------------- 14 15 # Stdlib 16 import re 17 18 # Our own packages 19 from IPython.core.error import UsageError 20 from IPython.core.magic import Magics, magics_class, line_magic 21 from logging import error 22 23 #----------------------------------------------------------------------------- 24 # Magic implementation classes 25 #----------------------------------------------------------------------------- 26 27 reg = re.compile(r'^\w+\.\w+$') 28 @magics_class 29 class ConfigMagics(Magics): 30 31 def __init__(self, shell): 32 super(ConfigMagics, self).__init__(shell) 33 self.configurables = [] 34 35 @line_magic 36 def config(self, s): 37 """configure IPython 38 39 %config Class[.trait=value] 40 41 This magic exposes most of the IPython config system. Any 42 Configurable class should be able to be configured with the simple 43 line:: 44 45 %config Class.trait=value 46 47 Where `value` will be resolved in the user's namespace, if it is an 48 expression or variable name. 49 50 Examples 51 -------- 52 53 To see what classes are available for config, pass no arguments:: 54 55 In [1]: %config 56 Available objects for config: 57 AliasManager 58 DisplayFormatter 59 HistoryManager 60 IPCompleter 61 LoggingMagics 62 MagicsManager 63 OSMagics 64 PrefilterManager 65 ScriptMagics 66 TerminalInteractiveShell 67 68 To view what is configurable on a given class, just pass the class 69 name:: 70 71 In [2]: %config LoggingMagics 72 LoggingMagics(Magics) options 73 --------------------------- 74 LoggingMagics.quiet=<Bool> 75 Suppress output of log state when logging is enabled 76 Current: False 77 78 but the real use is in setting values:: 79 80 In [3]: %config LoggingMagics.quiet = True 81 82 and these values are read from the user_ns if they are variables:: 83 84 In [4]: feeling_quiet=False 85 86 In [5]: %config LoggingMagics.quiet = feeling_quiet 87 88 """ 89 from traitlets.config.loader import Config 90 # some IPython objects are Configurable, but do not yet have 91 # any configurable traits. Exclude them from the effects of 92 # this magic, as their presence is just noise: 93 configurables = sorted(set([ c for c in self.shell.configurables 94 if c.__class__.class_traits(config=True) 95 ]), key=lambda x: x.__class__.__name__) 96 classnames = [ c.__class__.__name__ for c in configurables ] 97 98 line = s.strip() 99 if not line: 100 # print available configurable names 101 print("Available objects for config:") 102 for name in classnames: 103 print(" ", name) 104 return 105 elif line in classnames: 106 # `%config TerminalInteractiveShell` will print trait info for 107 # TerminalInteractiveShell 108 c = configurables[classnames.index(line)] 109 cls = c.__class__ 110 help = cls.class_get_help(c) 111 # strip leading '--' from cl-args: 112 help = re.sub(re.compile(r'^--', re.MULTILINE), '', help) 113 print(help) 114 return 115 elif reg.match(line): 116 cls, attr = line.split('.') 117 return getattr(configurables[classnames.index(cls)],attr) 118 elif '=' not in line: 119 msg = "Invalid config statement: %r, "\ 120 "should be `Class.trait = value`." 121 122 ll = line.lower() 123 for classname in classnames: 124 if ll == classname.lower(): 125 msg = msg + '\nDid you mean %s (note the case)?' % classname 126 break 127 128 raise UsageError( msg % line) 129 130 # otherwise, assume we are setting configurables. 131 # leave quotes on args when splitting, because we want 132 # unquoted args to eval in user_ns 133 cfg = Config() 134 exec("cfg."+line, self.shell.user_ns, locals()) 135 136 for configurable in configurables: 137 try: 138 configurable.update_config(cfg) 139 except Exception as e: 140 error(e) 141