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

Dict int key type #454

Merged
merged 34 commits into from
Dec 24, 2020
Merged

Dict int key type #454

merged 34 commits into from
Dec 24, 2020

Conversation

Jasha10
Copy link
Collaborator

@Jasha10 Jasha10 commented Dec 11, 2020

A preliminary stab at implementing int key-type for DictConfig.

@Jasha10 Jasha10 mentioned this pull request Dec 11, 2020
@omry omry requested review from pereman2, omry and odelalleau December 12, 2020 07:18
@omry
Copy link
Owner

omry commented Dec 12, 2020

Before moving further with test coverage, here is a design question:
will we want to support other primitive key types besides int?
Currently (before the above PR), DictConfig keys can be one of
[Any, str, Enum, None]
and DictConfig values can be one of
[Any, str, float, bool, int, None, StructuredConfig].

We will likely want to support float and bool as well (all primitive types).
yaml has no issues with them and if there aren't any special issues I think we can support them.

As for the test you commented out, you can delete it but add tests covering the usage.
You can look at enum key tests, which is the latest addition of a new supported key type for inspiration.

Copy link
Owner

@omry omry left a comment

Choose a reason for hiding this comment

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

Thanks for working on it!
Overall looks pretty good, but I think I will want more tests.
once things are settled down, you can also update the docs and finally you can create a news fragment for this change.

Per your question, it could be a good opportunity to add book and float as well to complete the spectrum of keys to all supported primitives.
This can also be done in a followup PR if you prefer (but if we go that way I will want this completed with tests and documentation updates before we land it).

omegaconf/dictconfig.py Outdated Show resolved Hide resolved
tests/test_basic_ops_dict.py Outdated Show resolved Hide resolved
omegaconf/_utils.py Outdated Show resolved Hide resolved
tests/structured_conf/data/attr_classes.py Outdated Show resolved Hide resolved
tests/structured_conf/test_structured_config.py Outdated Show resolved Hide resolved
tests/test_basic_ops_dict.py Outdated Show resolved Hide resolved
Jasha10 and others added 4 commits December 13, 2020 12:42
We want to test that DictConfig throws KeyValidationError if invalid key
type is used. But `int` type is no longer invalid, so we test on
Dict[object, str] instead of on Dict[int, str].
@omry
Copy link
Owner

omry commented Dec 13, 2020

A surface area that should be tested is Structured Configs.

A few things to add tests for:

@dataclass
class DictWithIntKeys:
  dict : Dict[int, str]

@dataclass
class ExtendDictWithIntKeys(Dict[int, str]:
  ...

Anything else I am not thinking about?

Copy link
Collaborator Author

@Jasha10 Jasha10 left a comment

Choose a reason for hiding this comment

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

A related issue with type checking of OmegaConf.create:
The following also gives mypy issues:
a = OmegaConf.create({Enum1.FOO: 123})
For simplicity, we could consider changing the signature of the OmegaConf.create overload to something like obj: Union[Dict[Any, Any], None] = None.

tests/test_basic_ops_dict.py Outdated Show resolved Hide resolved
@omry
Copy link
Owner

omry commented Dec 13, 2020

re-request review when ready.

The changes in this commit were primarly driven by feedback from mypy.

Note that the definition of `DictKeyType` has been moved from
dictconfig.py to basecontainer.py due to a circular import issue.
@Jasha10

This comment has been minimized.

omegaconf/dictconfig.py Outdated Show resolved Hide resolved
	modified:   omegaconf/dictconfig.py

Changing the declaration of DictConfig from
    class DictConfig(BaseContainer, MutableMapping[DictKeyType, Any]):
to
    class DictConfig(BaseContainer, MutableMapping[Any, Any]):

This eliminates some mypy errors.

For example, the following code was giving mypy errors when using the
old declaration:

    from omegaconf import OmegaConf
    cfg = OmegaConf.create()
    upd = dict(a=1)
    cfg.update(upd)

The mypy error was:

    error: Argument 1 to "update" of "MutableMapping" has incompatible type "Dict[str, int]"; expected "Mapping[Union[str, int, Enum], Any]"

An alternative to using `MutableMapping[Any, Any]` would have been
something like
```
KT = TypeVar("KT", bound=DictKeyType)
class DictConfig(BaseContainer, MutableMapping[KT, Any]): ...
```
but this alternative would have introduced additional complexity, such
as requiring parametrization of DictConfig instances, e.g.
`DictConfig[int]` or `DictConfig[str]`.
@Jasha10 Jasha10 requested review from omry and odelalleau December 14, 2020 18:57
Copy link
Collaborator

@odelalleau odelalleau left a comment

Choose a reason for hiding this comment

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

Just a minor remark on type annotations -- after this I think it should be all good for me!

tests/test_basic_ops_dict.py Outdated Show resolved Hide resolved
pereman2
pereman2 previously approved these changes Dec 17, 2020
@pereman2 pereman2 dismissed their stale review December 17, 2020 09:49

missclick

Copy link
Collaborator

@odelalleau odelalleau left a comment

Choose a reason for hiding this comment

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

All my remarks have been resolved, thanks!

@Jasha10
Copy link
Collaborator Author

Jasha10 commented Dec 18, 2020

@omry I think this is ready for your signoff :)

@omry
Copy link
Owner

omry commented Dec 18, 2020

Thanks for the ping, I will take a look in a few days!

Copy link
Owner

@omry omry left a comment

Choose a reason for hiding this comment

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

Overall looks pretty good. see my comments.

docs/source/usage.rst Outdated Show resolved Hide resolved
docs/source/usage.rst Outdated Show resolved Hide resolved
omegaconf/basecontainer.py Show resolved Hide resolved
omegaconf/dictconfig.py Show resolved Hide resolved
omegaconf/basecontainer.py Outdated Show resolved Hide resolved
@omry
Copy link
Owner

omry commented Dec 22, 2020

Let me know what you guys think of that suggestion.
In any case, I am ready to merge this. Good job @Jasha10!

@omry
Copy link
Owner

omry commented Dec 22, 2020

Can you add a news fragment?

NEWS.md Outdated
Comment on lines 1 to 6
## 2.0.6 (2020-12-22)

### Features

- OmegaConf now supports `int` for dictionary key types ([#149](https://github.com/omry/omegaconf/issues/149))

Copy link
Owner

Choose a reason for hiding this comment

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

sorry for not being more specific.
Do not edit the news file.

OmegaConf is using towncrier to generate this file. You can read about the general approach in this Hydra page: https://hydra.cc/docs/development/documentation#news-entries

You should create a specific file under the news directory.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ok, got it.

Copy link
Owner

@omry omry left a comment

Choose a reason for hiding this comment

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

Awesome work, thanks!

@omry omry merged commit a00ea90 into omry:master Dec 24, 2020
@Jasha10 Jasha10 deleted the dict-int-key-type branch January 21, 2021 21:17
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