drgrib / dotmap

Dot access dictionary with dynamic hierarchy creation and ordered iteration

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

getattr/setattr doesnt work

Sult opened this issue · comments

So far I have to say I love working with DotMap however I run into the issue that getattr and setattr don't work at the way you expect.

Example:

>>> from dotmap import DotMap
>>> data = DotMap({'Input': {}, 'Expected': {
...     'HttpResponseCode': '201', 'EndState': 'FullyProcessedOk', 'MaximumTimeUntilEndstate': '60'}
... })
>>> getattr(data, "Expected.EndState")
DotMap()

Similar with setattr
I suppose this has to do that it doesnt see the dots as a next branch (like on normal objects) but as 1 key
Any chance there is a way to get this working?

@Sult Glad you are enjoying the package! I don't have any plans to update calls to the getattr function to work the way you are expecting. That is a deeper level of implementation than what is advertised in the README.md, though I can understand why you would want it.

You are welcome to take a crack at it yourself and submit a PR if you are so inclined.

@Sult So, actually, I took a crack at what implementing this would look like. The problem with implementing this is that it would break cases when people actually want . in their key names.

For example:

>>> from dotmap import DotMap
>>> m = DotMap()
>>> m.normal_dot_stuff = 1
>>> m['.secret_file'] = "secret"

If I implemented the class the way you are expecting, this would break:

>>> m['.secret_file']
'secret'

It's a tough call either way and neither choice is perfect but, in this case, I am leaning towards allowing normal dict-like operation with keys that can have . in their name.

Yes I saw the earlier case where people wanted to used it in their keys. So already had a feeling.
When I have time I might look into an option you can set when creating an instance. So you could choose to forgo the dot availability inside keys to get a more dynamic way of using it.
Other option would be a parsing of keys to temporary something else to use dot and then convert back, but that would be inefficient and a pain to deal with.

Yeah, having a new option could work. Even that would be a non-trivial implementation. But feel free to pull the latest version and see if you can set one up that passes unit tests using both versions with dots in keys and with. I'd approve a PR and put it in the read me if you did.

With that said, you might see a more efficient solution in your own application by just accessing the keys programmatically with the traditional dict bracket notation ;)

For my implementation I have to do a lot of dict walking. (so multi layer nesting)
so it would be easier to do something like

value = getattr(Dotmap, '.',join(path))
than this

tmp = Dotmap() # new reference to existing dotmap instance
for key in path:
tmp = tmp[key]

Not that it is such a hassle, and easy to put in a method, just used working with getattr
And since i everywhere already work with the neat DotMap syntax, i thought its a more elegant solution to do the dotted path :)

I shall see if i have some time in the weekend, to make a PR