ENH: partial string match in query
State: closed

- [x] closes na (once proposed in #8749 but not implemented so far)
- [x] tests added / passed
- [x] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [x] whatsnew entry

This PR proposes to add partial string matching functionality to `query` method. In the proposed implementation, a query like `df.query('"alice" in person_name', partial_str_match=True)` returns rows with 'person_name' containing 'alice' in them. For other kind of queries (e.g. `'["alice", "bob"] in person_name'` or `'age == 20'`) with `partial_str_match=True` or those with `partial_str_match=False` (which is set to default for backward compatibility), results as before are returned.

Labels:
name: API Design
name: Strings
description: String extension data type and string data

Comments:
# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/26027?src=pr&el=h1) Report
> Merging [#26027](https://codecov.io/gh/pandas-dev/pandas/pull/26027?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/6de813364fd4ebfd16e2794e5ac3422d3bef87e7?src=pr&el=desc) will **decrease** coverage by `51.1%`.
> The diff coverage is `34.78%`.

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

```diff
@@             Coverage Diff             @@
##           master   #26027       +/-   ##
===========================================
- Coverage   91.82%   40.72%   -51.11%     
===========================================
  Files         175      175               
  Lines       52539    52554       +15     
===========================================
- Hits        48246    21404    -26842     
- Misses       4293    31150    +26857
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `?` | |
| #single | `40.72% <34.78%> (-0.14%)` | :arrow_down: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/26027?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/core/computation/eval.py](https://codecov.io/gh/pandas-dev/pandas/pull/26027/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvY29tcHV0YXRpb24vZXZhbC5weQ==) | `13.59% <ø> (-83.5%)` | :arrow_down: |
| [pandas/core/computation/expr.py](https://codecov.io/gh/pandas-dev/pandas/pull/26027/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvY29tcHV0YXRpb24vZXhwci5weQ==) | `61.63% <34.78%> (-26.93%)` | :arrow_down: |
| [pandas/io/formats/latex.py](https://codecov.io/gh/pandas-dev/pandas/pull/26027/diff?src=pr&el=tree#diff-cGFuZGFzL2lvL2Zvcm1hdHMvbGF0ZXgucHk=) | `0% <0%> (-100%)` | :arrow_down: |
| [pandas/io/sas/sas\_constants.py](https://codecov.io/gh/pandas-dev/pandas/pull/26027/diff?src=pr&el=tree#diff-cGFuZGFzL2lvL3Nhcy9zYXNfY29uc3RhbnRzLnB5) | `0% <0%> (-100%)` | :arrow_down: |
| [pandas/core/groupby/categorical.py](https://codecov.io/gh/pandas-dev/pandas/pull/26027/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZ3JvdXBieS9jYXRlZ29yaWNhbC5weQ==) | `0% <0%> (-100%)` | :arrow_down: |
| [pandas/tseries/plotting.py](https://codecov.io/gh/pandas-dev/pandas/pull/26027/diff?src=pr&el=tree#diff-cGFuZGFzL3RzZXJpZXMvcGxvdHRpbmcucHk=) | `0% <0%> (-100%)` | :arrow_down: |
| [pandas/tseries/converter.py](https://codecov.io/gh/pandas-dev/pandas/pull/26027/diff?src=pr&el=tree#diff-cGFuZGFzL3RzZXJpZXMvY29udmVydGVyLnB5) | `0% <0%> (-100%)` | :arrow_down: |
| [pandas/io/formats/html.py](https://codecov.io/gh/pandas-dev/pandas/pull/26027/diff?src=pr&el=tree#diff-cGFuZGFzL2lvL2Zvcm1hdHMvaHRtbC5weQ==) | `0% <0%> (-99.37%)` | :arrow_down: |
| [pandas/io/sas/sas7bdat.py](https://codecov.io/gh/pandas-dev/pandas/pull/26027/diff?src=pr&el=tree#diff-cGFuZGFzL2lvL3Nhcy9zYXM3YmRhdC5weQ==) | `0% <0%> (-91.16%)` | :arrow_down: |
| [pandas/io/sas/sas\_xport.py](https://codecov.io/gh/pandas-dev/pandas/pull/26027/diff?src=pr&el=tree#diff-cGFuZGFzL2lvL3Nhcy9zYXNfeHBvcnQucHk=) | `0% <0%> (-90.1%)` | :arrow_down: |
| ... and [132 more](https://codecov.io/gh/pandas-dev/pandas/pull/26027/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/26027?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/26027?src=pr&el=footer). Last update [6de8133...943615c](https://codecov.io/gh/pandas-dev/pandas/pull/26027?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/26027?src=pr&el=h1) Report
> Merging [#26027](https://codecov.io/gh/pandas-dev/pandas/pull/26027?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/6de813364fd4ebfd16e2794e5ac3422d3bef87e7?src=pr&el=desc) will **increase** coverage by `0.12%`.
> The diff coverage is `100%`.

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

```diff
@@            Coverage Diff             @@
##           master   #26027      +/-   ##
==========================================
+ Coverage   91.82%   91.95%   +0.12%     
==========================================
  Files         175      175              
  Lines       52539    52427     -112     
==========================================
- Hits        48246    48211      -35     
+ Misses       4293     4216      -77
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `90.51% <100%> (+0.13%)` | :arrow_up: |
| #single | `40.72% <58.33%> (-0.14%)` | :arrow_down: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/26027?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/core/computation/eval.py](https://codecov.io/gh/pandas-dev/pandas/pull/26027/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvY29tcHV0YXRpb24vZXZhbC5weQ==) | `97.08% <ø> (ø)` | :arrow_up: |
| [pandas/core/computation/expr.py](https://codecov.io/gh/pandas-dev/pandas/pull/26027/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvY29tcHV0YXRpb24vZXhwci5weQ==) | `96.83% <100%> (+8.27%)` | :arrow_up: |
| [pandas/io/gbq.py](https://codecov.io/gh/pandas-dev/pandas/pull/26027/diff?src=pr&el=tree#diff-cGFuZGFzL2lvL2dicS5weQ==) | `75% <0%> (-12.5%)` | :arrow_down: |
| [pandas/util/\_doctools.py](https://codecov.io/gh/pandas-dev/pandas/pull/26027/diff?src=pr&el=tree#diff-cGFuZGFzL3V0aWwvX2RvY3Rvb2xzLnB5) | `12% <0%> (-0.88%)` | :arrow_down: |
| [pandas/core/sparse/frame.py](https://codecov.io/gh/pandas-dev/pandas/pull/26027/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvc3BhcnNlL2ZyYW1lLnB5) | `95.49% <0%> (-0.21%)` | :arrow_down: |
| [pandas/plotting/\_core.py](https://codecov.io/gh/pandas-dev/pandas/pull/26027/diff?src=pr&el=tree#diff-cGFuZGFzL3Bsb3R0aW5nL19jb3JlLnB5) | `83.76% <0%> (-0.09%)` | :arrow_down: |
| [pandas/io/common.py](https://codecov.io/gh/pandas-dev/pandas/pull/26027/diff?src=pr&el=tree#diff-cGFuZGFzL2lvL2NvbW1vbi5weQ==) | `91.83% <0%> (-0.05%)` | :arrow_down: |
| [pandas/core/computation/ops.py](https://codecov.io/gh/pandas-dev/pandas/pull/26027/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvY29tcHV0YXRpb24vb3BzLnB5) | `95.62% <0%> (-0.04%)` | :arrow_down: |
| [pandas/core/computation/align.py](https://codecov.io/gh/pandas-dev/pandas/pull/26027/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvY29tcHV0YXRpb24vYWxpZ24ucHk=) | `97.8% <0%> (-0.03%)` | :arrow_down: |
| [pandas/core/reshape/melt.py](https://codecov.io/gh/pandas-dev/pandas/pull/26027/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvcmVzaGFwZS9tZWx0LnB5) | `97.47% <0%> (-0.03%)` | :arrow_down: |
| ... and [47 more](https://codecov.io/gh/pandas-dev/pandas/pull/26027/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/26027?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/26027?src=pr&el=footer). Last update [6de8133...b120f59](https://codecov.io/gh/pandas-dev/pandas/pull/26027?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

I am -1 on this idea generally. This is very easily implemented using the ``.str`` methods and ``.query`` doesn't need even more magic (note there is NO benefit to using string methods in .query anyhow as numexpr is not used).