ENH: add validate argument to merge
State: closed

 - [x] closes #16270 
 - [x] tests added / passed
 - [x] passes ``git diff upstream/master --name-only -- '*.py' | flake8 --diff``
 - [x] whatsnew entry

Open question: does not currently check for whether "many" side of a merge is in fact many. I can't think of a case where I'm doing a one-to-many merge and I'd be worried if it was in fact one-to-one, but open to alternate opinions. 

Labels:
name: Enhancement
name: Reshaping
description: Concat, Merge/Join, Stack/Unstack, Explode

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

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

```diff
@@            Coverage Diff             @@
##           master   #16275      +/-   ##
==========================================
- Coverage   90.34%   90.33%   -0.02%     
==========================================
  Files         167      167              
  Lines       50908    50935      +27     
==========================================
+ Hits        45994    46011      +17     
- Misses       4914     4924      +10
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `88.12% <92.59%> (ø)` | :arrow_up: |
| #single | `40.27% <3.7%> (-0.13%)` | :arrow_down: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/16275?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/core/frame.py](https://codecov.io/gh/pandas-dev/pandas/pull/16275?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZnJhbWUucHk=) | `97.59% <ø> (-0.1%)` | :arrow_down: |
| [pandas/core/reshape/merge.py](https://codecov.io/gh/pandas-dev/pandas/pull/16275?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvcmVzaGFwZS9tZXJnZS5weQ==) | `93.89% <92.59%> (-0.06%)` | :arrow_down: |
| [pandas/io/gbq.py](https://codecov.io/gh/pandas-dev/pandas/pull/16275?src=pr&el=tree#diff-cGFuZGFzL2lvL2dicS5weQ==) | `25% <0%> (-58.34%)` | :arrow_down: |
| [pandas/core/common.py](https://codecov.io/gh/pandas-dev/pandas/pull/16275?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvY29tbW9uLnB5) | `91.03% <0%> (+0.34%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/16275?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/16275?src=pr&el=footer). Last update [ea56550...e5a6ee1](https://codecov.io/gh/pandas-dev/pandas/pull/16275?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/16275?src=pr&el=h1) Report
> Merging [#16275](https://codecov.io/gh/pandas-dev/pandas/pull/16275?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/a6fcec6c1a8ef5fe1079cfc95e44bea9d76aa51a?src=pr&el=desc) will **increase** coverage by `0.03%`.
> The diff coverage is `100%`.

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

```diff
@@            Coverage Diff             @@
##           master   #16275      +/-   ##
==========================================
+ Coverage   90.38%   90.41%   +0.03%     
==========================================
  Files         161      161              
  Lines       50999    51024      +25     
==========================================
+ Hits        46096    46134      +38     
+ Misses       4903     4890      -13
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `88.25% <100%> (+0.03%)` | :arrow_up: |
| #single | `40.17% <4%> (-0.02%)` | :arrow_down: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/16275?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/core/frame.py](https://codecov.io/gh/pandas-dev/pandas/pull/16275?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZnJhbWUucHk=) | `97.69% <ø> (ø)` | :arrow_up: |
| [pandas/core/reshape/merge.py](https://codecov.io/gh/pandas-dev/pandas/pull/16275?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvcmVzaGFwZS9tZXJnZS5weQ==) | `94.19% <100%> (+0.24%)` | :arrow_up: |
| [pandas/core/indexes/datetimes.py](https://codecov.io/gh/pandas-dev/pandas/pull/16275?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvaW5kZXhlcy9kYXRldGltZXMucHk=) | `95.33% <0%> (+0.09%)` | :arrow_up: |
| [pandas/plotting/\_converter.py](https://codecov.io/gh/pandas-dev/pandas/pull/16275?src=pr&el=tree#diff-cGFuZGFzL3Bsb3R0aW5nL19jb252ZXJ0ZXIucHk=) | `65.05% <0%> (+1.81%)` | :arrow_up: |

------

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

@jreback I'm not sure the code in the PR checklist (`git diff upstream/master --name-only -- '*.py' | flake8 --diff`) works right. I don't get any errors with that, but clearly have flake8 errors (as evident from Travis tests). 
http://pandas.pydata.org/pandas-docs/stable/contributing.html#python-pep8
@jreback thanks -- but on my system I got no errors, when I had trailing white space and excessive empty lines between lines. I think the command should be `git diff master  -- '*.py' |flake8 --diff`, no?
if u read the doc it explains what upstream/master is
I'm fine with upstream/master (I was copying off doc which just has master). I think the problem is the `--name-only` option. So should be `git diff upstream/master -- '*.py' | flake8 --diff`. 
> This command will catch any stylistic errors in your changes specifically, but be beware it may not catch all of them. For example, if you delete the only usage of an imported function, it is stylistically incorrect to import an unused function. However, style-checking the diff will not catch this because the actual import is not part of the diff. Thus, for completeness, you should run this command, though it will take longer:

> git diff master --name-only -- '*.py' | grep 'pandas/' | xargs -r flake8

It's not even catching local stylistic issues. May be an order of arguments problem. 

![screen shot 2017-05-07 at 1 32 03 pm](https://cloud.githubusercontent.com/assets/9683693/25784890/a7c7ae1a-3329-11e7-8f28-8e716737490b.png)


I have this an alias and it works like a charm: ``git diff master --name-only -- '*.py' | grep 'pandas/' | xargs -r flake8``

yeah arg ordering does sometimes matter.
So maybe we need to change the check box command. Should i open as issue?
you can just do a PR (also make sure the constributing docs are consistent).
can you add a small section in merge docs (and link from the doc-string to this). Also an example in the doc-string would be good as well. Finally there is an existing warning in the docs somewhat about this (e.g. checking for duplicates), can you revise.
yep
@jorisvandenbossche @jreback Think I covered all suggestions!
@nickeubank Thanks!
@nickeubank I just noticed the MergeError comment, which I think you actually did nod not change? (only in the doc) 

So maybe we can do a follow-up PR if we want to change this from a ValueError to a MergeError. In any case, if we use this error, we also have to move it to `pandas.errors` module for public exposure. And mention it in the docstring that this error is raised.
I agree. let's change ValueError -> MergeError (and then add MergeError to ``pandas.errors``); also may need a doc-string :>
@jreback @jorisvandenbossche ugh, sorry -- I updated it but apparently didn't push the commit. Will open new PR.