-
-
Notifications
You must be signed in to change notification settings - Fork 25.8k
CI Use environment variable to turn warnings into errors in tests and doc build #28372
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
CI Use environment variable to turn warnings into errors in tests and doc build #28372
Conversation
… renaming" This reverts commit be8b69c.
b5f9d87
to
35dac82
Compare
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.
Tested locally and it works 👍🏼
Other than not being sure about the hack, lgtm.
sklearn/conftest.py
Outdated
# https://github.com/pytest-dev/pytest/blob/404d31a942975c04d4a7d48e258260584930819f/src/_pytest/warnings.py#L45-L48 | ||
# This would overrides our warning filters modifications so we set | ||
# sys.warnoptions to a non-empty value | ||
sys.warnoptions = "hack-to-avoid-pytest-overriding-warning-filters" |
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.
🤦🏼
I would have hoped for having things in pyproject.toml
or something instead of needing this hack.
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.
I think one of the challenge is to be able to dynamically set the warning filters based on an environment variable, so you need something else on top of defining the warning filters inside a configuration file. Also I am not a big fan of warnings as errors by default, I feel there may be too many warnings that contributors bump into depending on their environment, and chasing these warnings is not worth it, maybe I am wrong about this ...
If there was not the issue that pandas Pyarrow DeprecationWarning starts with a newline and thus can not be ignored with -W
, the hack would not be needed. With the right Pytest hook you can add -W
arguments before the command line is parsed for example with pytest_load_initial_conftests
https://docs.pytest.org/en/7.1.x/reference/reference.html?highlight=pytest_collection_modifyitems#std-hook-pytest_load_initial_conftests
An alternative would be to have:
pytest_load_initial_conftests
to add-W
arguments based on environment variable- special case for pandas Pyarrow DeprecationWarning using the right Pytest hook
I just found pytest-dev/pytest#3311 with a use case somewhat similar to ours, change pytest config value programatically but there does not seem to be a clean solution either.
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.
Thinking about it a bit more, it is kind of nice that in this PR the warning filters are used both for the tests and the doc build, so a Pytest-specific thing may not be the best solution.
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.
Only commandline python -W
doesn't work with \n
at the beginning of the message though. They work if loaded from config files: https://github.com/skops-dev/skops/pull/409/files
So we could have multiple config files and load from them based on some input arg or env variable.
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.
They work if loaded from config files
Yes I know 😉 filterwarnings in config files accept regexes, -W
does not.
So we could have multiple config files and load from them based on some input arg or env variable.
Indeed, something similar is mentioned in pytest-dev/pytest#3311 (comment). A bit hacky but maybe less hacky than alternatives.
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 I am not a big fan of warnings as errors by default, I feel there may be too many warnings that contributors bump into depending on their environment, and chasing these warnings is not worth it
I agree when building and running test locally, but I think it's good to have it configured as errors on the CI.
doc/computing/parallelism.rst
Outdated
- tests, for example by running `SKLEARN_WARNINGS_AS_ERRORS=1 pytest sklearn`. | ||
- documentation build, where it is turned on by default when you do `make | ||
html`. You can do `SKLEARN_WARNINGS_AS_ERRORS=0 make html` if you want to | ||
ignore warnings. Note that this checks that running examples don't produce | ||
any warnings which is not the same as `SHPINXOPTS="-W"` that checks syntax | ||
issues in the rst files. |
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.
we should be more clear what the default is.
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.
Based on the current diff it's set to 1 when building the doc but 0 when running the tests.
I think that for the sake of consistency, it should be 0 everywhere but we should set the SKLEARN_WARNINGS_AS_ERRORS=1
explicitly when building the doc on the CI.
WDYT @adrinjalali @lesteve?
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.
+1 for having SKLEARN_WARNINGS_AS_ERRORS=0
by default in the doc build as well. I guess one reason to have it set to 1/true by default in the doc build was that people have the same settings as the CI by default.
As I mentioned above, my main reason to have SKLEARN_WARNINGS_AS_ERRORS=0
by default is to avoid getting reports from contributors with warnings in some environments that are not worth fixing.
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.
I don't mind. And I can have the env present in my session always, so my personal workflow would be fine anyway.
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.
2 weeks ago, this error by default on local build was the source of confusion for an experience scikit-learn contributor because of a deprecation warning on Python 3.12 only.
Also use the same logic in doc/conf.py and tweak doc
So my last non-empty commit, I have an alternative approach with a slightly different hack which was mentioned in pytest-dev/pytest#3311 (comment): this uses The fact that it still works almost 6 years after the comment maybe is a sign that this is a hack that is not too brittle ... This is maybe a bit less hacky than the previous attempt based on warnings.filterwarnings since at least this uses pytest functionality. Full-disclosure:
|
@@ -21,9 +21,6 @@ addopts = | |||
# source folder. | |||
-p sklearn.tests.random_seed | |||
|
|||
filterwarnings = |
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.
I don't think there was a reason for this anymore ... it seems like the CI agrees.
The coverage drop is due to |
sklearn/conftest.py
Outdated
# This seems like the only way to programmatically change the config | ||
# filterwarnings. This was suggested in | ||
# https://github.com/pytest-dev/pytest/issues/3311#issuecomment-373177592 | ||
config._inicache["filterwarnings"] += get_pytest_filterwarning_str() |
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.
I think we can use public API:
# This seems like the only way to programmatically change the config | |
# filterwarnings. This was suggested in | |
# https://github.com/pytest-dev/pytest/issues/3311#issuecomment-373177592 | |
config._inicache["filterwarnings"] += get_pytest_filterwarning_str() | |
for line in get_pytest_filterwarning_str(): | |
config.addinivalue_line("filterwarnings", line) |
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.
Good point although it is kind of not encouraged in pytest-dev/pytest#3311 (comment)
while addinivalue_line exists, it feels it was added solely to expand the list of builtin markers, which seems like it could have been done in some other way.
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.
OK I used addinivalue_line, at least it is public ...
This is ready for a second round of review:
The full doc build passes in b5dad1c |
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.
LGTM, thank you very much @lesteve. Centralizing this is a quality of life improvement :)
WarningInfo("error", category=DeprecationWarning), | ||
WarningInfo("error", category=FutureWarning), | ||
WarningInfo("error", category=VisibleDeprecationWarning), | ||
WarningInfo( |
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 you please add comments (ideally with links to some issue tracker) to motivate the fact that we ignore those particular cases?
That might require some git blame archeology.
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.
I actually add back a comment I removed by mistake, this is about pyamg that uses pkg_resources in its latest release but not in main ...
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.
I don't understand what you mean by "in its latest release but not in main".
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.
pyamg 5.0.1 (latest release) will create a DeprecationWarning about using pkg_resources
. pyamg in main
has removed pkg_resources
usage.
When pyamg > 5.0.1 is released and our minimum pyamg supported version is strictly greater than 5.0.1, we can remove the pkg_resource ignore warning filters.
Note that for documentation build, `SKLEARN_WARNING_AS_ERRORS=1` is checking | ||
that the documentation build, in particular running examples, does not produce | ||
any warnings. This is different from the `-W` `sphinx-build` argument that | ||
catches syntax warnings in the rst files. |
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.
We should move the whole "Environment variables" section of the doc to its own environment_variables.rst
file instead of parallelism.rst
but ok for not doing it as part of this PR.
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 I agree ...
Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org>
… doc build (scikit-learn#28372) Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org>
… doc build (scikit-learn#28372) Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org>
… doc build (scikit-learn#28372) Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org>
… doc build (#28372) Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org>
Follow-up of #28348 (comment) to make it easier to run locally with the same "warnings as errors" setup as in the CI:
Warning filters have grown a bit and will grow a bit more once there is a Python 3.12 build in the CI (
dateutil
,joblib
latest releases create warnings with Python 3.12). There is now a single place where warning filters is defined instead of havingsetup.cfg
,test_script.sh
(CI), andsklearn/conftest.py
.While I was at it I use the same function for "warnings as errors" in the doc build.
For now there is a hack with
sys.warnoptions
, see comments insklearn/conftest.py
, I looked for some time, but I haven't found anything better ...cc @adrinjalali @ogrisel who put a ❤️ on my original comment.