From 48dd6623bfeb8635082cdecb0f87e75d3a9c4672 Mon Sep 17 00:00:00 2001 From: David Bieber Date: Thu, 2 Mar 2017 20:28:21 +0000 Subject: [PATCH] Updates documentation and fixes example CLI main syntax. Copybara generated commit for Python Fire. PiperOrigin-RevId: 149033447 Change-Id: I0a9b2efbf6d8fb5436c3cca419d01bee376079be Reviewed-on: https://team-review.git.corp.google.com/63542 Reviewed-by: David Bieber --- doc/using-cli.md | 47 +++++++++++++++++++----------------- examples/cipher/cipher.py | 2 +- examples/diff/diff.py | 2 +- examples/diff/difffull.py | 2 +- examples/widget/collector.py | 2 +- examples/widget/widget.py | 2 +- fire/interact.py | 10 ++++---- fire/interact_test.py | 17 ++++++------- 8 files changed, 43 insertions(+), 41 deletions(-) diff --git a/doc/using-cli.md b/doc/using-cli.md index fb1f61c2..ab4050bc 100644 --- a/doc/using-cli.md +++ b/doc/using-cli.md @@ -4,23 +4,25 @@ ## Basic usage -Every Fire command (even just running your Fire CLI with no arguments) always -corresponds to a Python component. +Every Fire command corresponds to a Python component. -This can be any Python component, e.g. an object, a function, a class, or a -module. To see what Python component a Fire command corresponds to, append -`-- --help` to the command. For example, to see what Python component the -command `widget whack` corresponds to, run `widget whack -- --help`. To see what -Python component the command `widget whack 5` corresponds to, run -`widget whack 5 -- --help`. To see what Python component the command `widget` -corresponds to, run `widget -- --help`. +The simplest Fire command consists of running your program with no additional +arguments. This command corresponds to the Python component you called the +`Fire` function on. If you did not supply an object in the call to `Fire`, then +the context in which `Fire` was called will be used as the Python component. -When you first go to use a Fire CLI you're unfamiliar with, let's say it is -called `widget`, start by seeing what Python component the command corresponds -to without any arguments, by calling `widget -- --help`. +You can append `-- --help` to any command to see what Python component it +corresponds to, as well as the various ways in which you can extend the command. +Flags are always separated from the Fire command by an isolated `--` in order +to distinguish between flags and named arguments. + +Given a Fire command that corresponds to a Python object, you can extend that +command to access a member of that object, call it with arguments if it is a +function, instantiate it if it is a class, or index into it if it is a list. + +Read on to learn about how you can write a Fire command corresponding to +whatever Python component you're looking for. -The following sections discuss how you can write a Fire command corresponding -to whatever Python component you're looking for. ### Accessing members of an object @@ -37,14 +39,15 @@ named high_score, then you can add the argument 'high-score' to your command, and the resulting new command corresponds to the value of the high_score property. + ### Accessing members of a dict If your command corresponds to a dict, you can extend your command by adding the name of one of the dict's keys as an argument. -For example, `widget function-that-returns-dict key` will correspond to the -value of the item with key "key" in the dict returned by -function_that_returns_dict. +For example, `widget function-that-returns-dict key` will correspond to the +value of the item with key `key` in the dict returned by +`function_that_returns_dict`. ### Accessing members of a list or tuple @@ -77,8 +80,8 @@ You can force a function that takes a variable number of arguments to be evaluated by adding a separator (the default separator is the hyphen, "-"). This will prevent arguments to the right of the separator from being consumed for calling the function. This is useful if the function has arguments with default -values, or if the function accepts *varargs, or if the function accepts -**kwargs. +values, or if the function accepts \*varargs, or if the function accepts +\*\*kwargs. See also the section on [Changing the Separator](#separator-flag). @@ -86,9 +89,9 @@ See also the section on [Changing the Separator](#separator-flag). ### Instantiating a class If your command corresponds to a class, you can extend your command by adding -the arguments of the class's __init__ function. Arguments can be specified -positionally, or by name. To specify an argument by name, use flag syntax. See -the section on [calling a function](#calling-a-function) for more details. +the arguments of the class's \_\_init\_\_ function. Arguments must be specified +by name, using the flags syntax. See the section on +[calling a function](#calling-a-function) for more details. ## Using Flags with Fire CLIs diff --git a/examples/cipher/cipher.py b/examples/cipher/cipher.py index c374a353..26a07756 100644 --- a/examples/cipher/cipher.py +++ b/examples/cipher/cipher.py @@ -52,7 +52,7 @@ def _caesar_shift_char(n=0, char=' '): return chr((ord(char) - ord('a') + n) % 26 + ord('a')) -def main() +def main(): fire.Fire(name='cipher') if __name__ == '__main__': diff --git a/examples/diff/diff.py b/examples/diff/diff.py index 0693b424..be5b8dab 100644 --- a/examples/diff/diff.py +++ b/examples/diff/diff.py @@ -96,7 +96,7 @@ def context_diff(self, lines=3): self._tofile, self.fromdate, self.todate, n=lines) -def main() +def main(): fire.Fire(DiffLibWrapper, name='diff') if __name__ == '__main__': diff --git a/examples/diff/difffull.py b/examples/diff/difffull.py index 301c214c..38918dee 100644 --- a/examples/diff/difffull.py +++ b/examples/diff/difffull.py @@ -44,7 +44,7 @@ import fire -def main() +def main(): fire.Fire(difflib, name='difffull') if __name__ == '__main__': diff --git a/examples/widget/collector.py b/examples/widget/collector.py index f9e39e2e..8886bb9d 100644 --- a/examples/widget/collector.py +++ b/examples/widget/collector.py @@ -31,7 +31,7 @@ def collect_widgets(self): return [widget.Widget() for _ in xrange(self.desired_widget_count)] -def main() +def main(): fire.Fire(Collector(), name='collector') if __name__ == '__main__': diff --git a/examples/widget/widget.py b/examples/widget/widget.py index 630cbac0..4fd28fc5 100644 --- a/examples/widget/widget.py +++ b/examples/widget/widget.py @@ -28,7 +28,7 @@ def bang(self, noise='bang'): return '{noise} bang!'.format(noise=noise) -def main() +def main(): fire.Fire(Widget(), name='widget') if __name__ == '__main__': diff --git a/fire/interact.py b/fire/interact.py index 729ebffa..4f470dca 100644 --- a/fire/interact.py +++ b/fire/interact.py @@ -74,16 +74,16 @@ def _AvailableString(variables, verbose=False): ).format(liststrs='\n'.join(liststrs)) -def _EmbedIPython(variables): - """Drops into an IPython REPL with variables available as local variables. +def _EmbedIPython(variables, argv=None): + """Drops into an IPython REPL with variables available for use. Args: variables: A dict of variables to make available. Keys are variable names. Values are variable values. + argv: The argv to use for starting ipython. Defaults to an empty list. """ - lcl = locals() - lcl.update(**variables) - IPython.embed() + argv = argv or [] + IPython.start_ipython(argv=argv, user_ns=variables) def _EmbedCode(variables): diff --git a/fire/interact_test.py b/fire/interact_test.py index f22b94d6..9a2871a8 100644 --- a/fire/interact_test.py +++ b/fire/interact_test.py @@ -24,21 +24,20 @@ class InteractTest(unittest.TestCase): - @mock.patch('IPython.embed') - def testInteract(self, mock_embed): - self.assertFalse(mock_embed.called) + @mock.patch('IPython.start_ipython') + def testInteract(self, mock_ipython): + self.assertFalse(mock_ipython.called) interact.Embed({}) - self.assertTrue(mock_embed.called) + self.assertTrue(mock_ipython.called) - @mock.patch('IPython.embed') - def testInteractVariables(self, mock_embed): - self.assertFalse(mock_embed.called) + @mock.patch('IPython.start_ipython') + def testInteractVariables(self, mock_ipython): + self.assertFalse(mock_ipython.called) interact.Embed({ 'count': 10, 'mock': mock, }) - self.assertTrue(mock_embed.called) - + self.assertTrue(mock_ipython.called) if __name__ == '__main__': unittest.main()