Skip to content

Commit

Permalink
aliases match flag pattern ('-' as wordsep, not '_')
Browse files Browse the repository at this point in the history
aliases are now: --log-level=foo
rather than --log_level=foo

unrecognized aliases give a warning, and to suppress these warnings in tests, a context manager for disabling warning messages is added to testing.tools.
  • Loading branch information
minrk committed Jul 13, 2011
1 parent cd98bc3 commit 21c18a1
Show file tree
Hide file tree
Showing 14 changed files with 94 additions and 53 deletions.
2 changes: 1 addition & 1 deletion IPython/config/application.py
Expand Up @@ -111,7 +111,7 @@ def _log_level_changed(self, name, old, new):
self.log.setLevel(new)

# the alias map for configurables
aliases = Dict(dict(log_level='Application.log_level'))
aliases = Dict({'log-level' : 'Application.log_level'})

# flags for loading Configurables or store_const style flags
# flags are loaded from this dict by '--key' flags
Expand Down
25 changes: 22 additions & 3 deletions IPython/config/loader.py
Expand Up @@ -24,6 +24,7 @@

from IPython.external import argparse
from IPython.utils.path import filefind, get_ipython_dir
from IPython.utils import warn

#-----------------------------------------------------------------------------
# Exceptions
Expand Down Expand Up @@ -325,7 +326,22 @@ class CommandLineConfigLoader(ConfigLoader):
here.
"""

kv_pattern = re.compile(r'\-\-[A-Za-z]\w*(\.\w+)*\=.*')
# raw --identifier=value pattern
# but *also* accept '-' as wordsep, for aliases
# accepts: --foo=a
# --Class.trait=value
# --alias-name=value
# rejects: -foo=value
# --foo
# --Class.trait
kv_pattern = re.compile(r'\-\-[A-Za-z][\w\-]*(\.[\w\-]+)*\=.*')

# just flags, no assignments, with two *or one* leading '-'
# accepts: --foo
# -foo-bar-again
# rejects: --anything=anything
# --two.word

flag_pattern = re.compile(r'\-\-?\w+[\-\w]*$')

class KeyValueConfigLoader(CommandLineConfigLoader):
Expand Down Expand Up @@ -364,8 +380,8 @@ def __init__(self, argv=None, aliases=None, flags=None):
>>> from IPython.config.loader import KeyValueConfigLoader
>>> cl = KeyValueConfigLoader()
>>> cl.load_config(["--foo='bar'","--A.name='brian'","--B.number=0"])
{'A': {'name': 'brian'}, 'B': {'number': 0}, 'foo': 'bar'}
>>> cl.load_config(["--A.name='brian'","--B.number=0"])
{'A': {'name': 'brian'}, 'B': {'number': 0}}
"""
self.clear()
if argv is None:
Expand Down Expand Up @@ -444,6 +460,9 @@ def load_config(self, argv=None, aliases=None, flags=None):
# Substitute longnames for aliases.
if lhs in aliases:
lhs = aliases[lhs]
if '.' not in lhs:
# probably a mistyped alias, but not technically illegal
warn.warn("Unrecognized alias: '%s', it will probably have no effect."%lhs)
exec_str = 'self.config.' + lhs + '=' + rhs
try:
# Try to see if regular Python syntax will work. This
Expand Down
13 changes: 9 additions & 4 deletions IPython/config/tests/test_application.py
Expand Up @@ -55,8 +55,13 @@ class MyApp(Application):
config_file = Unicode(u'', config=True,
help="Load this config file")

aliases = Dict(dict(i='Foo.i',j='Foo.j',name='Foo.name',
enabled='Bar.enabled', log_level='MyApp.log_level'))
aliases = Dict({
'i' : 'Foo.i',
'j' : 'Foo.j',
'name' : 'Foo.name',
'enabled' : 'Bar.enabled',
'log-level' : 'MyApp.log_level',
})

