config.py
157 lines
| 5.8 KiB
| text/x-python
|
PythonLexer
Fernando Perez
|
r6961 | """Implementation of configuration-related magic functions. | ||
""" | ||||
#----------------------------------------------------------------------------- | ||||
# Copyright (c) 2012 The IPython Development Team. | ||||
# | ||||
# Distributed under the terms of the Modified BSD License. | ||||
# | ||||
# The full license is in the file COPYING.txt, distributed with this software. | ||||
#----------------------------------------------------------------------------- | ||||
#----------------------------------------------------------------------------- | ||||
# Imports | ||||
#----------------------------------------------------------------------------- | ||||
# Stdlib | ||||
import re | ||||
# Our own packages | ||||
from IPython.core.error import UsageError | ||||
Fernando Perez
|
r6973 | from IPython.core.magic import Magics, magics_class, line_magic | ||
Pierre Gerold
|
r22092 | from logging import error | ||
Fernando Perez
|
r6961 | |||
#----------------------------------------------------------------------------- | ||||
# Magic implementation classes | ||||
#----------------------------------------------------------------------------- | ||||
Matthias BUSSONNIER
|
r10207 | reg = re.compile('^\w+\.\w+$') | ||
Fernando Perez
|
r6973 | @magics_class | ||
Fernando Perez
|
r6961 | class ConfigMagics(Magics): | ||
def __init__(self, shell): | ||||
super(ConfigMagics, self).__init__(shell) | ||||
self.configurables = [] | ||||
@line_magic | ||||
def config(self, s): | ||||
"""configure IPython | ||||
%config Class[.trait=value] | ||||
This magic exposes most of the 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 | ||||
""" | ||||
Min RK
|
r21253 | from traitlets.config.loader import Config | ||
Fernando Perez
|
r6961 | # some 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 = [ c for c in self.shell.configurables | ||||
if c.__class__.class_traits(config=True) ] | ||||
classnames = [ c.__class__.__name__ for c in configurables ] | ||||
line = s.strip() | ||||
if not line: | ||||
# print available configurable names | ||||
Thomas Kluyver
|
r13348 | print("Available objects for config:") | ||
Fernando Perez
|
r6961 | for name in classnames: | ||
Thomas Kluyver
|
r13348 | print(" ", name) | ||
Fernando Perez
|
r6961 | 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) | ||||
Thomas Kluyver
|
r13348 | print(help) | ||
Fernando Perez
|
r6961 | return | ||
Matthias BUSSONNIER
|
r10207 | elif reg.match(line): | ||
cls, attr = line.split('.') | ||||
return getattr(configurables[classnames.index(cls)],attr) | ||||
Fernando Perez
|
r6961 | elif '=' not in line: | ||
Matthias BUSSONNIER
|
r10207 | msg = "Invalid config statement: %r, "\ | ||
"should be `Class.trait = value`." | ||||
MinRK
|
r10245 | |||
ll = line.lower() | ||||
for classname in classnames: | ||||
if ll == classname.lower(): | ||||
msg = msg + '\nDid you mean %s (note the case)?' % classname | ||||
break | ||||
Matthias BUSSONNIER
|
r10207 | |||
raise UsageError( msg % line) | ||||
Fernando Perez
|
r6961 | |||
# otherwise, assume we are setting configurables. | ||||
# leave quotes on args when splitting, because we want | ||||
# unquoted args to eval in user_ns | ||||
cfg = Config() | ||||
Thomas Kluyver
|
r13350 | exec("cfg."+line, locals(), self.shell.user_ns) | ||
Fernando Perez
|
r6961 | |||
for configurable in configurables: | ||||
try: | ||||
configurable.update_config(cfg) | ||||
except Exception as e: | ||||
error(e) | ||||