BUG: CoW - correctly track references for chained operations
State: closed

I encountered a bug in the initial implementation of https://github.com/pandas-dev/pandas/pull/46958/ in case of chaining operations or methods (all the tests that I added were always only testing one indexing operation / method at a time ...), in the case that each step in the chain works with a view. 

Consider the following chaining (using `[:]` as the simplest way to get a view, but so this can be any indexing operation that returns a view or method that returns a view):

```
subset = df[:][:]
```

If you think of this as the following in two steps (except that `temp` actually is a named variable in practice):

```
temp = df[:]
subset = temp[:]
```

then the explanation is as follows: when creating `subset`, the Manager of `subset` keeps a weakref to the blocks of `temp` (so we know that `subset` is viewing other data and can trigger CoW when needed). `temp` itself also has a weakref to the parent `df` (so that we know that `df` is being viewed by using `getweakrefcount`, and can trigger CoW when needed). 
However, when you actually do this in a chaining way, `temp` gets cleaned up since nothing is referencing it with a hard reference (only a weakref). As a result `subset` has a weakref to a dead object, and `df` is not being tracked by anything, and so modifying `df` would not trigger CoW, incorrectly also mutating the viewing `subset`. 

The way I solved this for now is to also keep a hard reference to the parent BlockManager (called `parent` in this PR) when needed (in case of views), in addition to the weakrefs to the Blocks. This cannot replace the weakrefs, because we use the ability to check for weakrefs to know if we need CoW or not (for the case of modifying the parent). 

In general, I think this is fine to keep this hard reference as well, since we only do it when we _share_ data, and thus the data itself would be kept alive anyway, i.e. in general we this wouldn't cause keeping extra data in memory that would otherwise be cleaned-up (the additional hard reference is only to keep the intermediate Block(Manager) alive as well, in addition to the array). 
I can only think of the case where you would construct or read data and directly select a subset (eg `df = pd.read_csv(..)[col]` where this would now keep all data read alive instead of only the selected column). But I made sure to only populate this parent if actually using CoW, and on the short term I think correctness is more important (we can try to optimize this later).


- [x] [Tests added and passed](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#writing-tests) if fixing a bug or adding a new feature
- [x] All [code checks passed](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#pre-commit).
- [x] Added [type annotations](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#type-hints) to new arguments/methods/functions.
- [ ] Added an entry in the latest `doc/source/whatsnew/vX.X.X.rst` file if fixing a bug or adding a new feature.


Labels:
name: Bug
name: Copy / view semantics

Comments:
Yes, this should support arbitrarily deep nesting (the mechanism to keep the previous intermediate object alive _if_ the result is a view, should work for more than 2 steps as well). I could add one test (but without then checking all different ways to get a view) to confirm that. 
```
mypy.....................................................................Failed
- hook id: mypy
- exit code: 1

pandas/tests/copy_view/test_indexing.py:563: error: Slice index must be an integer or None  [misc]
Found 1 error in 1 file (checked 1398 source files)
```
@phofl thanks for the annoying typing fix! 
Otherwise this is ready to merge?
Yep is ready imo, @mroeschke any comments?
BTW, this was tagged as 1.5.x, because it's a rather serious bug in the new CoW implementation (but so it's not a regression, and typically we don't backport normal bugs). I think think it would be nice to include it, but given that we still need to improve the CoW implementation (use it in more places etc), it might be likely we will have to ask people to install nightly / main version anyway for testing CoW, so it's maybe not super crucial to include it in 1.5.x (although I would personally still prefer to include it)
I think we included fixes for new features quite regularly lately. Ea backed indexes is something that comes to mind for the 1.4.x series