diff --git a/IPython/config/loader.py b/IPython/config/loader.py index a3bdb2e..f37e725 100644 --- a/IPython/config/loader.py +++ b/IPython/config/loader.py @@ -325,15 +325,15 @@ class CommandLineConfigLoader(ConfigLoader): here. """ -kv_pattern = re.compile(r'[A-Za-z]\w*(\.\w+)*\=.*') -flag_pattern = re.compile(r'\w+(\-\w)*') +kv_pattern = re.compile(r'\-\-[A-Za-z]\w*(\.\w+)*\=.*') +flag_pattern = re.compile(r'\-\-?\w+[\-\w]*$') class KeyValueConfigLoader(CommandLineConfigLoader): """A config loader that loads key value pairs from the command line. This allows command line options to be gives in the following form:: - ipython Global.profile="foo" InteractiveShell.autocall=False + ipython --profile="foo" --InteractiveShell.autocall=False """ def __init__(self, argv=None, aliases=None, flags=None): @@ -364,7 +364,7 @@ class KeyValueConfigLoader(CommandLineConfigLoader): >>> from IPython.config.loader import KeyValueConfigLoader >>> cl = KeyValueConfigLoader() - >>> cl.load_config(["foo='bar'","A.name='brian'","B.number=0"]) + >>> cl.load_config(["--foo='bar'","--A.name='brian'","--B.number=0"]) {'A': {'name': 'brian'}, 'B': {'number': 0}, 'foo': 'bar'} """ self.clear() @@ -437,7 +437,7 @@ class KeyValueConfigLoader(CommandLineConfigLoader): self.extra_args.extend(uargv[idx+1:]) break - if kv_pattern.match(item): + if kv_pattern.match(raw): lhs,rhs = item.split('=',1) # Substitute longnames for aliases. if lhs in aliases: @@ -455,17 +455,24 @@ class KeyValueConfigLoader(CommandLineConfigLoader): # it succeeds. If it still fails, we let it raise. exec_str = u'self.config.' + lhs + '=' + repr(rhs) exec exec_str in locals(), globals() - elif item in flags: - cfg,help = flags[item] - if isinstance(cfg, (dict, Config)): - # don't clobber whole config sections, update - # each section from config: - for sec,c in cfg.iteritems(): - self.config[sec].update(c) + elif flag_pattern.match(raw): + if item in flags: + cfg,help = flags[item] + if isinstance(cfg, (dict, Config)): + # don't clobber whole config sections, update + # each section from config: + for sec,c in cfg.iteritems(): + self.config[sec].update(c) + else: + raise ValueError("Invalid flag: '%s'"%raw) else: - raise ValueError("Invalid flag: '%s'"%raw) + raise ArgumentError("Unrecognized flag: '%s'"%raw) elif raw.startswith('-'): - raise ArgumentError("invalid argument: '%s'"%raw) + kv = '--'+item + if kv_pattern.match(kv): + raise ArgumentError("Invalid argument: '%s', did you mean '%s'?"%(raw, kv)) + else: + raise ArgumentError("Invalid argument: '%s'"%raw) else: # keep all args that aren't valid in a list, # in case our parent knows what to do with them. diff --git a/IPython/config/tests/test_application.py b/IPython/config/tests/test_application.py index e75a47b..d74c17d 100644 --- a/IPython/config/tests/test_application.py +++ b/IPython/config/tests/test_application.py @@ -79,7 +79,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 +88,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) @@ -97,7 +97,7 @@ class TestApplication(TestCase): def test_flags(self): app = MyApp() - app.parse_command_line(["-disable"]) + app.parse_command_line(["--disable"]) app.init_bar() self.assertEquals(app.bar.enabled, False) app.parse_command_line(["--enable"]) @@ -106,7 +106,7 @@ class TestApplication(TestCase): def test_aliases(self): app = MyApp() - app.parse_command_line(["i=5", "j=10"]) + app.parse_command_line(["--i=5", "--j=10"]) app.init_foo() self.assertEquals(app.foo.i, 5) app.init_foo() @@ -115,18 +115,18 @@ class TestApplication(TestCase): def test_flag_clobber(self): """test that setting flags doesn't clobber existing settings""" app = MyApp() - app.parse_command_line(["Bar.b=5", "--disable"]) + app.parse_command_line(["--Bar.b=5", "--disable"]) app.init_bar() self.assertEquals(app.bar.enabled, False) self.assertEquals(app.bar.b, 5) - app.parse_command_line(["--enable", "Bar.b=10"]) + app.parse_command_line(["--enable", "--Bar.b=10"]) app.init_bar() self.assertEquals(app.bar.enabled, True) self.assertEquals(app.bar.b, 10) def test_extra_args(self): app = MyApp() - app.parse_command_line(["Bar.b=5", 'extra', "--disable", 'args']) + app.parse_command_line(["--Bar.b=5", 'extra', "--disable", 'args']) app.init_bar() self.assertEquals(app.bar.enabled, True) self.assertEquals(app.bar.b, 5) diff --git a/IPython/config/tests/test_loader.py b/IPython/config/tests/test_loader.py index 1995933..6d9ad69 100755 --- a/IPython/config/tests/test_loader.py +++ b/IPython/config/tests/test_loader.py @@ -119,7 +119,7 @@ class TestKeyValueCL(TestCase): def test_basic(self): cl = KeyValueConfigLoader() - argv = [s.strip('c.') for s in pyfile.split('\n')[2:-1]] + argv = ['--'+s.strip('c.') for s in pyfile.split('\n')[2:-1]] config = cl.load_config(argv) self.assertEquals(config.a, 10) self.assertEquals(config.b, 20) @@ -129,21 +129,21 @@ class TestKeyValueCL(TestCase): def test_extra_args(self): cl = KeyValueConfigLoader() - config = cl.load_config(['a=5', 'b', 'c=10', 'd']) - self.assertEquals(cl.extra_args, ['b', 'c=10' , 'd']) + config = cl.load_config(['--a=5', 'b', '--c=10', 'd']) + self.assertEquals(cl.extra_args, ['b', '--c=10' , 'd']) self.assertEquals(config.a, 5) self.assertRaises(AttributeError, getattr, config, 'c') - config = cl.load_config(['--', 'a=5', 'c=10']) - self.assertEquals(cl.extra_args, ['a=5', 'c=10']) + 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'] + argv = [u'--a=épsîlön'] config = cl.load_config(argv) self.assertEquals(config.a, u'épsîlön') def test_unicode_bytes_args(self): - uarg = u'a=é' + uarg = u'--a=é' try: barg = uarg.encode(sys.stdin.encoding) except (TypeError, UnicodeEncodeError): diff --git a/IPython/frontend/qt/console/qtconsoleapp.py b/IPython/frontend/qt/console/qtconsoleapp.py index 2d67b83..dcf7fd6 100644 --- a/IPython/frontend/qt/console/qtconsoleapp.py +++ b/IPython/frontend/qt/console/qtconsoleapp.py @@ -293,10 +293,10 @@ class IPythonQtConsoleApp(BaseIPythonApplication): self.kernel_argv = list(argv) # copy # kernel should inherit default config file from frontend - self.kernel_argv.append("KernelApp.parent_appname='%s'"%self.name) + self.kernel_argv.append("--KernelApp.parent_appname='%s'"%self.name) # scrub frontend-specific flags for a in argv: - if a.startswith('--') and a[2:] in qt_flags: + if a.startswith('-') and a.lstrip('-') in qt_flags: self.kernel_argv.remove(a) def init_kernel_manager(self): diff --git a/IPython/frontend/terminal/ipapp.py b/IPython/frontend/terminal/ipapp.py index 65459b3..2c37b4d 100755 --- a/IPython/frontend/terminal/ipapp.py +++ b/IPython/frontend/terminal/ipapp.py @@ -146,7 +146,8 @@ flags['quick']=( flags['i'] = ( {'TerminalIPythonApp' : {'force_interact' : True}}, - "If running code from the command line, become interactive afterwards." + """also works as '-i' + If running code from the command line, become interactive afterwards.""" ) flags['pylab'] = ( {'TerminalIPythonApp' : {'pylab' : 'auto'}}, diff --git a/IPython/lib/irunner.py b/IPython/lib/irunner.py index ac652e5..e90edfc 100755 --- a/IPython/lib/irunner.py +++ b/IPython/lib/irunner.py @@ -304,7 +304,7 @@ class IPythonRunner(InteractiveRunner): def __init__(self,program = 'ipython',args=None,out=sys.stdout,echo=True): """New runner, optionally passing the ipython command to use.""" - args0 = ['colors=NoColor', + args0 = ['--colors=NoColor', '--no-term-title', '--no-autoindent'] if args is None: args = args0 diff --git a/IPython/parallel/apps/launcher.py b/IPython/parallel/apps/launcher.py index 2f1ab7a..a46b81f 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,20 +468,20 @@ 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) def find_args(self): - return self.mpi_cmd + ['-n', self.n] + self.mpi_args + \ + return self.mpi_cmd + ['-n', str(self.n)] + self.mpi_args + \ self.controller_cmd + self.controller_args @@ -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,14 +1012,14 @@ 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) def find_args(self): - return self.ipcluster_cmd + ['--'+self.ipcluster_subcommand] + \ - ['n=%i'%self.ipcluster_n] + self.ipcluster_args + return self.ipcluster_cmd + [self.ipcluster_subcommand] + \ + ['--n=%i'%self.ipcluster_n] + self.ipcluster_args def start(self): self.log.info("Starting ipcluster: %r" % self.args) diff --git a/IPython/parallel/tests/__init__.py b/IPython/parallel/tests/__init__.py index 3e740f9..fe635d2 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 0de7f4f..1f151fa 100644 --- a/IPython/testing/tools.py +++ b/IPython/testing/tools.py @@ -158,8 +158,8 @@ def default_argv(): return ['--quick', # so no config file is loaded # Other defaults to minimize side effects on stdout - 'colors=NoColor', '--no-term-title','--no-banner', - 'autocall=0'] + '--colors=NoColor', '--no-term-title','--no-banner', + '--autocall=0'] def default_config(): @@ -197,9 +197,9 @@ def ipexec(fname, options=None): # For these subprocess calls, eliminate all prompt printing so we only see # output from script execution - prompt_opts = [ 'InteractiveShell.prompt_in1=""', - 'InteractiveShell.prompt_in2=""', - 'InteractiveShell.prompt_out=""' + prompt_opts = [ '--InteractiveShell.prompt_in1=""', + '--InteractiveShell.prompt_in2=""', + '--InteractiveShell.prompt_out=""' ] cmdargs = ' '.join(default_argv() + prompt_opts + options) diff --git a/IPython/zmq/entry_point.py b/IPython/zmq/entry_point.py index b4eaf2b..5811ff0 100644 --- a/IPython/zmq/entry_point.py +++ b/IPython/zmq/entry_point.py @@ -83,19 +83,19 @@ def base_launch_kernel(code, shell_port=0, iopub_port=0, stdin_port=0, hb_port=0 # Build the kernel launch command. if executable is None: executable = sys.executable - arguments = [ executable, '-c', code, 'shell=%i'%shell_port, - 'iopub=%i'%iopub_port, 'stdin=%i'%stdin_port, - 'hb=%i'%hb_port + arguments = [ executable, '-c', code, '--shell=%i'%shell_port, + '--iopub=%i'%iopub_port, '--stdin=%i'%stdin_port, + '--hb=%i'%hb_port ] if ip is not None: - arguments.append('ip=%s'%ip) + arguments.append('--ip=%s'%ip) arguments.extend(extra_arguments) # Spawn a kernel. if sys.platform == 'win32': # Create a Win32 event for interrupting the kernel. interrupt_event = ParentPollerWindows.create_interrupt_event() - arguments += [ 'interrupt=%i'%interrupt_event ] + arguments += [ '--interrupt=%i'%interrupt_event ] # If this process in running on pythonw, stdin, stdout, and stderr are # invalid. Popen will fail unless they are suitably redirected. We don't @@ -133,7 +133,7 @@ def base_launch_kernel(code, shell_port=0, iopub_port=0, stdin_port=0, hb_port=0 handle = DuplicateHandle(pid, pid, pid, 0, True, # Inheritable by new processes. DUPLICATE_SAME_ACCESS) - proc = Popen(arguments + ['parent=%i'%int(handle)], + proc = Popen(arguments + ['--parent=%i'%int(handle)], stdin=_stdin, stdout=_stdout, stderr=_stderr) # Attach the interrupt event to the Popen objet so it can be used later. @@ -153,7 +153,6 @@ def base_launch_kernel(code, shell_port=0, iopub_port=0, stdin_port=0, hb_port=0 proc = Popen(arguments, preexec_fn=lambda: os.setsid(), stdin=stdin, stdout=stdout, stderr=stderr) else: - proc = Popen(arguments + ['parent=1'], + proc = Popen(arguments + ['--parent=1'], stdin=stdin, stdout=stdout, stderr=stderr) - return proc, shell_port, iopub_port, stdin_port, hb_port diff --git a/IPython/zmq/kernelapp.py b/IPython/zmq/kernelapp.py index f748ddc..c8a155b 100644 --- a/IPython/zmq/kernelapp.py +++ b/IPython/zmq/kernelapp.py @@ -166,7 +166,7 @@ class KernelApp(BaseIPythonApplication): # single-port connection negotiation fully implemented. # set log-level to critical, to make sure it is output self.log.critical("To connect another client to this kernel, use:") - self.log.critical("--existing shell={0} iopub={1} stdin={2} hb={3}".format( + self.log.critical("--existing --shell={0} --iopub={1} --stdin={2} --hb={3}".format( self.shell_port, self.iopub_port, self.stdin_port, self.hb_port))