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

Change config #701

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open

Change config #701

wants to merge 17 commits into from

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

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

batchflow/config.py Outdated Show resolved Hide resolved
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

batchflow/config.py Outdated Show resolved Hide resolved
batchflow/config.py Outdated Show resolved Hide resolved
batchflow/config.py Outdated Show resolved Hide resolved
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

batchflow/config.py Outdated Show resolved Hide resolved
batchflow/config.py Outdated Show resolved Hide resolved
batchflow/config.py Outdated Show resolved Hide resolved
batchflow/config.py Outdated Show resolved Hide resolved
batchflow/config.py Outdated Show resolved Hide resolved
batchflow/config.py Outdated Show resolved Hide resolved
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}}.

batchflow/config.py Outdated Show resolved Hide resolved
batchflow/config.py Outdated Show resolved Hide resolved
batchflow/config.py Outdated Show resolved Hide resolved
batchflow/config.py Outdated Show resolved Hide resolved
batchflow/config.py Outdated Show resolved Hide resolved
batchflow/config.py Outdated Show resolved Hide resolved
batchflow/config.py Outdated Show resolved Hide resolved
batchflow/config.py Outdated Show resolved Hide resolved
batchflow/config.py Outdated Show resolved Hide resolved
batchflow/config.py Outdated Show resolved Hide resolved
batchflow/config.py Outdated Show resolved Hide resolved
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
Collaborator

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

batchflow/config.py Show resolved Hide resolved
batchflow/config.py Outdated Show resolved Hide resolved
batchflow/config.py Outdated Show resolved Hide resolved
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 .

batchflow/config.py Outdated Show resolved Hide resolved
batchflow/config.py Show resolved Hide resolved
batchflow/config.py Outdated Show resolved Hide resolved
Comment on lines 331 to 367
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.

4 participants