Show More
@@ -49,21 +49,19 b" Flags are command-line arguments passed as '--<flag>'." | |||
|
49 | 49 | These take no parameters, unlike regular key-value arguments. |
|
50 | 50 | They are typically used for setting boolean flags, or enabling |
|
51 | 51 | modes that involve setting multiple options together. |
|
52 | ||
|
53 | Flags *always* begin with '--', never just one '-'. | |
|
54 | 52 | """.strip() # trim newlines of front and back |
|
55 | 53 | |
|
56 | 54 | alias_description = """ |
|
57 | 55 | These are commonly set parameters, given abbreviated aliases for convenience. |
|
58 | They are set in the same `name=value` way as class parameters, where | |
|
56 | They are set in the same `--name=value` way as class parameters, where | |
|
59 | 57 | <name> is replaced by the real parameter for which it is an alias. |
|
60 | 58 | """.strip() # trim newlines of front and back |
|
61 | 59 | |
|
62 | 60 | keyvalue_description = """ |
|
63 | 61 | Parameters are set from command-line arguments of the form: |
|
64 | `Class.trait=value`. Parameters will *never* be prefixed with '-'. | |
|
62 | `--Class.trait=value`. | |
|
65 | 63 | This line is evaluated in Python, so simple expressions are allowed, e.g. |
|
66 | `C.a='range(3)'` For setting C.a=[0,1,2] | |
|
64 | `--C.a='range(3)'` For setting C.a=[0,1,2] | |
|
67 | 65 | """.strip() # trim newlines of front and back |
|
68 | 66 | |
|
69 | 67 | #----------------------------------------------------------------------------- |
@@ -210,11 +208,12 b' class Application(SingletonConfigurable):' | |||
|
210 | 208 | cls = classdict[classname] |
|
211 | 209 | |
|
212 | 210 | trait = cls.class_traits(config=True)[traitname] |
|
213 | help = cls.class_get_trait_help(trait) | |
|
214 | help = help.replace(longname, "%s (%s)"%(alias, longname), 1) | |
|
215 | lines.append(help) | |
|
211 | help = cls.class_get_trait_help(trait).splitlines() | |
|
212 | # reformat first line | |
|
213 | help[0] = help[0].replace(longname, alias) + ' (%s)'%longname | |
|
214 | lines.extend(help) | |
|
216 | 215 | lines.append('') |
|
217 |
print |
|
|
216 | print os.linesep.join(lines) | |
|
218 | 217 | |
|
219 | 218 | def print_flag_help(self): |
|
220 | 219 | """Print the flag part of the help.""" |
@@ -155,7 +155,7 b' class Configurable(HasTraits):' | |||
|
155 | 155 | def class_get_trait_help(cls, trait): |
|
156 | 156 | """Get the help string for a single trait.""" |
|
157 | 157 | lines = [] |
|
158 |
header = "%s.%s |
|
|
158 | header = "--%s.%s=<%s>" % (cls.__name__, trait.name, trait.__class__.__name__) | |
|
159 | 159 | lines.append(header) |
|
160 | 160 | try: |
|
161 | 161 | dvr = repr(trait.get_default_value()) |
@@ -326,7 +326,7 b' class CommandLineConfigLoader(ConfigLoader):' | |||
|
326 | 326 | """ |
|
327 | 327 | |
|
328 | 328 | kv_pattern = re.compile(r'[A-Za-z]\w*(\.\w+)*\=.*') |
|
329 |
flag_pattern = re.compile(r'\ |
|
|
329 | flag_pattern = re.compile(r'\w+(\-\w)*') | |
|
330 | 330 | |
|
331 | 331 | class KeyValueConfigLoader(CommandLineConfigLoader): |
|
332 | 332 | """A config loader that loads key value pairs from the command line. |
@@ -426,7 +426,17 b' class KeyValueConfigLoader(CommandLineConfigLoader):' | |||
|
426 | 426 | if flags is None: |
|
427 | 427 | flags = self.flags |
|
428 | 428 | |
|
429 | for item in self._decode_argv(argv): | |
|
429 | # ensure argv is a list of unicode strings: | |
|
430 | uargv = self._decode_argv(argv) | |
|
431 | for idx,raw in enumerate(uargv): | |
|
432 | # strip leading '-' | |
|
433 | item = raw.lstrip('-') | |
|
434 | ||
|
435 | if raw == '--': | |
|
436 | # don't parse arguments after '--' | |
|
437 | self.extra_args.extend(uargv[idx+1:]) | |
|
438 | break | |
|
439 | ||
|
430 | 440 | if kv_pattern.match(item): |
|
431 | 441 | lhs,rhs = item.split('=',1) |
|
432 | 442 | # Substitute longnames for aliases. |
@@ -445,26 +455,23 b' class KeyValueConfigLoader(CommandLineConfigLoader):' | |||
|
445 | 455 | # it succeeds. If it still fails, we let it raise. |
|
446 | 456 | exec_str = u'self.config.' + lhs + '=' + repr(rhs) |
|
447 | 457 | exec exec_str in locals(), globals() |
|
448 |
elif |
|
|
449 | # trim leading '--' | |
|
450 | m = item[2:] | |
|
451 | cfg,_ = flags.get(m, (None,None)) | |
|
452 | if cfg is None: | |
|
453 | raise ArgumentError("Unrecognized flag: %r"%item) | |
|
454 | elif isinstance(cfg, (dict, Config)): | |
|
458 | elif item in flags: | |
|
459 | cfg,help = flags[item] | |
|
460 | if isinstance(cfg, (dict, Config)): | |
|
455 | 461 | # don't clobber whole config sections, update |
|
456 | 462 | # each section from config: |
|
457 | 463 | for sec,c in cfg.iteritems(): |
|
458 | 464 | self.config[sec].update(c) |
|
459 | 465 | else: |
|
460 |
raise ValueError("Invalid flag: |
|
|
461 |
elif |
|
|
462 | # this shouldn't ever be valid | |
|
463 | raise ArgumentError("Invalid argument: %r"%item) | |
|
466 | raise ValueError("Invalid flag: '%s'"%raw) | |
|
467 | elif raw.startswith('-'): | |
|
468 | raise ArgumentError("invalid argument: '%s'"%raw) | |
|
464 | 469 | else: |
|
465 | 470 | # keep all args that aren't valid in a list, |
|
466 | 471 | # in case our parent knows what to do with them. |
|
467 | self.extra_args.append(item) | |
|
472 | # self.extra_args.append(item) | |
|
473 | self.extra_args.extend(uargv[idx:]) | |
|
474 | break | |
|
468 | 475 | return self.config |
|
469 | 476 | |
|
470 | 477 | class ArgParseConfigLoader(CommandLineConfigLoader): |
@@ -79,7 +79,7 b' class TestApplication(TestCase):' | |||
|
79 | 79 | |
|
80 | 80 | def test_config(self): |
|
81 | 81 | app = MyApp() |
|
82 | app.parse_command_line(["i=10","Foo.j=10","enabled=False","log_level=50"]) | |
|
82 | app.parse_command_line(["--i=10","Foo.j=10","--enabled=False","-log_level=50"]) | |
|
83 | 83 | config = app.config |
|
84 | 84 | self.assertEquals(config.Foo.i, 10) |
|
85 | 85 | self.assertEquals(config.Foo.j, 10) |
@@ -88,7 +88,7 b' class TestApplication(TestCase):' | |||
|
88 | 88 | |
|
89 | 89 | def test_config_propagation(self): |
|
90 | 90 | app = MyApp() |
|
91 | app.parse_command_line(["i=10","Foo.j=10","enabled=False","log_level=50"]) | |
|
91 | app.parse_command_line(["i=10","--Foo.j=10","enabled=False","log_level=50"]) | |
|
92 | 92 | app.init_foo() |
|
93 | 93 | app.init_bar() |
|
94 | 94 | self.assertEquals(app.foo.i, 10) |
@@ -97,7 +97,7 b' class TestApplication(TestCase):' | |||
|
97 | 97 | |
|
98 | 98 | def test_flags(self): |
|
99 | 99 | app = MyApp() |
|
100 |
app.parse_command_line([" |
|
|
100 | app.parse_command_line(["-disable"]) | |
|
101 | 101 | app.init_bar() |
|
102 | 102 | self.assertEquals(app.bar.enabled, False) |
|
103 | 103 | app.parse_command_line(["--enable"]) |
@@ -126,10 +126,10 b' class TestApplication(TestCase):' | |||
|
126 | 126 | |
|
127 | 127 | def test_extra_args(self): |
|
128 | 128 | app = MyApp() |
|
129 |
app.parse_command_line(['extra' |
|
|
129 | app.parse_command_line(["Bar.b=5", 'extra', "--disable", 'args']) | |
|
130 | 130 | app.init_bar() |
|
131 |
self.assertEquals(app.bar.enabled, |
|
|
131 | self.assertEquals(app.bar.enabled, True) | |
|
132 | 132 | self.assertEquals(app.bar.b, 5) |
|
133 | self.assertEquals(app.extra_args, ['extra', 'args']) | |
|
133 | self.assertEquals(app.extra_args, ['extra', "--disable", 'args']) | |
|
134 | 134 | |
|
135 | 135 |
@@ -47,10 +47,10 b' class MyConfigurable(Configurable):' | |||
|
47 | 47 | |
|
48 | 48 | mc_help=u"""MyConfigurable options |
|
49 | 49 | ---------------------- |
|
50 |
MyConfigurable.a |
|
|
50 | --MyConfigurable.a=<Int> | |
|
51 | 51 | Default: 1 |
|
52 | 52 | The integer a. |
|
53 |
MyConfigurable.b |
|
|
53 | --MyConfigurable.b=<Float> | |
|
54 | 54 | Default: 1.0 |
|
55 | 55 | The integer b.""" |
|
56 | 56 |
@@ -130,9 +130,11 b' class TestKeyValueCL(TestCase):' | |||
|
130 | 130 | def test_extra_args(self): |
|
131 | 131 | cl = KeyValueConfigLoader() |
|
132 | 132 | config = cl.load_config(['a=5', 'b', 'c=10', 'd']) |
|
133 | self.assertEquals(cl.extra_args, ['b', 'd']) | |
|
133 | self.assertEquals(cl.extra_args, ['b', 'c=10' , 'd']) | |
|
134 | 134 | self.assertEquals(config.a, 5) |
|
135 |
self.assert |
|
|
135 | self.assertRaises(AttributeError, getattr, config, 'c') | |
|
136 | config = cl.load_config(['--', 'a=5', 'c=10']) | |
|
137 | self.assertEquals(cl.extra_args, ['a=5', 'c=10']) | |
|
136 | 138 | |
|
137 | 139 | def test_unicode_args(self): |
|
138 | 140 | cl = KeyValueConfigLoader() |
@@ -93,7 +93,7 b' shell_aliases = dict(' | |||
|
93 | 93 | cache_size='InteractiveShell.cache_size', |
|
94 | 94 | colors='InteractiveShell.colors', |
|
95 | 95 | logfile='InteractiveShell.logfile', |
|
96 |
log |
|
|
96 | logappend='InteractiveShell.logappend', | |
|
97 | 97 | c='InteractiveShellApp.code_to_run', |
|
98 | 98 | ext='InteractiveShellApp.extra_extension', |
|
99 | 99 | ) |
@@ -188,6 +188,11 b' class InteractiveShellApp(Configurable):' | |||
|
188 | 188 | |
|
189 | 189 | def _exec_file(self, fname): |
|
190 | 190 | full_filename = filefind(fname, [u'.', self.ipython_dir]) |
|
191 | # Make sure that the running script gets a proper sys.argv as if it | |
|
192 | # were run from a system shell. | |
|
193 | save_argv = sys.argv | |
|
194 | sys.argv = sys.argv[sys.argv.index(fname):] | |
|
195 | try: | |
|
191 | 196 | if os.path.isfile(full_filename): |
|
192 | 197 | if full_filename.endswith('.ipy'): |
|
193 | 198 | self.log.info("Running file in user namespace: %s" % |
@@ -203,6 +208,8 b' class InteractiveShellApp(Configurable):' | |||
|
203 | 208 | self.shell.safe_execfile(full_filename, self.shell.user_ns) |
|
204 | 209 | finally: |
|
205 | 210 | del self.shell.user_ns['__file__'] |
|
211 | finally: | |
|
212 | sys.argv = save_argv | |
|
206 | 213 | |
|
207 | 214 | def _run_exec_files(self): |
|
208 | 215 | """Run files from IPythonApp.exec_files""" |
General Comments 0
You need to be logged in to leave comments.
Login now