BUG: DataFrame.__setitem__ sometimes operating inplace
- [ ] closes #xxxx
- [ ] tests added / passed
- [ ] Ensure all linting tests pass, see [here](https://pandas.pydata.org/pandas-docs/dev/development/contributing.html#code-standards) for how to run them
- [ ] whatsnew entry

The fixed bug is the currently-xfailed test test_setitem_same_dtype_not_inplace (see #39510, which has its own subsection in the 1.3.0 release notes).  Pretty much all the other altered tests are changed because those tests rely on the incorrect behavior.

The main non-test change is the addition of an `inplace` check in `BlockManager.iset`.  We want inplace to be False when this is reached via `DataFrame.__setitem__` and True when reached via `loc/iloc.__setitem__`
cc @jorisvandenbossche  cc @phofl  @jorisvandenbossche @phofl gentle ping @jorisvandenbossche gentle ping @jreback gentle ping, doesn't sound like the others are weighing in I think this looks good. Have to figure out the boolean case in the future, but otherwise is good let me look id like to get this in before tackling #43996 gentle ping; has a bearing on #40380 cool, ideally can simplify the caching checks at some point (e.g. the maybe_update_cacher is getting more complicated). `df.assign` uses `DataFrame.__setitem__`:

https://github.com/pandas-dev/pandas/blob/965ceca9fd796940050d6fc817707bba1c4f9bff/pandas/core/frame.py#L4841-L4845

> We want inplace to be False when this is reached via `DataFrame.__setitem__` and True when reached via `loc/iloc.__setitem__`

Did this change intend to modify `df.assign`'s behavior? Or do you think `assign` should be using the in-place mode again through `loc/iloc`? @SimeonStoykovQC no, `assign` should not modify the existing data so not be in-place. I guess an in-place modification on a *copy* would be fine though @SimeonStoykovQC I misunderstood what you meant. You meant to use `[...]` instead of `.loc[:, ...]` on the copy, right? That makes sense if `.loc` is faster (which I don't know) No, the assign change is intended. It caused a 10x performance regression in some of our code. We will try to come up with a reproducer.  > No, the assign change is intended.

In the meantime, could you elaborate? What's wrong with in-place allocations if [`df.assign` is creating a deep copy (prior version 2.0)](https://github.com/pandas-dev/pandas/blob/2e218d10984e9919f0296931d92ea851c6a6faf5/pandas/core/frame.py#L4886)? Yeah I know, but this was fixed for 2.0, we had a nasty performance bottleneck in 1.5 unfortunately. Everything is back to normal with 2.0