-
-
Notifications
You must be signed in to change notification settings - Fork 18.1k
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
TST: Disallow bare pytest.raises #23922
Comments
Just to provide some additional info, I did couple of greps, and I see that:
|
That's good to know. We can probably test for the existence of a closing parenthesis (in some way shape or form) is my first thought. |
Personally, I am not sure enforcing it here is needed. This will be a huge amount of work, which IMO would be better spent actually improving error messages. |
@jorisvandenbossche : I'm pretty sure we have plenty of people who would be happy to contribute to the effort, so I'm not concerned about that. 😉 |
I'm okay with putting aside enforcement, but if checking error messages is a thing we should be focusing on in the future, I think converting these bare |
@datapythonista : I'm not sure what
pandas/tests/arithmetic/test_datetime64.py |
For anyone who is interested in contributing, working on any one of the files listed above would be great! |
I agree with @jorisvandenbossche here as I'm not sure how much we stand to gain out of this. There will be a lot of instances where incremental value add is nil or questionable.
We already have a decent amount of PRs concerning code style and docstrings atm and the PR queue is larger than it's even been. Is this something we feel needs to be addressed now or can we come back to it once some of the noise around docstrings settles down? |
I won't rule out corner cases, but I'm pretty certain there are more instances where there will be value added. We don't have to push enforcing, but let's at least take a look and convert these. And if they aren't giving relevant error messages, then that's a good sign to change them.
Hardly. Otherwise, I would have tagged this for a release version. This is just another way for people to contribute to |
I agree with everyone. This is a worthwhile goal, not an urgent goal, and a good way for newcomers to make a real contribution while learning the code. The linting part might be easier if we required the contextmanager usage for To find non-context usages:
I'm sure the latter has corner cases I'm missing. |
@gfyoung the numbers I shared weren't number of files, but the times that What I'd do is create an issue to add the Does that make sense? |
Follow-up to pandas-devgh-23999. xref pandas-devgh-23922.
I don't think your regex is correct. For example, it found
in Should probably looks for |
Instead of using regex, what if we patched |
@jbrockmendel : By unwanted uses, what do you mean? And patch how exactly (not sure I follow you here 100%)? |
Something along the lines of:
|
I'm not necessarily saying this is a good idea, just that it avoids some of the pitfalls of grep-based linting. |
@gfyoung |
@mike-cramblett : That's fantastic! Let me answer your questions:
Yes.
I would suggest doing one file first and seeing how that goes. Some are trickier than others. In addition, that list is a little dated (I need to run the |
Thanks for the info and encouragement! Just reran that grep and got 162 files. I was figuring I'd start with tests/arithmetic/test_datetime64.py since it's first on the list. But it looks like that file has 94 pytest.raises calls to fix. I'm not that daunted by doing all that, since it seems they're mostly similar TypeErrors. But I'd also be open to starting on a simpler file if you have one in mind. Thanks again! |
@gfyoung are we close to the goal line here? |
wrong button |
at least 1167 still to do. quite time consuming. so not close. |
Question for the team - do we see any improvements for our current approach? Half of me continues to like this change as it can catch some subtle differences, but the other half of me thinks this causes unnecessary noise with CI (#26726 being an example) |
the CI breakages are an additional burden. but I do think that it helps identify inconsistencies in user-facing exception messages. |
So two things I've thought about:
With option 1 I think we should really avoid complicated patterns like this:
Where we aren't actually managing expectations around what the user sees as much as implicity doing some versioning to make CI happy For option 2 I just think failing because of a message change from an external dependency generates a lot of busy work for something we don't control anyway. Not sure how enforceable this is |
makes sense. maybe explicit checks for 2. and use 1 for messages raised by other packages. that would solve the CI issues and still help improve user-facing error messages. |
I second @simonjayhawkins suggestion as well |
i am ok with limiting how much we check in our error messages (option 1) CI failures are a canary and so good to have - even if occasionally are a false positive |
A potential issue i can foresee with explicitly checking error messages from 3rd party packages is where the pandas test suite is used to validate environments and distributions. After a pandas release, the test suite could fail purely due to subtle changes in the messages raised by updated dependencies. |
@jbrockmendel : I think there is still a fair distance to go here.
Where in the Here is the updated list of files that still have bare pandas/pandas/tests/io/test_html.py |
code_checks.sh line 136-138 |
That’s checking for a different usage of pytest.raises(Exception, lambda f: 1 / 0) We discourage this form and prefer: with pytest.raises(Exception):
1 / 0 I know because I authored the PR that added the check you referenced 😉 |
superseded by #30999 |
End users rely on error messages for their debugging purposes. Thus, it is important that we make sure that the correct error messages are surfaced depending on the error triggered.
I would like to propose that we disallow the following:I think we should convert the following:
And in the spirit of tm.assert_raises_regex, we should ensure that all tests have the following:
There are likely a few corner cases that would need to be ironed out, but I think the net benefit of converting this format would be much better for the robustness of our tests.
If we are going to focus on error message quality, then let's test them consistently! 🙂
Want to open to discussion first to see if we are on board with this. If we are, then this issue will be converted to one for doing said conversions and then (maybe) enforcing in our linter.
xref #16521
xref #23550
xref #23853
===============================================================
Running this command:
yields the following list:
pandas/tests/api/test_types.py
pandas/tests/arithmetic/test_datetime64.py
pandas/tests/arithmetic/test_numeric.py
pandas/tests/arithmetic/test_object.py
pandas/tests/arithmetic/test_period.py
pandas/tests/arithmetic/test_timedelta64.py
pandas/tests/arrays/categorical/test_algos.py
pandas/tests/arrays/categorical/test_analytics.py
pandas/tests/arrays/categorical/test_api.py
pandas/tests/arrays/categorical/test_constructors.py
pandas/tests/arrays/categorical/test_indexing.py
pandas/tests/arrays/categorical/test_operators.py
pandas/tests/arrays/interval/test_ops.py
pandas/tests/arrays/sparse/test_array.py
pandas/tests/arrays/sparse/test_dtype.py
pandas/tests/arrays/sparse/test_libsparse.py
pandas/tests/arrays/test_array.py
pandas/tests/arrays/test_datetimelike.py
pandas/tests/arrays/test_integer.py
pandas/tests/computation/test_compat.py
pandas/tests/computation/test_eval.py
pandas/tests/dtypes/test_cast.py
pandas/tests/dtypes/test_dtypes.py
pandas/tests/extension/base/getitem.py
pandas/tests/extension/base/ops.py
pandas/tests/extension/base/reduce.py
pandas/tests/extension/base/setitem.py
pandas/tests/extension/decimal/test_decimal.py
pandas/tests/extension/json/test_json.py
pandas/tests/extension/test_categorical.py
pandas/tests/extension/test_integer.py
pandas/tests/frame/test_analytics.py
pandas/tests/frame/test_apply.py
pandas/tests/frame/test_arithmetic.py
pandas/tests/frame/test_axis_select_reindex.py
pandas/tests/frame/test_constructors.py
pandas/tests/frame/test_convert_to.py
pandas/tests/frame/test_dtypes.py
pandas/tests/frame/test_duplicates.py
pandas/tests/frame/test_indexing.py
pandas/tests/frame/test_missing.py
pandas/tests/frame/test_mutate_columns.py
pandas/tests/frame/test_operators.py
pandas/tests/frame/test_quantile.py
pandas/tests/frame/test_query_eval.py
pandas/tests/frame/test_reshape.py
pandas/tests/frame/test_sorting.py
pandas/tests/frame/test_timeseries.py
pandas/tests/generic/test_frame.py
pandas/tests/generic/test_generic.py
pandas/tests/generic/test_series.py
pandas/tests/groupby/test_categorical.py
pandas/tests/groupby/test_groupby.py
pandas/tests/groupby/test_timegrouper.py
pandas/tests/indexes/common.py
pandas/tests/indexes/datetimelike.py
pandas/tests/indexes/datetimes/test_arithmetic.py
pandas/tests/indexes/datetimes/test_astype.py
pandas/tests/indexes/datetimes/test_construction.py
pandas/tests/indexes/datetimes/test_date_range.py
pandas/tests/indexes/datetimes/test_indexing.py
pandas/tests/indexes/datetimes/test_timezones.py
pandas/tests/indexes/datetimes/test_tools.py
pandas/tests/indexes/interval/test_astype.py
pandas/tests/indexes/interval/test_interval.py
pandas/tests/indexes/interval/test_interval_new.py
pandas/tests/indexes/interval/test_interval_tree.py
pandas/tests/indexes/multi/test_analytics.py
pandas/tests/indexes/multi/test_compat.py
pandas/tests/indexes/multi/test_constructor.py
pandas/tests/indexes/multi/test_drop.py
pandas/tests/indexes/multi/test_duplicates.py
pandas/tests/indexes/multi/test_get_set.py
pandas/tests/indexes/multi/test_indexing.py
pandas/tests/indexes/multi/test_integrity.py
pandas/tests/indexes/multi/test_monotonic.py
pandas/tests/indexes/multi/test_partial_indexing.py
pandas/tests/indexes/multi/test_sorting.py
pandas/tests/indexes/period/test_arithmetic.py
pandas/tests/indexes/period/test_construction.py
pandas/tests/indexes/period/test_indexing.py
pandas/tests/indexes/period/test_partial_slicing.py
pandas/tests/indexes/period/test_period.py
pandas/tests/indexes/test_base.py
pandas/tests/indexes/test_category.py
pandas/tests/indexes/test_common.py
pandas/tests/indexes/test_numeric.py
pandas/tests/indexes/test_range.py
pandas/tests/indexes/timedeltas/test_arithmetic.py
pandas/tests/indexes/timedeltas/test_construction.py
pandas/tests/indexes/timedeltas/test_indexing.py
pandas/tests/indexing/interval/test_interval.py
pandas/tests/indexing/interval/test_interval_new.py
pandas/tests/indexing/multiindex/test_setitem.py
pandas/tests/indexing/multiindex/test_slice.py
pandas/tests/indexing/test_categorical.py
pandas/tests/indexing/test_indexing.py
pandas/tests/indexing/test_loc.py
pandas/tests/indexing/test_panel.py
pandas/tests/indexing/test_partial.py
pandas/tests/indexing/test_scalar.py
pandas/tests/internals/test_internals.py
pandas/tests/io/formats/test_format.py
pandas/tests/io/formats/test_style.py
pandas/tests/io/formats/test_to_latex.py
pandas/tests/io/json/test_json_table_schema.py
pandas/tests/io/json/test_normalize.py
pandas/tests/io/json/test_pandas.py
pandas/tests/io/json/test_ujson.py
pandas/tests/io/parser/test_network.py
pandas/tests/io/parser/test_python_parser_only.py
pandas/tests/io/sas/test_sas7bdat.py
pandas/tests/io/test_clipboard.py
pandas/tests/io/test_common.py
pandas/tests/io/test_excel.py
pandas/tests/io/test_feather.py
pandas/tests/io/test_gcs.py
pandas/tests/io/test_html.py
pandas/tests/io/test_parquet.py
pandas/tests/io/test_pytables.py
pandas/tests/io/test_sql.py
pandas/tests/io/test_stata.py
pandas/tests/plotting/test_boxplot_method.py
pandas/tests/plotting/test_frame.py
pandas/tests/plotting/test_hist_method.py
pandas/tests/plotting/test_series.py
pandas/tests/reductions/test_reductions.py
pandas/tests/reductions/test_stat_reductions.py
pandas/tests/resample/test_base.py
pandas/tests/resample/test_period_index.py
pandas/tests/resample/test_resample_api.py
pandas/tests/reshape/merge/test_join.py
pandas/tests/reshape/merge/test_merge.py
pandas/tests/reshape/merge/test_merge_asof.py
pandas/tests/reshape/merge/test_multi.py
pandas/tests/reshape/test_concat.py
pandas/tests/reshape/test_melt.py
pandas/tests/reshape/test_pivot.py
pandas/tests/reshape/test_reshape.py
pandas/tests/reshape/test_union_categoricals.py
pandas/tests/scalar/interval/test_interval.py
pandas/tests/scalar/period/test_asfreq.py
pandas/tests/scalar/period/test_period.py
pandas/tests/scalar/timedelta/test_arithmetic.py
pandas/tests/scalar/timedelta/test_construction.py
pandas/tests/scalar/timedelta/test_timedelta.py
pandas/tests/scalar/timestamp/test_comparisons.py
pandas/tests/scalar/timestamp/test_timestamp.py
pandas/tests/scalar/timestamp/test_timezones.py
pandas/tests/scalar/timestamp/test_unary_ops.py
pandas/tests/series/indexing/test_alter_index.py
pandas/tests/series/indexing/test_boolean.py
pandas/tests/series/indexing/test_datetime.py
pandas/tests/series/indexing/test_indexing.py
pandas/tests/series/indexing/test_numeric.py
pandas/tests/series/test_alter_axes.py
pandas/tests/series/test_analytics.py
pandas/tests/series/test_api.py
pandas/tests/series/test_apply.py
pandas/tests/series/test_arithmetic.py
pandas/tests/series/test_asof.py
pandas/tests/series/test_dtypes.py
pandas/tests/series/test_missing.py
pandas/tests/series/test_operators.py
pandas/tests/series/test_replace.py
pandas/tests/series/test_timeseries.py
pandas/tests/series/test_timezones.py
pandas/tests/sparse/frame/test_frame.py
pandas/tests/sparse/test_indexing.py
pandas/tests/test_base.py
pandas/tests/test_common.py
pandas/tests/test_errors.py
pandas/tests/test_lib.py
pandas/tests/test_nanops.py
pandas/tests/test_panel.py
pandas/tests/test_take.py
pandas/tests/test_window.py
pandas/tests/tools/test_numeric.py
pandas/tests/tseries/offsets/test_offsets.py
pandas/tests/tseries/offsets/test_ticks.py
pandas/tests/tseries/test_frequencies.py
pandas/tests/tseries/test_holiday.py
pandas/tests/tslibs/test_array_to_datetime.py
pandas/tests/tslibs/test_liboffsets.py
pandas/tests/tslibs/test_timedeltas.py
pandas/tests/tslibs/test_timezones.py
The text was updated successfully, but these errors were encountered: