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

RFC: Allow dot traversing to access nested dictionaries #84

Closed
rochacbruno opened this issue Sep 21, 2018 · 3 comments
Closed

RFC: Allow dot traversing to access nested dictionaries #84

rochacbruno opened this issue Sep 21, 2018 · 3 comments

Comments

@rochacbruno
Copy link
Owner

@rochacbruno rochacbruno commented Sep 21, 2018

Lets take a settings.yaml

DEFAULT:
    REDIS:
        HOST: localhost
        PORT: 1234

To access the port you need to use one of:

settings.REDIS['PORT']        # may raise KeyError
settings['REDIS']['PORT']      # may raise KeyError
settings.REDIS.PORT           # possible because it is a Box(), but may raise AtributeError
settings.get('REDIS').PORT  # dict like get method
settings('REDIS')['PORT']      # the same as calling .get
settings.get('REDIS').get('PORT')  # may raise AttributeError

But what if you are not sure that the REDIS value is defined in settings.yaml and you don't wanna fail?

one way is relying on the .get default argument (dict like)

settings.get('REDIS', {}).get('PORT', 1234)

RFC: Allow traversing

settings('REDIS.PORT')   # would access the settings['REDIS']['PORT'] or raise KeyError.

settings('REDIS.PORT', 1234)   # if value cannot be accessed returns 1234 by default

The . should be parsed on LazySettings.get method and then perform the traversing.

Requirements

  • Avoid regressions (keep backwards compatibility)
  • Allow it to be disabled opt-out
  • Ensure it does not include overhead by recursion and traversing
  • Document it
  • Write test cases
  • Write examples/
@rochacbruno rochacbruno changed the title Allow dot traversing to access nested dictionaries RFC: Allow dot traversing to access nested dictionaries Sep 21, 2018
@rochacbruno
Copy link
Owner Author

@rochacbruno rochacbruno commented Sep 21, 2018

As dynaconf uses Box https://github.com/cdgriffith/Box this functionality is easy to implement, the major concern is about testing and performance

@rochacbruno rochacbruno added the RFC label Sep 21, 2018
jperras added a commit to jperras/dynaconf that referenced this issue Oct 16, 2018
A simple memoized recursion has been added to `get()` if the key
contains at least one dot.

The caller can choose to opt-out of this behaviour by specifying the
`dotted_lookup` argument:

```python
settings('AUTH.USERNAME', dotted_lookup=False)
```

While the performance impact of this has not been quantified, the net
impact in any real-world application should be minimal due to typical
nesting levels, and the fact that we overwrite the memoized portion of
the dotted-key lookup on each iteration.

- Avoids regressions [✓]
- Can be opted-out on a per-call basis [✓]
- Minimal performance impact [✓]
- Documented [✓]
- Tested [✓]
- Examples added [✓]

Closes rochacbruno#84
@allan-silva
Copy link
Contributor

@allan-silva allan-silva commented Oct 17, 2018

@rochacbruno, considering the given yaml, what should happen when the REDIS entry does not exist? Should the PORT be accessible?

@rochacbruno
Copy link
Owner Author

@rochacbruno rochacbruno commented Oct 19, 2018

@allan-silva this feature has been implemented!

If the base REDIS does not exists then it raises keyerror.

jperras added a commit to jperras/dynaconf that referenced this issue Oct 22, 2018
A simple memoized recursion has been added to `get()` if the key
contains at least one dot.

The caller can choose to opt-out of this behaviour by specifying the
`dotted_lookup` argument:

```python
settings('AUTH.USERNAME', dotted_lookup=False)
```

While the performance impact of this has not been quantified, the net
impact in any real-world application should be minimal due to typical
nesting levels, and the fact that we overwrite the memoized portion of
the dotted-key lookup on each iteration.

- Avoids regressions [✓]
- Can be opted-out on a per-call basis [✓]
- Minimal performance impact [✓]
- Documented [✓]
- Tested [✓]
- Examples added [✓]

Closes rochacbruno#84
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.