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

Fix to allow config.toml to be loaded with [meta] not present #591

Merged
merged 4 commits into from
Aug 17, 2022
Merged

Fix to allow config.toml to be loaded with [meta] not present #591

merged 4 commits into from
Aug 17, 2022

Conversation

ascillitoe
Copy link
Contributor

@ascillitoe ascillitoe commented Aug 16, 2022

#564 introduced a bug whereby config.toml files were not loadable via load_detector if the [meta] field was not present. The [meta] field is only present when config.toml files are generated by save_detector, hence why this was not picked up during previous CI.

This PR fixes this issue, and adds tests to check that validate_config and load_detector both work when [meta] is not present.

This will be released in a v0.10.3 patch once merged.

@ascillitoe ascillitoe modified the milestones: v0.10.2, v0.10.3 Aug 16, 2022
@codecov-commenter
Copy link

codecov-commenter commented Aug 16, 2022

Codecov Report

Merging #591 (09bbbf0) into master (af57b12) will decrease coverage by 0.03%.
The diff coverage is 100.00%.

❗ Current head 09bbbf0 differs from pull request most recent head b6e08cf. Consider uploading reports for the commit b6e08cf to get more accurate results

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #591      +/-   ##
==========================================
- Coverage   84.77%   84.74%   -0.04%     
==========================================
  Files         202      202              
  Lines       13538    13528      -10     
==========================================
- Hits        11477    11464      -13     
- Misses       2061     2064       +3     
Impacted Files Coverage Δ
alibi_detect/base.py 84.00% <100.00%> (+0.32%) ⬆️
alibi_detect/saving/schemas.py 99.20% <100.00%> (-0.05%) ⬇️
alibi_detect/saving/tests/test_saving.py 95.53% <100.00%> (+0.12%) ⬆️
alibi_detect/saving/tests/test_validate.py 100.00% <100.00%> (ø)
alibi_detect/saving/validate.py 96.15% <100.00%> (+0.15%) ⬆️
alibi_detect/utils/_types.py 72.41% <0.00%> (-24.14%) ⬇️
alibi_detect/utils/missing_optional_dependency.py 94.28% <0.00%> (-0.16%) ⬇️
alibi_detect/datasets.py 69.19% <0.00%> (-0.14%) ⬇️
alibi_detect/utils/fetching/fetching.py 0.00% <0.00%> (ø)
... and 3 more

@@ -259,6 +268,22 @@ def preprocess_hiddenoutput(classifier, backend):
return preprocess_fn


@parametrize('cfg', CFGS)
def test_load_simple_config(cfg, tmp_path):
Copy link
Contributor

Choose a reason for hiding this comment

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

Worth adding a docstring saying exactly what this is testing, i.e. not using the save_detector functionality here as that adds [meta] field automatically?

Comment on lines +280 to +283
# Save config.toml then load it
with open(cfg_path, 'w') as f:
toml.dump(cfg, f)
cd = load_detector(cfg_path)
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it necessary to dump to .toml first instead of calling load_detector on the dictionary? I suppose if we're strictly testing loading of .toml then it's ok.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree with you on this one, being able to pass config dicts to load_detector is something I think is nice. However, I can't recall why now but sometime back we decided to remove this capability (I think just to reduce complexity). The function signature for load_detector is currently load_detector(filepath: Union[str, os.PathLike], **kwargs).

I'd quite like to revisit this at some point...

with open(cfg_path, 'w') as f:
toml.dump(cfg, f)
cd = load_detector(cfg_path)
assert cd.__class__.__name__ == cfg['name']
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a way to assert "more", e.g. get the config dict?

Comment on lines 40 to 41
meta = cfg.get('meta')
meta = {} if meta is None else meta
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not meta = cfg.get('meta', {})? Ease of reading?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This bit was the root of the bug. The pydantic schema for DetectorConfig sets meta to None if it doesn't exist in the config.toml. Since meta does exist in cfg (but equals None), cfg.get('meta', {}) will still return None, and then line 42 fails.

Copy link
Contributor

Choose a reason for hiding this comment

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

Is this something worth leaving a comment in the code for (to prevent overzealous code "clean-up")?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea. Added a comment to this and the line in base.py.

Comment on lines 148 to 149
meta = config.pop('meta', None)
meta = {} if meta is None else meta
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not meta = config.pop('meta', {})? Ease of reading?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See previous comment.


# Define a detector config dict without meta (as simple as it gets!)
mmd_cfg_nometa = mmd_cfg.copy()
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to worry about shallow copies and shared objects here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did check and it doesn't seem to be an issue. Which is confusing since I think it would be for a list i.e. the pop-ing some from mmd_cfg_nometa would have removed it from mmd_cfg too 🤷🏻‍♂️

I've changed it to deepcopy anyway just to be on the safe side...

Copy link
Contributor

@jklaise jklaise 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 few questions from me.

Copy link
Contributor

@jklaise jklaise left a comment

Choose a reason for hiding this comment

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

LGTM

@ascillitoe ascillitoe merged commit cf03eb7 into SeldonIO:master Aug 17, 2022
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.

3 participants