Skip to content

Conversation

@greenmoon55
Copy link
Contributor

Fixes #84

Copy link
Collaborator

@dbieber dbieber left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great, I wish I'd noticed your pull request sooner. 2 comments inline.

fire/core.py Outdated
arg_consumed = True
else:
unconsumed_named_args.append(argument)
arg_consumed = True
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove arg_consumed altogether (here and at 698), and replace the if at 739 with an else.

fn_keywords: The argument name for **kwargs, or None if **kwargs not used
Returns:
kwargs: A dictionary mapping keywords to values.
remaining_args: A list of the unused arguments from the original args.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Please update the Returns: section of the docstring.
  • Also how about "remaining_kwargs" instead of unconsumed_named_args for consistency with the existing terminology?

@greenmoon55
Copy link
Contributor Author

Thanks! I'll look into it.

@dbieber
Copy link
Collaborator

dbieber commented Nov 27, 2017

Heads up that some of the tests are failing. You can see the details here (https://travis-ci.org/google/python-fire/jobs/287352133) or by clicking "Details" next to the continuous-integration line after "Some checks were not successfull".

It looks like the majority of the failures are using the components tc.Kwargs or tc.MixedDefaults.

A good first place to investigate might be why this assert is failing [1] [2]:

self.assertEqual(
fire.Fire(tc.MixedDefaults,
command=['identity', '--alpha', '--beta', '10']), (True, 10))

Here's the definition of MixedDefaults:

class MixedDefaults(object):
def ten(self):
return 10
def sum(self, alpha=0, beta=0):
return alpha + 2 * beta
def identity(self, alpha, beta='0'):
return alpha, beta


For what it's worth, these components are also used in many of the failing tests:

class WithDefaults(object):
def double(self, count=0):
return 2 * count
def triple(self, count=0):
return 3 * count

class Kwargs(object):
def props(self, **kwargs):
return kwargs
def upper(self, **kwargs):
return ' '.join(sorted(kwargs.keys())).upper()
def run(self, positional, named=None, **kwargs):
return (positional, named, kwargs)

remaining_kwargs = []
remaining_args = []

if not args:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I add a return statement here because pylint complains about "Too many nested blocks (6/5)". Not sure if I should do it this way.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems ok to me.

Another possibility would be moving some of the inner blocks into their own functions, but I don't see a super clean way to do that.

@greenmoon55
Copy link
Contributor Author

@dbieber Thanks for the tip! I forgot to save the value corresponding to the keyword.

Copy link
Collaborator

@dbieber dbieber left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good!

"""Parses the list of `args` into (varargs, kwargs), remaining_args."""
kwargs, remaining_args = _ParseKeywordArgs(args, all_args, fn_spec.varkw)
kwargs, remaining_kwargs, remaining_args = \
_ParseKeywordArgs(args, all_args, fn_spec.varkw)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: for consistency w/ codebase, let's do:

kwargs, remaining_kwargs, remaining_args = _ParseKeywordArgs(
    args, all_args, fn_spec.varkw)

remaining_kwargs = []
remaining_args = []

if not args:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems ok to me.

Another possibility would be moving some of the inner blocks into their own functions, but I don't see a super clean way to do that.

fire.Fire(
tc.MixedDefaults,
command=['identity', '--alpha', 'True', '"--test"']),
(True, '--test'))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm.

self.assertEqual(
fire.Fire(tc.MixedDefaults,
command=['identity', 'True', '10']), (True, 10))

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another thing that may be worthwhile to test is the behavior in the presence of separators / chained function calls.

For example, with these components:

def example_component(arg1, kwarg2='default2'):
  def inner_component(kwarg3='default3'):
    return kwarg3
  return inner_component
def example_component(arg1, *varargs):
  def inner_component(kwarg3='default3'):
    return kwarg3
  return inner_component

What is the behavior of these calls?

fire.Fire(example_component, command=['value1', '-', '--kwarg3', 'value3']) == 'value3'
fire.Fire(example_component, command=['value1', '--kwarg3', 'value3'])

@dbieber
Copy link
Collaborator

dbieber commented Dec 4, 2017

I'm going to go ahead and squash + merge. If you're up for adding those tests and/or making the nit fix, go ahead and do so in a follow up PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants