-
Notifications
You must be signed in to change notification settings - Fork 37
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
Support pathlib.Path
values for dvcyaml
argument in Live()
.
#842
Support pathlib.Path
values for dvcyaml
argument in Live()
.
#842
Conversation
a2153eb
to
61a9fdc
Compare
src/dvclive/live.py
Outdated
@@ -82,7 +82,7 @@ def __init__( | |||
resume: bool = False, | |||
report: Literal["md", "notebook", "html", None] = None, | |||
save_dvc_exp: bool = True, | |||
dvcyaml: Optional[str] = "dvc.yaml", | |||
dvcyaml: Optional[str, Path] = "dvc.yaml", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dvcyaml: Optional[str, Path] = "dvc.yaml", | |
dvcyaml: Optional[str, os.Pathlike[str]] = "dvc.yaml", |
Use os.PathLike[str]
, which is more generic than Path
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AbdullahMakhdoom Yes, I think the suggestion from @skshetry is just a best practice for typing hinting paths. For example, a PurePath
will fail against pathlib.Path
but not against os.PathLike[str]
. Everything else in the PR LGTM.
Fixes Issue#769 |
src/dvclive/live.py
Outdated
@@ -265,10 +265,14 @@ def _init_dvc(self): # noqa: C901 | |||
self._include_untracked.append(self.dir) | |||
|
|||
def _init_dvc_file(self) -> str: | |||
if isinstance(self._dvcyaml, Path): | |||
self._dvcyaml = str(self._dvcyaml) | |||
if isinstance(self._dvcyaml, str): | |||
if os.path.basename(self._dvcyaml) == "dvc.yaml": | |||
return self._dvcyaml | |||
raise InvalidDvcyamlError |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we drop this line if we are adding the exception below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, makes sense.
tests/test_dvc.py
Outdated
@@ -220,12 +221,13 @@ def test_get_exp_name_duplicate(tmp_dir, mocked_dvc_repo, mocker, caplog): | |||
assert msg in caplog.text | |||
|
|||
|
|||
def test_test_mode(tmp_dir, monkeypatch, mocked_dvc_repo): | |||
@pytest.mark.parametrize("dvcyaml_path", ["dvc.yaml", Path("dvcyaml/dvc.yaml")]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for not getting back to you on this earlier, but I would vote to put this in a separate test in tests/test_make_dvcyaml.py
. It's probably enough to add a parameter here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this makes sense.
73d300f
to
a96e739
Compare
a96e739
to
f18c308
Compare
Thanks @AbdullahMakhdoom! |
@AbdullahMakhdoom it seems mypy failed, could you please take a look. Thanks! |
f18c308
to
66daf24
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #842 +/- ##
==========================================
- Coverage 95.47% 95.19% -0.29%
==========================================
Files 57 55 -2
Lines 3889 3909 +20
Branches 353 350 -3
==========================================
+ Hits 3713 3721 +8
- Misses 124 138 +14
+ Partials 52 50 -2 ☔ View full report in Codecov by Sentry. |
return "dvc.yaml" | ||
if self._dvcyaml is None: | ||
return "dvc.yaml" | ||
if isinstance(self._dvcyaml, bool): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, so is it something new? do we want to support bool as well?
we need to update docs then?
what happens if it's False (sounds like dvc.yaml
should not be produced at all then?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On True/False/None, it defaults to "dvc.yaml".
I had to make this change to pass an already written test case, which testsTrue
, False
values to dvcyaml
argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AbdullahMakhdoom could you please point me to that test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shcheklein, you can read the docstring for dvcyaml
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay, so:
If `False`, DVCLive will not write to "dvc.yaml" (useful if you are
tracking DVCLive metrics, plots, and parameters independently and
want to avoid duplication).
it means we can't default to dvc.yaml
- we should probably not running this function at all then if it's False.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shcheklein The code is maybe a bit of a mess here, but this sets self._dvcfile
, which shouldn't matter for whether the dvc.yaml
file is written. The code still checks self._dvcyaml
to decide whether to write dvc.yaml
here. This is tested here:
dvclive/tests/test_make_dvcyaml.py
Lines 461 to 463 in 6888462
def test_make_dvcyaml_false(tmp_dir, mocker): | |
dvclive = Live("logs", dvcyaml=False) | |
dvclive.end() |
It shouldn't matter much if self._dvcfile
is set in this scenario, but the slight justification for still setting it to dvc.yaml
is that if someone has set Live(dvcyaml=False)
but then manually calls make_dvcyaml()
, it will still write to dvc.yaml
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's unclear why using False
is necessary here, as setting dvcyaml
to None
appears to produce the same outcome. Both tests ensure that the dvc.yaml
file is not created when dvcyaml
is either False or None, indicating that these options are functionally equivalent in this context.
def test_make_dvcyaml_false(tmp_dir, mocker):
dvclive = Live("logs", dvcyaml=False)
dvclive.end()
assert not os.path.exists("dvc.yaml")
def test_make_dvcyaml_none(tmp_dir, mocker):
dvclive = Live("logs", dvcyaml=None)
dvclive.end()
assert not os.path.exists("dvc.yaml")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, apologize for the delayed responses, I've been quite busy with my day job. Please let me know the best way to move forward, and I'll make sure to do my best.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No problem @AbdullahMakhdoom, thanks for keeping on top of this!
dvcyaml
used to be a bool argument and support for bools was left to avoid making a breaking change. We should probably have dropped this during the last major release but missed it.
…cyaml` argument.
4f0f16b
to
ba66faa
Compare
for more information, see https://pre-commit.ci
@skshetry please approve and merge if everything looks good to you. |
Apologies for multiple approval. GH bugged out. :( |
if self._dvcyaml is None: | ||
return "dvc.yaml" | ||
if isinstance(self._dvcyaml, bool): | ||
return "dvc.yaml" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we okay with returning dvc.yaml
in case of dvcyaml=False
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But this is unrelated to this PR. We were already doing that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@skshetry, as pointed out by @dberenbaum, "the slight justification for still setting it to dvc.yaml is that if someone has set Live(dvcyaml=False) but then manually calls make_dvcyaml(), it will still write to dvc.yaml. "dvc.yaml" is being returned ".
Also, there was a test case for backward compatability of accepting bool values of dvc_yaml
argument.
…cyaml` argument.
❗ I have followed the Contributing to DVCLive guide.
📖 If this PR requires documentation updates, I have created a separate PR (or issue, at least) in dvc.org and linked it here.
Thank you for the contribution - we'll try to review it as soon as possible. 🙏