From 21c18a1e38c9107ca1d37dea31c4f609b266eeab 2011-07-13 21:03:03 From: MinRK Date: 2011-07-13 21:03:03 Subject: [PATCH] aliases match flag pattern ('-' as wordsep, not '_') 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. --- diff --git a/IPython/config/application.py b/IPython/config/application.py index 4933ca9..3a48295 100644 --- a/IPython/config/application.py +++ b/IPython/config/application.py @@ -111,7 +111,7 @@ class Application(SingletonConfigurable): 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 diff --git a/IPython/config/loader.py b/IPython/config/loader.py index f795e91..bc904af 100644 --- a/IPython/config/loader.py +++ b/IPython/config/loader.py @@ -24,6 +24,7 @@ import sys from IPython.external import argparse from IPython.utils.path import filefind, get_ipython_dir +from IPython.utils import warn #----------------------------------------------------------------------------- # Exceptions @@ -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): @@ -364,8 +380,8 @@ class KeyValueConfigLoader(CommandLineConfigLoader): >>> 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: @@ -444,6 +460,9 @@ class KeyValueConfigLoader(CommandLineConfigLoader): # 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 diff --git a/IPython/config/tests/test_application.py b/IPython/config/tests/test_application.py index 6e0c473..0e69cab 100644 --- a/IPython/config/tests/test_application.py +++ b/IPython/config/tests/test_application.py @@ -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"))) @@ -79,7 +84,7 @@ class TestApplication(TestCase): 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) @@ -88,7 +93,7 @@ class TestApplication(TestCase): 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) diff --git a/IPython/config/tests/test_loader.py b/IPython/config/tests/test_loader.py index 27f38eb..e40c585 100755 --- a/IPython/config/tests/test_loader.py +++ b/IPython/config/tests/test_loader.py @@ -27,6 +27,8 @@ from unittest import TestCase 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 ( @@ -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) @@ -129,17 +132,20 @@ class TestKeyValueCL(TestCase): 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): @@ -150,7 +156,8 @@ class TestKeyValueCL(TestCase): 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'é') diff --git a/IPython/core/application.py b/IPython/core/application.py index c99966f..817ffcc 100644 --- a/IPython/core/application.py +++ b/IPython/core/application.py @@ -52,11 +52,11 @@ from IPython.utils.traitlets import List, Unicode, Type, Bool, Dict # 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}}, diff --git a/IPython/core/profileapp.py b/IPython/core/profileapp.py index d42f9c5..d3220cb 100644 --- a/IPython/core/profileapp.py +++ b/IPython/core/profileapp.py @@ -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, diff --git a/IPython/core/shellapp.py b/IPython/core/shellapp.py index 863e06c..a93cad2 100755 --- a/IPython/core/shellapp.py +++ b/IPython/core/shellapp.py @@ -90,13 +90,13 @@ shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.") # 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 diff --git a/IPython/parallel/apps/baseapp.py b/IPython/parallel/apps/baseapp.py index 3b03600..7a455b0 100755 --- a/IPython/parallel/apps/baseapp.py +++ b/IPython/parallel/apps/baseapp.py @@ -96,11 +96,11 @@ class ParallelCrashHandler(CrashHandler): 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 = { diff --git a/IPython/parallel/apps/ipclusterapp.py b/IPython/parallel/apps/ipclusterapp.py index 29d9269..a294b58 100755 --- a/IPython/parallel/apps/ipclusterapp.py +++ b/IPython/parallel/apps/ipclusterapp.py @@ -321,9 +321,9 @@ start_aliases = {} 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): diff --git a/IPython/parallel/apps/ipcontrollerapp.py b/IPython/parallel/apps/ipcontrollerapp.py index 4678e8d..23416bd 100755 --- a/IPython/parallel/apps/ipcontrollerapp.py +++ b/IPython/parallel/apps/ipcontrollerapp.py @@ -111,15 +111,13 @@ flags.update(boolean_flag('secure', 'IPControllerApp.secure', "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', diff --git a/IPython/parallel/apps/ipengineapp.py b/IPython/parallel/apps/ipengineapp.py index d4872c7..0dcdd61 100755 --- a/IPython/parallel/apps/ipengineapp.py +++ b/IPython/parallel/apps/ipengineapp.py @@ -111,7 +111,7 @@ aliases = dict( ident = 'Session.session', user = 'Session.username', - exec_key = 'Session.keyfile', + keyfile = 'Session.keyfile', url = 'EngineFactory.url', ip = 'EngineFactory.ip', diff --git a/IPython/parallel/apps/launcher.py b/IPython/parallel/apps/launcher.py index a46b81f..7168a67 100644 --- a/IPython/parallel/apps/launcher.py +++ b/IPython/parallel/apps/launcher.py @@ -323,7 +323,7 @@ class LocalControllerLauncher(LocalProcessLauncher): controller_cmd = List(ipcontroller_cmd_argv, config=True, help="""Popen command to launch ipcontroller.""") # Command line arguments to ipcontroller. - controller_args = List(['--log-to-file','--log_level=%i'%logging.INFO], config=True, + controller_args = List(['--log-to-file','--log-level=%i'%logging.INFO], config=True, help="""command-line args to pass to ipcontroller""") def find_args(self): @@ -331,7 +331,7 @@ class LocalControllerLauncher(LocalProcessLauncher): def start(self, profile_dir): """Start the controller by profile_dir.""" - self.controller_args.extend(['--profile_dir=%s'%profile_dir]) + self.controller_args.extend(['--profile-dir=%s'%profile_dir]) self.profile_dir = unicode(profile_dir) self.log.info("Starting LocalControllerLauncher: %r" % self.args) return super(LocalControllerLauncher, self).start() @@ -343,7 +343,7 @@ class LocalEngineLauncher(LocalProcessLauncher): engine_cmd = List(ipengine_cmd_argv, config=True, help="""command to launch the Engine.""") # Command line arguments for ipengine. - engine_args = List(['--log-to-file','--log_level=%i'%logging.INFO], config=True, + engine_args = List(['--log-to-file','--log-level=%i'%logging.INFO], config=True, help="command-line arguments to pass to ipengine" ) @@ -352,7 +352,7 @@ class LocalEngineLauncher(LocalProcessLauncher): def start(self, profile_dir): """Start the engine by profile_dir.""" - self.engine_args.extend(['--profile_dir=%s'%profile_dir]) + self.engine_args.extend(['--profile-dir=%s'%profile_dir]) self.profile_dir = unicode(profile_dir) return super(LocalEngineLauncher, self).start() @@ -362,7 +362,7 @@ class LocalEngineSetLauncher(BaseLauncher): # Command line arguments for ipengine. engine_args = List( - ['--log-to-file','--log_level=%i'%logging.INFO], config=True, + ['--log-to-file','--log-level=%i'%logging.INFO], config=True, help="command-line arguments to pass to ipengine" ) # launcher class @@ -468,14 +468,14 @@ class MPIExecControllerLauncher(MPIExecLauncher): controller_cmd = List(ipcontroller_cmd_argv, config=True, help="Popen command to launch the Contropper" ) - controller_args = List(['--log-to-file','--log_level=%i'%logging.INFO], config=True, + controller_args = List(['--log-to-file','--log-level=%i'%logging.INFO], config=True, help="Command line arguments to pass to ipcontroller." ) n = Int(1) def start(self, profile_dir): """Start the controller by profile_dir.""" - self.controller_args.extend(['--profile_dir=%s'%profile_dir]) + self.controller_args.extend(['--profile-dir=%s'%profile_dir]) self.profile_dir = unicode(profile_dir) self.log.info("Starting MPIExecControllerLauncher: %r" % self.args) return super(MPIExecControllerLauncher, self).start(1) @@ -491,14 +491,14 @@ class MPIExecEngineSetLauncher(MPIExecLauncher): help="Popen command for ipengine" ) program_args = List( - ['--log-to-file','--log_level=%i'%logging.INFO], config=True, + ['--log-to-file','--log-level=%i'%logging.INFO], config=True, help="Command line arguments for ipengine." ) n = Int(1) def start(self, n, profile_dir): """Start n engines by profile or profile_dir.""" - self.program_args.extend(['--profile_dir=%s'%profile_dir]) + self.program_args.extend(['--profile-dir=%s'%profile_dir]) self.profile_dir = unicode(profile_dir) self.n = n self.log.info('Starting MPIExecEngineSetLauncher: %r' % self.args) @@ -567,7 +567,7 @@ class SSHControllerLauncher(SSHLauncher): program = List(ipcontroller_cmd_argv, config=True, help="remote ipcontroller command.") - program_args = List(['--reuse-files', '--log-to-file','--log_level=%i'%logging.INFO], config=True, + program_args = List(['--reuse-files', '--log-to-file','--log-level=%i'%logging.INFO], config=True, help="Command line arguments to ipcontroller.") @@ -745,7 +745,7 @@ class WindowsHPCControllerLauncher(WindowsHPCLauncher): def start(self, profile_dir): """Start the controller by profile_dir.""" - self.extra_args = ['--profile_dir=%s'%profile_dir] + self.extra_args = ['--profile-dir=%s'%profile_dir] self.profile_dir = unicode(profile_dir) return super(WindowsHPCControllerLauncher, self).start(1) @@ -779,7 +779,7 @@ class WindowsHPCEngineSetLauncher(WindowsHPCLauncher): def start(self, n, profile_dir): """Start the controller by profile_dir.""" - self.extra_args = ['--profile_dir=%s'%profile_dir] + self.extra_args = ['--profile-dir=%s'%profile_dir] self.profile_dir = unicode(profile_dir) return super(WindowsHPCEngineSetLauncher, self).start(n) @@ -936,7 +936,7 @@ class PBSControllerLauncher(PBSLauncher): default_template= Unicode("""#!/bin/sh #PBS -V #PBS -N ipcontroller -%s --log-to-file --profile_dir={profile_dir} +%s --log-to-file --profile-dir={profile_dir} """%(' '.join(ipcontroller_cmd_argv))) def start(self, profile_dir): @@ -952,7 +952,7 @@ class PBSEngineSetLauncher(PBSLauncher): default_template= Unicode(u"""#!/bin/sh #PBS -V #PBS -N ipengine -%s --profile_dir={profile_dir} +%s --profile-dir={profile_dir} """%(' '.join(ipengine_cmd_argv))) def start(self, n, profile_dir): @@ -977,7 +977,7 @@ class SGEControllerLauncher(SGELauncher): default_template= Unicode(u"""#$ -V #$ -S /bin/sh #$ -N ipcontroller -%s --log-to-file --profile_dir={profile_dir} +%s --log-to-file --profile-dir={profile_dir} """%(' '.join(ipcontroller_cmd_argv))) def start(self, profile_dir): @@ -992,7 +992,7 @@ class SGEEngineSetLauncher(SGELauncher): default_template = Unicode("""#$ -V #$ -S /bin/sh #$ -N ipengine -%s --profile_dir={profile_dir} +%s --profile-dir={profile_dir} """%(' '.join(ipengine_cmd_argv))) def start(self, n, profile_dir): @@ -1012,7 +1012,7 @@ class IPClusterLauncher(LocalProcessLauncher): ipcluster_cmd = List(ipcluster_cmd_argv, config=True, help="Popen command for ipcluster") ipcluster_args = List( - ['--clean-logs', '--log-to-file', '--log_level=%i'%logging.INFO], config=True, + ['--clean-logs', '--log-to-file', '--log-level=%i'%logging.INFO], config=True, help="Command line arguments to pass to ipcluster.") ipcluster_subcommand = Unicode('start') ipcluster_n = Int(2) diff --git a/IPython/parallel/tests/__init__.py b/IPython/parallel/tests/__init__.py index fe635d2..a38ffd6 100644 --- a/IPython/parallel/tests/__init__.py +++ b/IPython/parallel/tests/__init__.py @@ -55,7 +55,7 @@ def setup(): cp = TestProcessLauncher() cp.cmd_and_args = ipcontroller_cmd_argv + \ - ['--profile=iptest', '--log_level=50'] + ['--profile=iptest', '--log-level=50'] cp.start() launchers.append(cp) tic = time.time() @@ -74,7 +74,7 @@ def add_engines(n=1, profile='iptest'): eps = [] for i in range(n): ep = TestProcessLauncher() - ep.cmd_and_args = ipengine_cmd_argv + ['--profile=%s'%profile, '--log_level=50'] + ep.cmd_and_args = ipengine_cmd_argv + ['--profile=%s'%profile, '--log-level=50'] ep.start() launchers.append(ep) eps.append(ep) diff --git a/IPython/testing/tools.py b/IPython/testing/tools.py index 1f151fa..01882a9 100644 --- a/IPython/testing/tools.py +++ b/IPython/testing/tools.py @@ -32,6 +32,8 @@ import os import re import sys +from contextlib import contextmanager + try: # These tools are used by parts of the runtime, so we make the nose # dependency optional at this point. Nose is a hard dependency to run the @@ -307,3 +309,13 @@ def check_pairs(func, pairs): for inp, expected in pairs: out = func(inp) assert out == expected, pair_fail_msg.format(func.func_name, inp, expected, out) + +@contextmanager +def mute_warn(): + from IPython.utils import warn + save_warn = warn.warn + warn.warn = lambda *a, **kw: None + try: + yield + finally: + warn.warn = save_warn \ No newline at end of file