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

Is it possible to forbid accessing missing keys? #121

Closed
devforfu opened this issue Apr 7, 2020 · 4 comments
Closed

Is it possible to forbid accessing missing keys? #121

devforfu opened this issue Apr 7, 2020 · 4 comments

Comments

@devforfu
Copy link

devforfu commented Apr 7, 2020

Hi there,

I'm using addict.Dict instances to store some predefined configuration. The configuration is stored as JSON and loaded into Dict as follows.

import json
from addict import Dict
with open(filename) as f:
    config = Dict(json.load(f))

It works great. Then I use this configuration to set up some properties of my objects.

class Object:
    def __init__(self, config: Dict):
        self.x = config.section_a.x
        self.y = config.section_b.sub_section.y
        self.z = config.section_c.value
        ...  # etc.

The problem with this approach is that if I made a typo in the attribute name, I'll not get an attribute error but an empty dictionary and my class's internal logic fails later on when encounters dictionary type instead of expected value.

self.z = config.section_c.vallue   # typo that returns {}
...
z_squared = self.z**2  # fails because of the wrong type

I understand that this behavior is expected and required to enable the creation of dynamic nested dictionaries. However, in my case, I use Dict as a "frozen" configuration object that is not expected to be modified during the program's lifetime and would like it to fail early in case of typos or missing entries. With the current behavior, the program doesn't fail on an object's creation but raises a (non-obvious) error later on.

I wonder is it possible to add a frozen attribute to the Dict initializer? Like the following snippet shows.

from addict import Dict
config = Dict(config, frozen=True)

# or

import addict
config = addict.freeze(addict.Dict(config))

And if a "frozen" object is asked a missing key, the error is raised.

config.section.missing_key  # raises KeyError

Would be glad to hear your thoughts!

@mewwts
Copy link
Owner

mewwts commented Apr 8, 2020

Hi @devforfu,

Good suggestion. I'd be open to adding this, sure! Would you like to take a stab at the implementation?

What do you think of the following API?

from addict import Dict
c = Dict(config)
c.freeze()

@devforfu
Copy link
Author

Hi @mewwts,

Thank you for the response! Yes, looks good! Probably it is worth also to return a Dict instance? Like c = Dict(config).freeze()?

Ok, sure, not a problem. I'll try to cope up with something and open a PR.

@mewwts
Copy link
Owner

mewwts commented Apr 27, 2020

Yes, sure, but then in the example

a = Dict(config)
b = a.freeze()

I would expect b to be a separate instance to a, right?

@mewwts
Copy link
Owner

mewwts commented Sep 12, 2020

Moved discussion to #123

@mewwts mewwts closed this as completed Sep 12, 2020
This was referenced Nov 18, 2020
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

No branches or pull requests

2 participants