Skip to content

Conversation

@EvgeniyS99
Copy link
Contributor

@EvgeniyS99 EvgeniyS99 commented Jun 2, 2023

A new version of config supports any hashable object as key (like a simple dict):
image
However, due to the fact that tests were written for the old version of config which supports only str as a key, some of them are failed

@EvgeniyS99 EvgeniyS99 requested a review from SergeyTsimfer June 2, 2023 16:17
Copy link
Member

@SergeyTsimfer SergeyTsimfer left a comment

Choose a reason for hiding this comment

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

An overall impression is that not much has changed
Rewrite this thing from scratches with desired functionality (and tests) in mind

pass
elif isinstance(config, Config):
self.config = config.config
super().__init__(config)
Copy link
Member

Choose a reason for hiding this comment

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

should not that start endless recursion?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, it simpy returns the given config
image

raise TypeError(f'only str and Path keys are supported, "{str(key)}" is of {type(key)} type')

if isinstance(key, str):
key = '/'.join(filter(None, key.split('/')))
Copy link
Member

Choose a reason for hiding this comment

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

If the goal is to deduplicate slashes, then .replace('//', '/') is much easier to read; also, if clause is not needed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree, but what if we have three or more consecutive slashes? Also, I think that if clause is needed cause key could be another object, not necessarily a string

Comment on lines 87 to 88
if key in self:
self.pop(key)
Copy link
Contributor

Choose a reason for hiding this comment

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

I want here syntax like in the dict :

Suggested change
if key in self:
self.pop(key)
_ = self.pop(key, None)

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, why we can't write the put method in the way when we needn't pop before put?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also, why we can't write the put method in the way when we needn't pop before put?

I think, we can't, because we want to update value if key is already in config. However, there are some cases when pop is necessary.
For example: config = Config({'a/b': 1, 'a/c': 2})
When we want to set a new value for key='a', config['a'] = dict(b=0, d=3), we want to get
config = {'a': {'b': 0, 'd': 3}}.

if parent in config and isinstance(config[parent], Config): # for example, we put value=3 with key='a/c' into the
config[parent].update(Config({child: value})) # config = {'a': {'b': 1}} and want to receive {'a': {'b': 1, 'c': 3}}
else:
config[parent] = Config({child: value})
Copy link
Member

Choose a reason for hiding this comment

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

We will silently rewrite items like {'a': 3} by {'a/b': 2}. Should it be a warning or exception?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We will silently rewrite items like {'a': 3} by {'a/b': 2}. Should it be a warning or exception?

I think, yes, a warning would be good here

Comment on lines 201 to 207
def __getattr__(self, key):
if key in self:
value = self.get(key)
value = Config(value) if isinstance(value, dict) else value
return value
raise AttributeError(key)

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe AttributeError should be defined in the self.get?

Copy link
Contributor Author

@EvgeniyS99 EvgeniyS99 Aug 15, 2023

Choose a reason for hiding this comment

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

Maybe AttributeError should be defined in the self.get?

But in this case we will catch AttributeError every time we want to retrieve nonexisting key from the dict, not only by .

Comment on lines 331 to 367
def __eq__(self, other):
self_ = self.flatten() if isinstance(self, Config) else self
other_ = Config(other).flatten() if isinstance(other, dict) else other
return self_.__eq__(other_)
Copy link
Contributor

Choose a reason for hiding this comment

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

What if other is a Config and not flatten?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What if other is a Config and not flatten?

He will be flattened anyway because if other is an instance of Config, isinstance(other, dict) is True

Copy link
Member

@SergeyTsimfer SergeyTsimfer left a comment

Choose a reason for hiding this comment

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

Still overly complicated and keeps old code. Also, make sure that tests are working

Copy link
Member

@SergeyTsimfer SergeyTsimfer left a comment

Choose a reason for hiding this comment

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

Looks a lot better!
A few comments:

  • there are some dev comments in the code, but not enough of them in the _get/_put methods
  • check that documentation is up-to-date
  • add descriptive messages into raised errors: that would help greatly when keys are missing on various levels of nestedness

return other << self

def __getstate__(self):
""" Must be explicitly defined for pickling to work. """
Copy link
Member

Choose a reason for hiding this comment

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

Sounds very dogmatic

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.

5 participants