flags = Dict(dict(enable=({'Bar': {'enabled' : True}}, "Set Bar.enabled to True"),
disable=({'Bar': {'enabled' : False}}, "Set Bar.enabled to False")))
Expand All @@ -79,7 +84,7 @@ def test_basic(self):

def test_config(self):
app = MyApp()
app.parse_command_line(["--i=10","--Foo.j=10","--enabled=False","--log_level=50"])
app.parse_command_line(["--i=10","--Foo.j=10","--enabled=False","--log-level=50"])
config = app.config
self.assertEquals(config.Foo.i, 10)
self.assertEquals(config.Foo.j, 10)
Expand All @@ -88,7 +93,7 @@ def test_config(self):

def test_config_propagation(self):
app = MyApp()
app.parse_command_line(["--i=10","--Foo.j=10","--enabled=False","--log_level=50"])
app.parse_command_line(["--i=10","--Foo.j=10","--enabled=False","--log-level=50"])
app.init_foo()
app.init_bar()
self.assertEquals(app.foo.i, 10)
Expand Down
17 changes: 12 additions & 5 deletions IPython/config/tests/test_loader.py
Expand Up @@ -27,6 +27,8 @@

from nose import SkipTest

from IPython.testing.tools import mute_warn

from IPython.utils.traitlets import Int, Unicode
from IPython.config.configurable import Configurable
from IPython.config.loader import (
Expand Down Expand Up @@ -120,7 +122,8 @@ class TestKeyValueCL(TestCase):
def test_basic(self):
cl = KeyValueConfigLoader()
argv = ['--'+s.strip('c.') for s in pyfile.split('\n')[2:-1]]
config = cl.load_config(argv)
with mute_warn():
config = cl.load_config(argv)
self.assertEquals(config.a, 10)
self.assertEquals(config.b, 20)
self.assertEquals(config.Foo.Bar.value, 10)
Expand All @@ -129,17 +132,20 @@ def test_basic(self):

def test_extra_args(self):
cl = KeyValueConfigLoader()
config = cl.load_config(['--a=5', 'b', '--c=10', 'd'])
with mute_warn():
config = cl.load_config(['--a=5', 'b', '--c=10', 'd'])
self.assertEquals(cl.extra_args, ['b', 'd'])
self.assertEquals(config.a, 5)
self.assertEquals(config.c, 10)
config = cl.load_config(['--', '--a=5', '--c=10'])
with mute_warn():
config = cl.load_config(['--', '--a=5', '--c=10'])
self.assertEquals(cl.extra_args, ['--a=5', '--c=10'])

def test_unicode_args(self):
cl = KeyValueConfigLoader()
argv = [u'--a=épsîlön']
config = cl.load_config(argv)
with mute_warn():
config = cl.load_config(argv)
self.assertEquals(config.a, u'épsîlön')

def test_unicode_bytes_args(self):
Expand All @@ -150,7 +156,8 @@ def test_unicode_bytes_args(self):
raise SkipTest("sys.stdin.encoding can't handle 'é'")

cl = KeyValueConfigLoader()
config = cl.load_config([barg])
with mute_warn():
config = cl.load_config([barg])
self.assertEquals(config.a, u'é')


Expand Down
10 changes: 5 additions & 5 deletions IPython/core/application.py
Expand Up @@ -52,11 +52,11 @@

# aliases and flags

base_aliases = dict(
profile='BaseIPythonApplication.profile',
ipython_dir='BaseIPythonApplication.ipython_dir',
log_level='Application.log_level',
)
base_aliases = {
'profile' : 'BaseIPythonApplication.profile',
'ipython-dir' : 'BaseIPythonApplication.ipython_dir',
'log-level' : 'Application.log_level',
}

base_flags = dict(
debug = ({'Application' : {'log_level' : logging.DEBUG}},
Expand Down
10 changes: 5 additions & 5 deletions IPython/core/profileapp.py
Expand Up @@ -84,13 +84,13 @@ class ProfileList(Application):
name = u'ipython-profile'
description = list_help

aliases = Dict(dict(
ipython_dir = 'ProfileList.ipython_dir',
log_level = 'Application.log_level',
))
aliases = Dict({
'ipython-dir' : 'ProfileList.ipython_dir',
'log-level' : 'Application.log_level',
})
flags = Dict(dict(
debug = ({'Application' : {'log_level' : 0}},
"Set log_level to 0, maximizing log output."
"Set Application.log_level to 0, maximizing log output."
)
))
ipython_dir = Unicode(get_ipython_dir(), config=True,
Expand Down
2 changes: 1 addition & 1 deletion IPython/core/shellapp.py
Expand Up @@ -90,13 +90,13 @@
# it's possible we don't want short aliases for *all* of these:
shell_aliases = dict(
autocall='InteractiveShell.autocall',
cache_size='InteractiveShell.cache_size',
colors='InteractiveShell.colors',
logfile='InteractiveShell.logfile',
logappend='InteractiveShell.logappend',
c='InteractiveShellApp.code_to_run',
ext='InteractiveShellApp.extra_extension',
)
shell_aliases['cache-size'] = 'InteractiveShell.cache_size'

#-----------------------------------------------------------------------------
# Main classes and functions
Expand Down
10 changes: 5 additions & 5 deletions IPython/parallel/apps/baseapp.py
Expand Up @@ -96,11 +96,11 @@ def __init__(self, app):
base_aliases = {}
base_aliases.update(base_ip_aliases)
base_aliases.update({
'profile_dir' : 'ProfileDir.location',
'work_dir' : 'BaseParallelApplication.work_dir',
'log_to_file' : 'BaseParallelApplication.log_to_file',
'clean_logs' : 'BaseParallelApplication.clean_logs',
'log_url' : 'BaseParallelApplication.log_url',
'profile-dir' : 'ProfileDir.location',
'work-dir' : 'BaseParallelApplication.work_dir',
'log-to-file' : 'BaseParallelApplication.log_to_file',
'clean-logs' : 'BaseParallelApplication.clean_logs',
'log-url' : 'BaseParallelApplication.log_url',
})

base_flags = {
Expand Down
2 changes: 1 addition & 1 deletion IPython/parallel/apps/ipclusterapp.py
Expand Up @@ -321,9 +321,9 @@ def start(self):
start_aliases.update(engine_aliases)
start_aliases.update(dict(
delay='IPClusterStart.delay',
clean_logs='IPClusterStart.clean_logs',
controller = 'IPClusterStart.controller_launcher_class',
))
start_aliases['clean-logs'] = 'IPClusterStart.clean_logs'

class IPClusterStart(IPClusterEngines):

Expand Down
4 changes: 1 addition & 3 deletions IPython/parallel/apps/ipcontrollerapp.py
Expand Up @@ -111,15 +111,13 @@
"Don't authenticate messages."
))
aliases = dict(
reuse_files = 'IPControllerApp.reuse_files',
secure = 'IPControllerApp.secure',
ssh = 'IPControllerApp.ssh_server',
use_threads = 'IPControllerApp.use_threads',
location = 'IPControllerApp.location',

ident = 'Session.session',
user = 'Session.username',
exec_key = 'Session.keyfile',
keyfile = 'Session.keyfile',

url = 'HubFactory.url',
ip = 'HubFactory.ip',
Expand Down
2 changes: 1 addition & 1 deletion IPython/parallel/apps/ipengineapp.py
Expand Up @@ -111,7 +111,7 @@ def _on_use_changed(self, old, new):

ident = 'Session.session',
user = 'Session.username',
exec_key = 'Session.keyfile',
keyfile = 'Session.keyfile',

url = 'EngineFactory.url',
ip = 'EngineFactory.ip',
Expand Down

0 comments on commit 21c18a1

Please sign in to comment.