STY: Check pytest.raises is used context manager
State: closed

Follow-up to https://github.com/pandas-dev/pandas/pull/24297#issuecomment-447675032.


Labels:
name: CI
description: Continuous Integration
name: Code Style
description: Code style, linting, code_checks

Comments:
# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/24332?src=pr&el=h1) Report
> Merging [#24332](https://codecov.io/gh/pandas-dev/pandas/pull/24332?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/216986d4691297d5cfec33b5c62be7890b9a54d7?src=pr&el=desc) will **increase** coverage by `<.01%`.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/pandas-dev/pandas/pull/24332/graphs/tree.svg?width=650&token=eZ4WkYLtcO&height=150&src=pr)](https://codecov.io/gh/pandas-dev/pandas/pull/24332?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master   #24332      +/-   ##
==========================================
+ Coverage   92.28%   92.28%   +<.01%     
==========================================
  Files         162      162              
  Lines       51831    51808      -23     
==========================================
- Hits        47830    47813      -17     
+ Misses       4001     3995       -6
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `90.69% <ø> (ø)` | :arrow_up: |
| #single | `42.99% <ø> (-0.02%)` | :arrow_down: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/24332?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/core/arrays/datetimes.py](https://codecov.io/gh/pandas-dev/pandas/pull/24332/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvYXJyYXlzL2RhdGV0aW1lcy5weQ==) | `98.24% <0%> (ø)` | :arrow_up: |
| [pandas/core/indexes/period.py](https://codecov.io/gh/pandas-dev/pandas/pull/24332/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvaW5kZXhlcy9wZXJpb2QucHk=) | `93.09% <0%> (+0.03%)` | :arrow_up: |
| [pandas/core/reshape/tile.py](https://codecov.io/gh/pandas-dev/pandas/pull/24332/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvcmVzaGFwZS90aWxlLnB5) | `94.82% <0%> (+0.06%)` | :arrow_up: |
| [pandas/tseries/offsets.py](https://codecov.io/gh/pandas-dev/pandas/pull/24332/diff?src=pr&el=tree#diff-cGFuZGFzL3RzZXJpZXMvb2Zmc2V0cy5weQ==) | `96.95% <0%> (+0.11%)` | :arrow_up: |
| [pandas/core/resample.py](https://codecov.io/gh/pandas-dev/pandas/pull/24332/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvcmVzYW1wbGUucHk=) | `96.76% <0%> (+0.18%)` | :arrow_up: |
| [pandas/core/indexes/category.py](https://codecov.io/gh/pandas-dev/pandas/pull/24332/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvaW5kZXhlcy9jYXRlZ29yeS5weQ==) | `98.65% <0%> (+0.75%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/24332?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/24332?src=pr&el=footer). Last update [216986d...33a427a](https://codecov.io/gh/pandas-dev/pandas/pull/24332?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

The check works as expected:

https://dev.azure.com/pandas-dev/pandas/_build/results?buildId=5501

I will address comments from @datapythonista and comment out the check.
There’s still something like a thousand non-compliant usages right?
> There’s still something like a thousand non-compliant usages right?

@gfyoung right, don't we need to either comment this out or run it but not fail on it?
@jreback : As I mentioned [above](https://github.com/pandas-dev/pandas/pull/24332#issuecomment-448333161), I will comment out the check now that I have confirmed that it works.

@jbrockmendel : Indeed, there are about 1000 non-compliant usages (1034 to be exact if you run the `grep` without the `-l` flag and pipe the output via `wc`)
@gfyoung sgtm.
@jreback @datapythonista : Addressed all comments, and everything is green.  PTAL.
thanks @gfyoung 

yeah prob need a way to actually implement this. I think a few PR's might just do it
This effort will likely intersect with some other work I have been doing to add more `pytest` idiom to tests, including enhancing error checks.  Thus, I'll probably tackle this along the way as I go.  Whatever is left would certainly be good first issues (to your point @datapythonista )
For reference, running the command:

~~~
grep -r -e "[[:space:]] pytest.raises" pandas/tests -l
~~~

yields:

pandas/tests/arithmetic/test_timedelta64.py
pandas/tests/arrays/categorical/test_analytics.py
pandas/tests/arrays/categorical/test_operators.py
pandas/tests/arrays/sparse/test_libsparse.py
pandas/tests/computation/test_eval.py
pandas/tests/dtypes/test_cast.py
pandas/tests/dtypes/test_common.py
pandas/tests/dtypes/test_dtypes.py
pandas/tests/frame/test_alter_axes.py
pandas/tests/frame/test_analytics.py
pandas/tests/frame/test_api.py
pandas/tests/frame/test_axis_select_reindex.py
pandas/tests/frame/test_block_internals.py
pandas/tests/frame/test_constructors.py
pandas/tests/frame/test_convert_to.py
pandas/tests/frame/test_dtypes.py
pandas/tests/frame/test_indexing.py
pandas/tests/frame/test_missing.py
pandas/tests/frame/test_mutate_columns.py
pandas/tests/frame/test_nonunique_indexes.py
pandas/tests/frame/test_quantile.py
pandas/tests/frame/test_query_eval.py
pandas/tests/frame/test_replace.py
pandas/tests/frame/test_reshape.py
pandas/tests/frame/test_sorting.py
pandas/tests/frame/test_timeseries.py
pandas/tests/frame/test_to_csv.py
pandas/tests/generic/test_generic.py
pandas/tests/generic/test_series.py
pandas/tests/groupby/test_bin_groupby.py
pandas/tests/groupby/test_filters.py
pandas/tests/groupby/test_function.py
pandas/tests/groupby/test_groupby.py
pandas/tests/groupby/test_grouping.py
pandas/tests/groupby/test_transform.py
pandas/tests/indexes/common.py
pandas/tests/indexes/datetimes/test_construction.py
pandas/tests/indexes/datetimes/test_date_range.py
pandas/tests/indexes/datetimes/test_misc.py
pandas/tests/indexes/datetimes/test_ops.py
pandas/tests/indexes/datetimes/test_partial_slicing.py
pandas/tests/indexes/datetimes/test_scalar_compat.py
pandas/tests/indexes/datetimes/test_tools.py
pandas/tests/indexes/interval/test_interval.py
pandas/tests/indexes/interval/test_interval_new.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_contains.py
pandas/tests/indexes/multi/test_drop.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/period/test_asfreq.py
pandas/tests/indexes/period/test_construction.py
pandas/tests/indexes/period/test_indexing.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/timedeltas/test_arithmetic.py
pandas/tests/indexes/timedeltas/test_construction.py
pandas/tests/indexes/timedeltas/test_ops.py
pandas/tests/indexes/timedeltas/test_partial_slicing.py
pandas/tests/indexes/timedeltas/test_timedelta.py
pandas/tests/indexes/timedeltas/test_tools.py
pandas/tests/indexing/multiindex/test_loc.py
pandas/tests/indexing/multiindex/test_partial.py
pandas/tests/indexing/multiindex/test_slice.py
pandas/tests/indexing/test_categorical.py
pandas/tests/indexing/test_chaining_and_caching.py
pandas/tests/indexing/test_floats.py
pandas/tests/indexing/test_iloc.py
pandas/tests/indexing/test_ix.py
pandas/tests/indexing/test_loc.py
pandas/tests/indexing/test_partial.py
pandas/tests/indexing/test_scalar.py
pandas/tests/io/formats/test_format.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/msgpack/test_except.py
pandas/tests/io/msgpack/test_limits.py
pandas/tests/io/msgpack/test_obj.py
pandas/tests/io/msgpack/test_pack.py
pandas/tests/io/msgpack/test_sequnpack.py
pandas/tests/io/msgpack/test_unpack.py
pandas/tests/io/parser/test_c_parser_only.py
pandas/tests/io/parser/test_textreader.py
pandas/tests/io/test_common.py
pandas/tests/io/test_packers.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_datetimelike.py
pandas/tests/plotting/test_hist_method.py
pandas/tests/plotting/test_misc.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/test_concat.py
pandas/tests/reshape/test_melt.py
pandas/tests/reshape/test_pivot.py
pandas/tests/scalar/period/test_period.py
pandas/tests/scalar/timedelta/test_timedelta.py
pandas/tests/scalar/timestamp/test_timestamp.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_loc.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_combine_concat.py
pandas/tests/series/test_constructors.py
pandas/tests/series/test_dtypes.py
pandas/tests/series/test_internals.py
pandas/tests/series/test_missing.py
pandas/tests/series/test_rank.py
pandas/tests/series/test_replace.py
pandas/tests/series/test_sorting.py
pandas/tests/series/test_timeseries.py
pandas/tests/sparse/frame/test_frame.py
pandas/tests/sparse/series/test_series.py
pandas/tests/test_algos.py
pandas/tests/test_config.py
pandas/tests/test_multilevel.py
pandas/tests/test_nanops.py
pandas/tests/test_panel.py
pandas/tests/test_sorting.py
pandas/tests/test_strings.py
pandas/tests/test_window.py
pandas/tests/tseries/offsets/test_offsets.py
pandas/tests/tseries/offsets/test_yqm_offsets.py
pandas/tests/tseries/test_frequencies.py
pandas/tests/tslibs/test_parsing.py
@gfyoung : will probably need to ignore `pytest.raises` in commented out code..

`grep -r -e "[[:space:]] pytest.raises" pandas/tests|grep -v -e "#.*pytest.raises"`

would work.

also may need to ignore `pytest raises` in skipped tests. perhaps comment them out?

@simonjayhawkins : You're right that those are edge cases we would have to tackle.  However, as we're in no rush to invoke this linting yet, let's see how many of those we have (especially once `PY2` is phased out).  Commenting out is one option, but we could also just fill in with dummy messages for the time being (so that they can remind us to populate with meaningful strings once un-skipped).
> but we could also just fill in with dummy messages for the time being

OK. that's simpler, i'll go with that approach if no objections.

> we're in no rush to invoke this linting yet

2 PRS awaiting approval, 1 PR should cover frame and another pytables, then moreless done.


following #25516
```
$ grep -r -e "[[:space:]] pytest.raises" pandas/tests -l
```
now yields
```
pandas/tests/arrays/sparse/test_libsparse.py
pandas/tests/computation/test_eval.py
pandas/tests/frame/test_nonunique_indexes.py
pandas/tests/generic/test_generic.py
pandas/tests/generic/test_series.py
pandas/tests/indexes/interval/test_interval_new.py
pandas/tests/indexing/multiindex/test_partial.py
pandas/tests/indexing/test_floats.py
pandas/tests/io/test_pytables.py
pandas/tests/io/test_sql.py
pandas/tests/series/test_constructors.py
pandas/tests/test_panel.py
```

`pandas/tests/io/test_pytables.py` should probably wait until #25004 is merged.