API: Coerce None according to the dtype of the container

This pull request fixes #7939 by ensuring that None coercion always obeys the following rules:

1. If the container is numeric, None should be coerced to NaN
2. If the container is for time data, None should be coerced to NaT
3. If the container contains heterogenous data (i.e. objects), None should be preserved.

## Old behaviour examples

### Assigning None in integer containers
None is sometimes preserved, sometimes coerced to NaN, and sometimes causes an error.

```python
>>> s = Series([1, 2, 3])
>>> s[0] = None # error

>>> s = Series([1, 2, 3])
>>> s.loc[0] = None
>>> s
0    None
1       2
2       3
dtype: object

>>> s = Series([1, 2, 3])
>>> s[s == 1] = None
>>> s
0   NaN
1     2
2     3
dtype: float64

>>> s = Series([1, 2, 3])
>>> s.loc[s == 1] = None
0    None
1       2
2       3
dtype: object

```

Datetimes are similar.

### Assigning None in object containers
None is sometimes preserved, and sometimes coerced.

```python
>>> s = Series(["a", "b", "c"])
>>> s[0] = None
0    None
1       b
2       c
dtype: object

>>> s = Series(["a", "b", "c"])
>>> s.loc[0] = None
0    None
1       b
2       c
dtype: object

>>> s = Series(["a", "b", "c"])
>>> s[s == 'a'] = None
0    NaN
1      b
2      c
dtype: object

>>> s = Series(["a", "b", "c"])
>>> s.loc[s == 'a'] = None
0    None
1       b
2       c
dtype: object
```

## New behaviour examples

### None is always coerced to NaN in integer containers

```python
>>> s = Series([1, 2, 3])
>>> s[0] = None
0    NaN
1      2
2      3
dtype: float64

>>> s = Series([1, 2, 3])
>>> s.loc[0] = None # same

>>> s = Series([1, 2, 3])
>>> s[s == 1] = None # same

>>> s = Series([1, 2, 3])
>>> s.loc[s == 1] = None # same
```

### None is always preserved in object containers

```python
>>> s = Series(["a", "b", "c"])
>>> s[0] = None
0    None
1       b
2       c
dtype: object

>>> s = Series(["a", "b", "c"])
>>> s.loc[0] = None # same

>>> s = Series(["a", "b", "c"])
>>> s[s == 'a'] = None

>>> s = Series(["a", "b", "c"])
>>> s.loc[s == 'a'] = None # same
```
perhaps in this case you migh use ``equals`` which is specifically tailored to compare (well nans) depending on the dtype vagarities of numpy. You can also check for specific values, 
but dont' use ``math``, use ``np.nan(value)`` or ``value == None`` for an exact comparision.
You can also double check dtypes on the result.

Make a general comparision function and use it for testing.


```
In [2]: Series([np.nan,"a"]).equals(Series([None,"a"]))
Out[2]: False

In [3]: Series([np.nan,1]).equals(Series([None,1]))
Out[3]: True
```