Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support passing variable number of arguments to resolvers. #46

Merged
merged 1 commit into from
Oct 24, 2019

Conversation

swist
Copy link
Contributor

@swist swist commented Oct 23, 2019

This PR adds the ability to pass in 0 or more arguments to resolvers:

${foo:}               # zero arguments
${foo:a}              # one argument (currently supported)
${foo:a,b,..,n}       # n arguments

@swist
Copy link
Contributor Author

swist commented Oct 23, 2019

BTW when do you plan to publish a new version to pypi? Would be nice to not have to run my fork

@coveralls
Copy link

coveralls commented Oct 23, 2019

Pull Request Test Coverage Report for Build 245

  • 15 of 15 (100.0%) changed or added relevant lines in 2 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.1%) to 99.262%

Totals Coverage Status
Change from base Build 233: 0.1%
Covered Lines: 2421
Relevant Lines: 2439

💛 - Coveralls

@omry
Copy link
Owner

omry commented Oct 23, 2019

I am planning to make a pass at the open issues first.
It may take a few months as I am still heavily focused on Hydra and also got a bunch of travel coming in the following months.

In the mean time, you can install from master by putting something like this in your setup.py:
(Or probably also instructing pip to install this directly).

        install_requires=[
            "omegaconf@git+ssh://[email protected]/omry/omegaconf.git@master",
        ],

@omry
Copy link
Owner

omry commented Oct 23, 2019

What do you think about extending the resolver to properly accept multiple arguments instead?
Allowing any argument like this will deny the possibility of cleanly doing it in the future.

tests/test_interpolation.py Outdated Show resolved Hide resolved
@swist swist force-pushed the feature/better-regex-for-custom-resolvers branch from 9430abb to 221d5c7 Compare October 23, 2019 16:38
Copy link
Owner

@omry omry left a comment

