def maybe_upcast_putmask(result, mask, other):
if not isinstance(result, np.ndarray):<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>if mask.any():<EOL><INDENT>if is_datetimelike(result.dtype):<EOL><INDENT>if is_scalar(other):<EOL><INDENT>if isna(other):<EOL><INDENT>other = result.dtype.type('<STR_LIT>')<EOL><DEDENT>elif is_integer(other):<EOL><INDENT>other = np.array(other, dtype=result.dtype)<EOL><DEDENT><DEDENT>elif is_integer_dtype(other):<EOL><INDENT>other = np.array(other, dtype=result.dtype)<EOL><DEDENT><DEDENT>def changeit():<EOL><INDENT>try:<EOL><INDENT>om = other[mask]<EOL>om_at = om.astype(result.dtype)<EOL>if (om == om_at).all():<EOL><INDENT>new_result = result.values.copy()<EOL>new_result[mask] = om_at<EOL>result[:] = new_result<EOL>return result, False<EOL><DEDENT><DEDENT>except Exception:<EOL><INDENT>pass<EOL><DEDENT>r, _ = maybe_upcast(result, fill_value=other, copy=True)<EOL>np.place(r, mask, other)<EOL>return r, True<EOL><DEDENT>new_dtype, _ = maybe_promote(result.dtype, other)<EOL>if new_dtype != result.dtype:<EOL><INDENT>if (is_scalar(other) or<EOL>(isinstance(other, np.ndarray) and other.ndim < <NUM_LIT:1>)):<EOL><INDENT>if isna(other):<EOL><INDENT>return changeit()<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if isna(other).any():<EOL><INDENT>return changeit()<EOL><DEDENT><DEDENT><DEDENT>try:<EOL><INDENT>np.place(result, mask, other)<EOL><DEDENT>except Exception:<EOL><INDENT>return changeit()<EOL><DEDENT><DEDENT>return result, False<EOL>
A safe version of putmask that potentially upcasts the result.
The result is replaced with the first N elements of other,
where N is the number of True values in mask.
If the length of other is shorter than N, other will be repeated.

Parameters
----------
result : ndarray
    The destination array. This will be mutated in-place if no upcasting is
    necessary.
mask : boolean ndarray
other : ndarray or scalar
    The source array or value

Returns
-------
result : ndarray
changed : boolean
    Set to true if the result array was upcasted

Examples
--------
>>> result, _ = maybe_upcast_putmask(np.arange(1,6),
np.array([False, True, False, True, True]), np.arange(21,23))
>>> result
array([1, 21, 3, 22, 21])