def set_env(self, parameter_s): """Set environment variables. Assumptions are that either "val" is a name in the user namespace, or val is something that evaluates to a string. Usage:\\ %set_env var val: set value for var %set_env var=val: set value for var %set_env var=$val: set value for var, using python expansion if possible """ split = '=' if '=' in parameter_s else ' ' bits = parameter_s.split(split, 1) if not parameter_s.strip() or len(bits)<2: raise UsageError("usage is 'set_env var=val'") var = bits[0].strip() val = bits[1].strip() if re.match(r'.*\s.*', var): # an environment variable with whitespace is almost certainly # not what the user intended. what's more likely is the wrong # split was chosen, ie for "set_env cmd_args A=B", we chose # '=' for the split and should have chosen ' '. to get around # this, users should just assign directly to os.environ or use # standard magic {var} expansion. err = "refusing to set env var with whitespace: '{0}'" err = err.format(val) raise UsageError(err) os.environ[var] = val print('env: {0}={1}'.format(var,val))
def bookmark(self, parameter_s=''): """Manage yap_ipython's bookmark system. %bookmark <name> - set bookmark to current dir %bookmark <name> <dir> - set bookmark to <dir> %bookmark -l - list all bookmarks %bookmark -d <name> - remove bookmark %bookmark -r - remove all bookmarks You can later on access a bookmarked folder with:: %cd -b <name> or simply '%cd <name>' if there is no directory called <name> AND there is such a bookmark defined. Your bookmarks persist through yap_ipython sessions, but they are associated with each profile.""" opts,args = self.parse_options(parameter_s,'drl',mode='list') if len(args) > 2: raise UsageError("%bookmark: too many arguments") bkms = self.shell.db.get('bookmarks',{}) if 'd' in opts: try: todel = args[0] except IndexError: raise UsageError( "%bookmark -d: must provide a bookmark to delete") else: try: del bkms[todel] except KeyError: raise UsageError( "%%bookmark -d: Can't delete bookmark '%s'" % todel) elif 'r' in opts: bkms = {} elif 'l' in opts: bks = sorted(bkms) if bks: size = max(map(len, bks)) else: size = 0 fmt = '%-'+str(size)+'s -> %s' print('Current bookmarks:') for bk in bks: print(fmt % (bk, bkms[bk])) else: if not args: raise UsageError("%bookmark: You must specify the bookmark name") elif len(args)==1: bkms[args[0]] = os.getcwd() elif len(args)==2: bkms[args[0]] = args[1] self.shell.db['bookmarks'] = bkms
def pycat(self, parameter_s=''): """Show a syntax-highlighted file through a pager. This magic is similar to the cat utility, but it will assume the file to be Python source and will show it with syntax highlighting. This magic command can either take a local filename, an url, an history range (see %history) or a macro as argument :: %pycat myscript.py %pycat 7-27 %pycat myMacro %pycat http://www.example.com/myscript.py """ if not parameter_s: raise UsageError('Missing filename, URL, input history range, ' 'or macro.') try : cont = self.shell.find_user_code(parameter_s, skip_encoding_cookie=False) except (ValueError, IOError): print("Error: no such file, variable, URL, history range or macro") return page.page(self.shell.pycolorize(source_to_unicode(cont)))
def enable_gui(self, gui): from .eventloops import enable_gui as real_enable_gui try: real_enable_gui(gui) self.active_eventloop = gui except ValueError as e: raise UsageError("%s" % e)
def popd(self, parameter_s=''): """Change to directory popped off the top of the stack. """ if not self.shell.dir_stack: raise UsageError("%popd on empty stack") top = self.shell.dir_stack.pop(0) self.cd(top) print("popd ->",top)
def load_ext(self, module_str): """Load an yap_ipython extension by its module name.""" if not module_str: raise UsageError('Missing module name.') res = self.shell.extension_manager.load_extension(module_str) if res == 'already loaded': print("The %s extension is already loaded. To reload it, use:" % module_str) print(" %reload_ext", module_str) elif res == 'no load function': print("The %s module is not an yap_ipython extension." % module_str)
def less(self, arg_s): """Show a file through the pager. Files ending in .py are syntax-highlighted.""" if not arg_s: raise UsageError('Missing filename.') if arg_s.endswith('.py'): cont = self.shell.pycolorize( openpy.read_py_file(arg_s, skip_encoding_cookie=False)) else: cont = open(arg_s).read() page.page(cont)
def pwd(self, parameter_s=''): """Return the current working directory path. Examples -------- :: In [9]: pwd Out[9]: '/home/tsuser/sprint/ipython' """ try: return os.getcwd() except FileNotFoundError: raise UsageError("CWD no longer exists - please use %cd to change directory.")
def profile(self, parameter_s=''): """DEPRECATED since yap_ipython 2.0. Raise `UsageError`. To profile code use the :magic:`prun` magic. See Also -------- prun : run code using the Python profiler (:magic:`prun`) """ raise UsageError( "The `%profile` magic has been deprecated since yap_ipython 2.0. " "and removed in yap_ipython 6.0. Please use the value of `get_ipython().profile` instead " "to see current profile in use. Perhaps you meant to use `%prun` to profile code?" )
def unload_ext(self, module_str): """Unload an yap_ipython extension by its module name. Not all extensions can be unloaded, only those which define an ``unload_ipython_extension`` function. """ if not module_str: raise UsageError('Missing module name.') res = self.shell.extension_manager.unload_extension(module_str) if res == 'no unload function': print("The %s extension doesn't define how to unload it." % module_str) elif res == "not loaded": print("The %s extension is not loaded." % module_str)
def colors(self, parameter_s=''): """Switch color scheme for prompts, info system and exception handlers. Currently implemented schemes: NoColor, Linux, LightBG. Color scheme names are not case-sensitive. Examples -------- To get a plain black and white terminal:: %colors nocolor """ def color_switch_err(name): warn('Error changing %s color schemes.\n%s' % (name, sys.exc_info()[1]), stacklevel=2) new_scheme = parameter_s.strip() if not new_scheme: raise UsageError( "%colors: you must specify a color scheme. See '%colors?'") # local shortcut shell = self.shell # Set shell colour scheme try: shell.colors = new_scheme shell.refresh_style() except: color_switch_err('shell') # Set exception colors try: shell.InteractiveTB.set_colors(scheme=new_scheme) shell.SyntaxTB.set_colors(scheme=new_scheme) except: color_switch_err('exception') # Set info (for 'object?') colors if shell.color_info: try: shell.inspector.set_active_scheme(new_scheme) except: color_switch_err('object inspector') else: shell.inspector.set_active_scheme('NoColor')
def passwd(passphrase=None, algorithm='sha1'): """Generate hashed password and salt for use in notebook configuration. In the notebook configuration, set `c.NotebookApp.password` to the generated string. Parameters ---------- passphrase : str Password to hash. If unspecified, the user is asked to input and verify a password. algorithm : str Hashing algorithm to use (e.g, 'sha1' or any argument supported by :func:`hashlib.new`). Returns ------- hashed_passphrase : str Hashed password, in the format 'hash_algorithm:salt:passphrase_hash'. Examples -------- >>> passwd('mypassword') 'sha1:7cf3:b7d6da294ea9592a9480c8f52e63cd42cfb9dd12' """ if passphrase is None: for i in range(3): p0 = getpass.getpass('Enter password: '******'Verify password: '******'Passwords do not match.') else: raise UsageError('No matching passwords found. Giving up.') h = hashlib.new(algorithm) salt = ('%0' + str(salt_len) + 'x') % random.getrandbits(4 * salt_len) h.update(encode(passphrase, 'utf-8') + encode(salt, 'ascii')) return ':'.join((algorithm, salt, h.hexdigest()))
def __call__(self, rest=''): cmd = self.cmd nargs = self.nargs # Expand the %l special to be the user's input line if cmd.find('%l') >= 0: cmd = cmd.replace('%l', rest) rest = '' if nargs == 0: if cmd.find('%%s') >= 1: cmd = cmd.replace('%%s', '%s') # Simple, argument-less aliases cmd = '%s %s' % (cmd, rest) else: # Handle aliases with positional arguments args = rest.split(None, nargs) if len(args) < nargs: raise UsageError( 'Alias <%s> requires %s arguments, %s given.' % (self.name, nargs, len(args))) cmd = '%s %s' % (cmd % tuple(args[:nargs]), ' '.join(args[nargs:])) self.shell.system(cmd)
def autosave(self, arg_s): """Set the autosave interval in the notebook (in seconds). The default value is 120, or two minutes. ``%autosave 0`` will disable autosave. This magic only has an effect when called from the notebook interface. It has no effect when called in a startup file. """ try: interval = int(arg_s) except ValueError: raise UsageError("%%autosave requires an integer, got %r" % arg_s) # javascript wants milliseconds milliseconds = 1000 * interval display(Javascript("yap_ipython.notebook.set_autosave_interval(%i)" % milliseconds), include=['application/javascript']) if interval: print("Autosaving every %i seconds" % interval) else: print("Autosave disabled")
def env(self, parameter_s=''): """Get, set, or list environment variables. Usage:\\ %env: lists all environment variables/values %env var: get value for var %env var val: set value for var %env var=val: set value for var %env var=$val: set value for var, using python expansion if possible """ if parameter_s.strip(): split = '=' if '=' in parameter_s else ' ' bits = parameter_s.split(split) if len(bits) == 1: key = parameter_s.strip() if key in os.environ: return os.environ[key] else: err = "Environment does not have key: {0}".format(key) raise UsageError(err) if len(bits) > 1: return self.set_env(parameter_s) return dict(os.environ)
def reload_ext(self, module_str): """Reload an yap_ipython extension by its module name.""" if not module_str: raise UsageError('Missing module name.') self.shell.extension_manager.reload_extension(module_str)
def alias_magic(self, line=''): """Create an alias for an existing line or cell magic. Examples -------- :: In [1]: %alias_magic t timeit Created `%t` as an alias for `%timeit`. Created `%%t` as an alias for `%%timeit`. In [2]: %t -n1 pass 1 loops, best of 3: 954 ns per loop In [3]: %%t -n1 ...: pass ...: 1 loops, best of 3: 954 ns per loop In [4]: %alias_magic --cell whereami pwd UsageError: Cell magic function `%%pwd` not found. In [5]: %alias_magic --line whereami pwd Created `%whereami` as an alias for `%pwd`. In [6]: %whereami Out[6]: u'/home/testuser' In [7]: %alias_magic h history -p "-l 30" --line Created `%h` as an alias for `%history -l 30`. """ args = magic_arguments.parse_argstring(self.alias_magic, line) shell = self.shell mman = self.shell.magics_manager escs = ''.join(magic_escapes.values()) target = args.target.lstrip(escs) name = args.name.lstrip(escs) params = args.params if (params and ((params.startswith('"') and params.endswith('"')) or (params.startswith("'") and params.endswith("'")))): params = params[1:-1] # Find the requested magics. m_line = shell.find_magic(target, 'line') m_cell = shell.find_magic(target, 'cell') if args.line and m_line is None: raise UsageError('Line magic function `%s%s` not found.' % (magic_escapes['line'], target)) if args.cell and m_cell is None: raise UsageError('Cell magic function `%s%s` not found.' % (magic_escapes['cell'], target)) # If --line and --cell are not specified, default to the ones # that are available. if not args.line and not args.cell: if not m_line and not m_cell: raise UsageError( 'No line or cell magic with name `%s` found.' % target) args.line = bool(m_line) args.cell = bool(m_cell) params_str = "" if params is None else " " + params if args.line: mman.register_alias(name, target, 'line', params) print('Created `%s%s` as an alias for `%s%s%s`.' % (magic_escapes['line'], name, magic_escapes['line'], target, params_str)) if args.cell: mman.register_alias(name, target, 'cell', params) print('Created `%s%s` as an alias for `%s%s%s`.' % (magic_escapes['cell'], name, magic_escapes['cell'], target, params_str))
def cd(self, parameter_s=''): """Change the current working directory. This command automatically maintains an internal list of directories you visit during your yap_ipython session, in the variable _dh. The command %dhist shows this history nicely formatted. You can also do 'cd -<tab>' to see directory history conveniently. Usage: cd 'dir': changes to directory 'dir'. cd -: changes to the last visited directory. cd -<n>: changes to the n-th directory in the directory history. cd --foo: change to directory that matches 'foo' in history cd -b <bookmark_name>: jump to a bookmark set by %bookmark (note: cd <bookmark_name> is enough if there is no directory <bookmark_name>, but a bookmark with the name exists.) 'cd -b <tab>' allows you to tab-complete bookmark names. Options: -q: quiet. Do not print the working directory after the cd command is executed. By default yap_ipython's cd command does print this directory, since the default prompts do not display path information. Note that !cd doesn't work for this purpose because the shell where !command runs is immediately discarded after executing 'command'. Examples -------- :: In [10]: cd parent/child /home/tsuser/parent/child """ try: oldcwd = os.getcwd() except FileNotFoundError: # Happens if the CWD has been deleted. oldcwd = None numcd = re.match(r'(-)(\d+)$',parameter_s) # jump in directory history by number if numcd: nn = int(numcd.group(2)) try: ps = self.shell.user_ns['_dh'][nn] except IndexError: print('The requested directory does not exist in history.') return else: opts = {} elif parameter_s.startswith('--'): ps = None fallback = None pat = parameter_s[2:] dh = self.shell.user_ns['_dh'] # first search only by basename (last component) for ent in reversed(dh): if pat in os.path.basename(ent) and os.path.isdir(ent): ps = ent break if fallback is None and pat in ent and os.path.isdir(ent): fallback = ent # if we have no last part match, pick the first full path match if ps is None: ps = fallback if ps is None: print("No matching entry in directory history") return else: opts = {} else: opts, ps = self.parse_options(parameter_s, 'qb', mode='string') # jump to previous if ps == '-': try: ps = self.shell.user_ns['_dh'][-2] except IndexError: raise UsageError('%cd -: No previous directory to change to.') # jump to bookmark if needed else: if not os.path.isdir(ps) or 'b' in opts: bkms = self.shell.db.get('bookmarks', {}) if ps in bkms: target = bkms[ps] print('(bookmark:%s) -> %s' % (ps, target)) ps = target else: if 'b' in opts: raise UsageError("Bookmark '%s' not found. " "Use '%%bookmark -l' to see your bookmarks." % ps) # at this point ps should point to the target dir if ps: try: os.chdir(os.path.expanduser(ps)) if hasattr(self.shell, 'term_title') and self.shell.term_title: set_term_title(self.shell.term_title_format.format(cwd=abbrev_cwd())) except OSError: print(sys.exc_info()[1]) else: cwd = os.getcwd() dhist = self.shell.user_ns['_dh'] if oldcwd != cwd: dhist.append(cwd) self.shell.db['dhist'] = compress_dhist(dhist)[-100:] else: os.chdir(self.shell.home_dir) if hasattr(self.shell, 'term_title') and self.shell.term_title: set_term_title(self.shell.term_title_format.format(cwd="~")) cwd = os.getcwd() dhist = self.shell.user_ns['_dh'] if oldcwd != cwd: dhist.append(cwd) self.shell.db['dhist'] = compress_dhist(dhist)[-100:] if not 'q' in opts and self.shell.user_ns['_dh']: print(self.shell.user_ns['_dh'][-1])
def store(self, parameter_s=''): """Lightweight persistence for python variables. Example:: In [1]: l = ['hello',10,'world'] In [2]: %store l In [3]: exit (yap_ipython session is closed and started again...) ville@badger:~$ ipython In [1]: l NameError: name 'l' is not defined In [2]: %store -r In [3]: l Out[3]: ['hello', 10, 'world'] Usage: * ``%store`` - Show list of all variables and their current values * ``%store spam`` - Store the *current* value of the variable spam to disk * ``%store -d spam`` - Remove the variable and its value from storage * ``%store -z`` - Remove all variables from storage * ``%store -r`` - Refresh all variables from store (overwrite current vals) * ``%store -r spam bar`` - Refresh specified variables from store (delete current val) * ``%store foo >a.txt`` - Store value of foo to new file a.txt * ``%store foo >>a.txt`` - Append value of foo to file a.txt It should be noted that if you change the value of a variable, you need to %store it again if you want to persist the new value. Note also that the variables will need to be pickleable; most basic python types can be safely %store'd. Also aliases can be %store'd across sessions. """ opts, argsl = self.parse_options(parameter_s, 'drz', mode='string') args = argsl.split(None, 1) ip = self.shell db = ip.db # delete if 'd' in opts: try: todel = args[0] except IndexError: raise UsageError('You must provide the variable to forget') else: try: del db['autorestore/' + todel] except: raise UsageError("Can't delete variable '%s'" % todel) # reset elif 'z' in opts: for k in db.keys('autorestore/*'): del db[k] elif 'r' in opts: if args: for arg in args: try: obj = db['autorestore/' + arg] except KeyError: print("no stored variable %s" % arg) else: ip.user_ns[arg] = obj else: restore_data(ip) # run without arguments -> list variables & values elif not args: vars = db.keys('autorestore/*') vars.sort() if vars: size = max(map(len, vars)) else: size = 0 print('Stored variables and their in-db values:') fmt = '%-' + str(size) + 's -> %s' get = db.get for var in vars: justkey = os.path.basename(var) # print 30 first characters from every var print(fmt % (justkey, repr(get(var, '<unavailable>'))[:50])) # default action - store the variable else: # %store foo >file.txt or >>file.txt if len(args) > 1 and args[1].startswith('>'): fnam = os.path.expanduser(args[1].lstrip('>').lstrip()) if args[1].startswith('>>'): fil = open(fnam, 'a') else: fil = open(fnam, 'w') obj = ip.ev(args[0]) print("Writing '%s' (%s) to file '%s'." % (args[0], obj.__class__.__name__, fnam)) if not isinstance(obj, str): from pprint import pprint pprint(obj, fil) else: fil.write(obj) if not obj.endswith('\n'): fil.write('\n') fil.close() return # %store foo try: obj = ip.user_ns[args[0]] except KeyError: # it might be an alias name = args[0] try: cmd = ip.alias_manager.retrieve_alias(name) except ValueError: raise UsageError("Unknown variable '%s'" % name) staliases = db.get('stored_aliases', {}) staliases[name] = cmd db['stored_aliases'] = staliases print("Alias stored: %s (%s)" % (name, cmd)) return else: modname = getattr(inspect.getmodule(obj), '__name__', '') if modname == '__main__': print( textwrap.dedent("""\ Warning:%s is %s Proper storage of interactively declared classes (or instances of those classes) is not possible! Only instances of classes in real modules on file system can be %%store'd. """ % (args[0], obj))) return #pickled = pickle.dumps(obj) db['autorestore/' + args[0]] = obj print("Stored '%s' (%s)" % (args[0], obj.__class__.__name__))
def error(self, message): """ Raise a catchable error instead of exiting. """ raise UsageError(message)
def psource(self, parameter_s='', namespaces=None): """Print (or run through pager) the source code for an object.""" if not parameter_s: raise UsageError('Missing object name.') self.shell._inspect('psource', parameter_s, namespaces)
def save(self, parameter_s=''): """Save a set of lines or a macro to a given filename. Usage:\\ %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ... Options: -r: use 'raw' input. By default, the 'processed' history is used, so that magics are loaded in their transformed version to valid Python. If this option is given, the raw input as typed as the command line is used instead. -f: force overwrite. If file exists, %save will prompt for overwrite unless -f is given. -a: append to the file instead of overwriting it. This function uses the same syntax as %history for input ranges, then saves the lines to the filename you specify. It adds a '.py' extension to the file if you don't do so yourself, and it asks for confirmation before overwriting existing files. If `-r` option is used, the default extension is `.ipy`. """ opts, args = self.parse_options(parameter_s, 'fra', mode='list') if not args: raise UsageError('Missing filename.') raw = 'r' in opts force = 'f' in opts append = 'a' in opts mode = 'a' if append else 'w' ext = u'.ipy' if raw else u'.py' fname, codefrom = args[0], " ".join(args[1:]) if not fname.endswith((u'.py', u'.ipy')): fname += ext file_exists = os.path.isfile(fname) if file_exists and not force and not append: try: overwrite = self.shell.ask_yes_no( 'File `%s` exists. Overwrite (y/[N])? ' % fname, default='n') except StdinNotImplementedError: print( "File `%s` exists. Use `%%save -f %s` to force overwrite" % (fname, parameter_s)) return if not overwrite: print('Operation cancelled.') return try: cmds = self.shell.find_user_code(codefrom, raw) except (TypeError, ValueError) as e: print(e.args[0]) return out = py3compat.cast_unicode(cmds) with io.open(fname, mode, encoding="utf-8") as f: if not file_exists or not append: f.write(u"# coding: utf-8\n") f.write(out) # make sure we end on a newline if not out.endswith(u'\n'): f.write(u'\n') print('The following commands were written to file `%s`:' % fname) print(cmds)
def load(self, arg_s): """Load code into the current frontend. Usage:\\ %load [options] source where source can be a filename, URL, input history range, macro, or element in the user namespace Options: -r <lines>: Specify lines or ranges of lines to load from the source. Ranges could be specified as x-y (x..y) or in python-style x:y (x..(y-1)). Both limits x and y can be left blank (meaning the beginning and end of the file, respectively). -s <symbols>: Specify function or classes to load from python source. -y : Don't ask confirmation for loading source above 200 000 characters. -n : Include the user's namespace when searching for source code. This magic command can either take a local filename, a URL, an history range (see %history) or a macro as argument, it will prompt for confirmation before loading source with more than 200 000 characters, unless -y flag is passed or if the frontend does not support raw_input:: %load myscript.py %load 7-27 %load myMacro %load http://www.example.com/myscript.py %load -r 5-10 myscript.py %load -r 10-20,30,40: foo.py %load -s MyClass,wonder_function myscript.py %load -n MyClass %load -n my_module.wonder_function """ opts, args = self.parse_options(arg_s, 'yns:r:') if not args: raise UsageError('Missing filename, URL, input history range, ' 'macro, or element in the user namespace.') search_ns = 'n' in opts contents = self.shell.find_user_code(args, search_ns=search_ns) if 's' in opts: try: blocks, not_found = extract_symbols(contents, opts['s']) except SyntaxError: # non python code error("Unable to parse the input as valid Python code") return if len(not_found) == 1: warn('The symbol `%s` was not found' % not_found[0]) elif len(not_found) > 1: warn('The symbols %s were not found' % get_text_list(not_found, wrap_item_with='`')) contents = '\n'.join(blocks) if 'r' in opts: ranges = opts['r'].replace(',', ' ') lines = contents.split('\n') slices = extract_code_ranges(ranges) contents = [lines[slice(*slc)] for slc in slices] contents = '\n'.join( strip_initial_indent(chain.from_iterable(contents))) l = len(contents) # 200 000 is ~ 2500 full 80 character lines # so in average, more than 5000 lines if l > 200000 and 'y' not in opts: try: ans = self.shell.ask_yes_no(("The text you're trying to load seems pretty big"\ " (%d characters). Continue (y/[N]) ?" % l), default='n' ) except StdinNotImplementedError: #assume yes if raw input not implemented ans = True if ans is False: print('Operation cancelled.') return contents = "# %load {}\n".format(arg_s) + contents self.shell.set_next_input(contents, replace=True)
def config(self, s): """configure yap_ipython %config Class[.trait=value] This magic exposes most of the yap_ipython config system. Any Configurable class should be able to be configured with the simple line:: %config Class.trait=value Where `value` will be resolved in the user's namespace, if it is an expression or variable name. Examples -------- To see what classes are available for config, pass no arguments:: In [1]: %config Available objects for config: TerminalInteractiveShell HistoryManager PrefilterManager AliasManager IPCompleter DisplayFormatter To view what is configurable on a given class, just pass the class name:: In [2]: %config IPCompleter IPCompleter options ----------------- IPCompleter.omit__names=<Enum> Current: 2 Choices: (0, 1, 2) Instruct the completer to omit private method names Specifically, when completing on ``object.<tab>``. 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=<CBool> 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.limit_to__all__=<CBool> Current: False Instruct the completer to use __all__ for the completion Specifically, when completing on ``object.<tab>``. When True: only those names in obj.__all__ will be included. When False [default]: the __all__ attribute is ignored IPCompleter.greedy=<CBool> Current: False Activate greedy completion This will enable completion on elements of lists, results of function calls, etc., but can be unsafe because the code is actually evaluated on TAB. but the real use is in setting values:: In [3]: %config IPCompleter.greedy = True and these values are read from the user_ns if they are variables:: In [4]: feeling_greedy=False In [5]: %config IPCompleter.greedy = feeling_greedy """ from traitlets.config.loader import Config # some yap_ipython objects are Configurable, but do not yet have # any configurable traits. Exclude them from the effects of # this magic, as their presence is just noise: configurables = sorted(set([ c for c in self.shell.configurables if c.__class__.class_traits(config=True) ]), key=lambda x: x.__class__.__name__) classnames = [c.__class__.__name__ for c in configurables] line = s.strip() if not line: # print available configurable names print("Available objects for config:") for name in classnames: print(" ", name) return elif line in classnames: # `%config TerminalInteractiveShell` will print trait info for # TerminalInteractiveShell c = configurables[classnames.index(line)] cls = c.__class__ help = cls.class_get_help(c) # strip leading '--' from cl-args: help = re.sub(re.compile(r'^--', re.MULTILINE), '', help) print(help) return elif reg.match(line): cls, attr = line.split('.') return getattr(configurables[classnames.index(cls)], attr) elif '=' not in line: msg = "Invalid config statement: %r, "\ "should be `Class.trait = value`." ll = line.lower() for classname in classnames: if ll == classname.lower(): msg = msg + '\nDid you mean %s (note the case)?' % classname break raise UsageError(msg % line) # otherwise, assume we are setting configurables. # leave quotes on args when splitting, because we want # unquoted args to eval in user_ns cfg = Config() exec("cfg." + line, locals(), self.shell.user_ns) for configurable in configurables: try: configurable.update_config(cfg) except Exception as e: error(e)