Choose a reason for hiding this comment

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

  1. Can you keep the value (new terminology: ${func:value} as a string until it's actually passed to the user's function?
    not sure if this is possible, but it feels like touches a bit too much.

  2. handle and test escaping.

  3. Update documentation.

omegaconf/config.py Outdated Show resolved Hide resolved
@swist swist force-pushed the feature/better-regex-for-custom-resolvers branch 3 times, most recently from 553d882 to a987662 Compare October 23, 2019 17:46
@swist
Copy link
Contributor Author

swist commented Oct 23, 2019

Cool, will update later tomorrow, got the tokenizer in the right place, just having some pains dealing with escaping spaces - ideally something like this would work, but no clean solution comes to mind off the top of my head

tokenize('cat dog, dog cat') == ['cat dog', 'dog cat']
tokenize('cat dog,\ dog cat') == ['cat dog', ' dog cat']

i.e. only need to escape whitespace at the "boundaries" of the word

[edit] d'oh, just realised this is what you wrote earlier

@omry
Copy link
Owner

omry commented Oct 23, 2019

Great, I will take a closer look later.
Ideally, this would be handled by a proper tokenizer like antlr, but OmegaConf does not (yet) has this dependency.
It would also be pretty involved to set this up cleanly (see http://github.com/omry/antelope for an example).

Re:

tokenize('cat dog, dog cat') == ['cat dog', 'dog cat']
tokenize('cat dog,\ dog cat') == ['cat dog', ' dog cat']

I think something like this would be a good overall strategy:

  1. split by un-escaped commas:
    'cat dog,\ dog cat' -> ['cat dog', '\ dog cat']
  2. replace ',' and '\ ' by ',' and ' '.
  3. for each element, strip whitespace for both ends.

The first part is a bit tricky, you can achieve that relatively cleanly by replacing ',' with an illegal character like *, then split by that, and then replace it back.

@swist swist force-pushed the feature/better-regex-for-custom-resolvers branch from a987662 to 658adef Compare October 23, 2019 18:37
@swist
Copy link
Contributor Author

swist commented Oct 23, 2019

Un-brainfarted myself. I think the current version makes sense. The strategy is as follows:

  1. split by unescaped commas
  2. remove unescaped whitespace at word ends for each in split
  3. unescape commas and whitespace

Also added a doc example

@swist swist force-pushed the feature/better-regex-for-custom-resolvers branch from 658adef to e96e53d Compare October 23, 2019 19:49
Copy link
Owner

@omry omry left a comment

Choose a reason for hiding this comment

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

Almost there!

omegaconf/config.py Outdated Show resolved Hide resolved
omegaconf/omegaconf.py Outdated Show resolved Hide resolved
tests/test_interpolation.py Outdated Show resolved Hide resolved
docs/source/usage.rst Outdated Show resolved Hide resolved
docs/source/usage.rst Outdated Show resolved Hide resolved
@swist swist force-pushed the feature/better-regex-for-custom-resolvers branch 4 times, most recently from b81cd62 to 79f114a Compare October 23, 2019 21:32
Copy link
Owner

@omry omry left a comment

Choose a reason for hiding this comment

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

two small comments.

docs/source/usage.rst Outdated Show resolved Hide resolved
Comment on lines +253 to +258
@pytest.mark.parametrize('resolver,name,key,result', [
(lambda *args: args, 'arg_list', "${my_resolver:cat, dog}",("cat", "dog")),
(lambda *args: args, 'escape_comma',"${my_resolver:cat\, do g}",("cat, do g",)),
(lambda *args: args, 'escape_whitespace',"${my_resolver:cat\, do g}",("cat, do g",)),
(lambda: 'zero', 'zero_arg',"${my_resolver:}",("zero")),
])
Copy link
Owner

Choose a reason for hiding this comment

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

Not familiar with this syntex. Why do you need it here?

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'm not sure what you mean? Would you prefer I passed in entire config dictionaries as opposed to pairs of key, string_to_resolve?

Copy link
Owner

Choose a reason for hiding this comment

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

oh, I was confused by the lambda being passed there, I get why you need this now.

OmegaConf's templating language allows very few characters.
There are some use cases where you'd want to have special characters
so that your custom resolver can handle resolution there (kind of like
embedding a templating language inside of OmegaConfs). This allows
such behaviour without seemingly breaking anything too majorly
@swist swist force-pushed the feature/better-regex-for-custom-resolvers branch from 79f114a to 3c053c4 Compare October 24, 2019 08:37
Comment on lines +253 to +258
@pytest.mark.parametrize('resolver,name,key,result', [
(lambda *args: args, 'arg_list', "${my_resolver:cat, dog}",("cat", "dog")),
(lambda *args: args, 'escape_comma',"${my_resolver:cat\, do g}",("cat, do g",)),
(lambda *args: args, 'escape_whitespace',"${my_resolver:cat\, do g}",("cat, do g",)),
(lambda: 'zero', 'zero_arg',"${my_resolver:}",("zero")),
])
Copy link
Owner

Choose a reason for hiding this comment

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

oh, I was confused by the lambda being passed there, I get why you need this now.

@omry
Copy link
Owner

omry commented Oct 24, 2019

Thanks a lot for this!
By the way, It will be useful to include to add an optional default value to the environment variable resolver by default.

@omry
Copy link
Owner

omry commented Oct 24, 2019

General feedback:
When I merge, I can squash in the GitHub UI just prior to merging the PR.
For future diffs, it will be easier if you don't force push to allow me to see the incremental difference from the previously reviewed diff(s).

@omry omry changed the title Loosen up regex requirements in resolve single Support passing variable number of arguments to resolvers. Oct 24, 2019
@omry omry merged commit efbf485 into omry:master Oct 24, 2019
@swist
Copy link
Contributor Author

swist commented Oct 25, 2019

Cool no problem, I normally default to pull-rebase so that merge commits don't come through and I didn't want to spam history with a bunch of wip commits.

@omry omry mentioned this pull request Nov 19, 2019
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.

3 participants