BUG: Dtype was not changed when float was assignt to int column
State: closed

- [x] closes #26395
- [x] closes #20643
- [x] tests added / passed
- [x] passes `black pandas`
- [x] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [x] whatsnew entry

We have to keep the get_loc statement to check, if the series._set_value function does the trick. I added the dtype conversion there, to avoid implementing the same thing twice

Labels:
name: Indexing
description: Related to indexing on series/frames, not to indexes themselves
name: Dtype Conversions
description: Unexpected or buggy dtype conversions
name: Stale

Comments:
Had to check for numeric dtype, we could do this in ``validate_numeric_casting``?
Found #20643 which was not fixed completly. Adjusted the code accordingly to fix this too.
cc @jreback 

Two open points here:
- If integer/float is assigned to boolean series, which dtype is expected? Currently it is converted to object
- Through dispatching to iloc, when it is takeble but dtypes are not equal in ``iat``, we get a different error. Is this a problem?

Fixed a few tests, which were xfailing previously.
My suggestion is to start with adding in validate_numeric_casting:

```
    if issubclass(dtype.type, (np.integer, np.bool_)):
        if is_float(value) and np.isnan(value):
            raise ValueError("Cannot assign nan to integer series")
+        if is_float(value) and not value.is_integer():
+            raise ValueError("Cannot assign non-integer float to integer series")
```

That won't fix all of this, but i think is the right place to collect the relevant logic.
The issue was actually different. Did not recognize this a few days ago. This is only a problem, if the Index contains tuples as values, loc does not support this. So we get a ``KeyError``. Changed this now a bit, which should make it clearer.
@phofl can you run the indexing asvs on this.  we've optimized this portion of the code pretty hard and im not confident this is the right place to catch these cases

@jreback pls hold off on merging for a couple days so i can hopefully get a handle on this
yep agreed 
Ran indexing asvs

```
      before           after         ratio
     [50ae0bfc]       [566d7692]
     <master>         <26395>   
+      8.45±0.3ms       10.2±0.4ms     1.20  indexing.NumericSeriesIndexing.time_loc_slice(<class 'pandas.core.indexes.numeric.UInt64Index'>, 'nonunique_monotonic_inc')
+      54.3±0.8μs         63.9±8μs     1.18  indexing.NonNumericSeriesIndexing.time_getitem_pos_slice('period', 'non_monotonic')
-         105±3μs       95.1±0.3μs     0.91  indexing.DataFrameNumericIndexing.time_iloc_dups
-         256±4ms          223±7ms     0.87  indexing.NumericSeriesIndexing.time_getitem_array(<class 'pandas.core.indexes.numeric.Float64Index'>, 'unique_monotonic_inc')
-         259±9ms          219±6ms     0.85  indexing.NumericSeriesIndexing.time_getitem_lists(<class 'pandas.core.indexes.numeric.Float64Index'>, 'unique_monotonic_inc')
-         253±8ms          214±8ms     0.85  indexing.NumericSeriesIndexing.time_loc_list_like(<class 'pandas.core.indexes.numeric.Float64Index'>, 'unique_monotonic_inc')
-        261±10ms          217±7ms     0.83  indexing.NumericSeriesIndexing.time_loc_array(<class 'pandas.core.indexes.numeric.Float64Index'>, 'unique_monotonic_inc')
-         211±1μs          171±2μs     0.81  indexing_engines.NumericEngineIndexing.time_get_loc((<class 'pandas._libs.index.Int8Engine'>, <class 'numpy.int8'>), 'monotonic_incr')
-         188±7ms          152±4ms     0.81  indexing.NumericSeriesIndexing.time_getitem_lists(<class 'pandas.core.indexes.numeric.Float64Index'>, 'nonunique_monotonic_inc')
-        270±10ms          216±7ms     0.80  indexing.NumericSeriesIndexing.time_getitem_list_like(<class 'pandas.core.indexes.numeric.Float64Index'>, 'unique_monotonic_inc')
-         184±2ms          146±4ms     0.79  indexing.NumericSeriesIndexing.time_getitem_array(<class 'pandas.core.indexes.numeric.Float64Index'>, 'nonunique_monotonic_inc')
-      42.5±0.9μs         26.4±1μs     0.62  indexing.NumericSeriesIndexing.time_getitem_scalar(<class 'pandas.core.indexes.numeric.Float64Index'>, 'nonunique_monotonic_inc')
-     1.89±0.05ms      1.09±0.04ms     0.58  indexing.NumericSeriesIndexing.time_getitem_list_like(<class 'pandas.core.indexes.numeric.Float64Index'>, 'nonunique_monotonic_inc')
-     1.62±0.04ms         910±40μs     0.56  indexing.NumericSeriesIndexing.time_loc_list_like(<class 'pandas.core.indexes.numeric.Float64Index'>, 'nonunique_monotonic_inc')
-        310±10μs          168±5μs     0.54  indexing.NumericSeriesIndexing.time_loc_slice(<class 'pandas.core.indexes.numeric.Float64Index'>, 'nonunique_monotonic_inc')
-         307±8μs          164±6μs     0.54  indexing.NumericSeriesIndexing.time_getitem_slice(<class 'pandas.core.indexes.numeric.Float64Index'>, 'nonunique_monotonic_inc')
-        90.1±2μs         47.7±1μs     0.53  indexing.NumericSeriesIndexing.time_loc_scalar(<class 'pandas.core.indexes.numeric.Float64Index'>, 'nonunique_monotonic_inc')
```
If I understood you correctly, you would have expected the opposite?
This pull request is stale because it has been open for thirty days with no activity. Please update or respond to this comment if you're still interested in working on this.
@phofl can you merge master (even if this is on the back-burner, lets prevent it from drifting too far)
Yeah have to get back to this...
@phofl #39478 does something similar, same effect on test_setitem_series_bool.  Can that approach be used here too?
@phofl what's the status here?
@phofl closing as stale. reopen when ready.