diff options
| author | Stephan Hoyer <shoyer@climate.com> | 2015-10-12 16:44:00 -0700 |
|---|---|---|
| committer | Stephan Hoyer <shoyer@climate.com> | 2015-10-13 20:59:49 -0700 |
| commit | 33adec24a1403df5c47afe235ac1869a8f489489 (patch) | |
| tree | 86d2ed7f93c128f516413fb89598c24e132465bc /numpy/core/src | |
| parent | 9cc55dc7720a949cb3e6578805fe6f70906a700e (diff) | |
| download | numpy-33adec24a1403df5c47afe235ac1869a8f489489.tar.gz | |
BUG: fix casting rules for generic datetime64/timedelta64 units
Fixes GH6452
There are two types of datetime64/timedelta64 objects with generic times
units:
* NaT
* unit-less timedelta64 objects
Both of these should be safely castable to any more specific dtype. However,
more specific dtypes should not be safely castable to generic units.
Otherwise, the result of `np.datetime64('NaT')` or `np.timedelta(1)` is
entirely useless, because they can't be used in any arithmetic operations or
comparisons.
This is a regression from NumPy 1.9, where these sort of operations worked
because the default casting rules with ufuncs were less strict.
Diffstat (limited to 'numpy/core/src')
| -rw-r--r-- | numpy/core/src/multiarray/datetime.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/numpy/core/src/multiarray/datetime.c b/numpy/core/src/multiarray/datetime.c index 9e4e00e9c..264178d30 100644 --- a/numpy/core/src/multiarray/datetime.c +++ b/numpy/core/src/multiarray/datetime.c @@ -1232,12 +1232,18 @@ datetime_metadata_divides( { npy_uint64 num1, num2; - /* Generic units divide into anything */ - if (divisor->base == NPY_FR_GENERIC) { + /* + * Any unit can always divide into generic units. In other words, we + * should be able to convert generic units into any more specific unit. + */ + if (dividend->base == NPY_FR_GENERIC) { return 1; } - /* Non-generic units never divide into generic units */ - else if (dividend->base == NPY_FR_GENERIC) { + /* + * However, generic units cannot always divide into more specific units. + * We cannot safely convert datetimes with units back into generic units. + */ + else if (divisor->base == NPY_FR_GENERIC) { return 0; } @@ -1330,7 +1336,7 @@ can_cast_datetime64_units(NPY_DATETIMEUNIT src_unit, */ case NPY_SAME_KIND_CASTING: if (src_unit == NPY_FR_GENERIC || dst_unit == NPY_FR_GENERIC) { - return src_unit == dst_unit; + return src_unit == NPY_FR_GENERIC; } else { return (src_unit <= NPY_FR_D && dst_unit <= NPY_FR_D) || @@ -1344,7 +1350,7 @@ can_cast_datetime64_units(NPY_DATETIMEUNIT src_unit, */ case NPY_SAFE_CASTING: if (src_unit == NPY_FR_GENERIC || dst_unit == NPY_FR_GENERIC) { - return src_unit == dst_unit; + return src_unit == NPY_FR_GENERIC; } else { return (src_unit <= dst_unit) && @@ -1380,7 +1386,7 @@ can_cast_timedelta64_units(NPY_DATETIMEUNIT src_unit, */ case NPY_SAME_KIND_CASTING: if (src_unit == NPY_FR_GENERIC || dst_unit == NPY_FR_GENERIC) { - return src_unit == dst_unit; + return src_unit == NPY_FR_GENERIC; } else { return (src_unit <= NPY_FR_M && dst_unit <= NPY_FR_M) || @@ -1394,7 +1400,7 @@ can_cast_timedelta64_units(NPY_DATETIMEUNIT src_unit, */ case NPY_SAFE_CASTING: if (src_unit == NPY_FR_GENERIC || dst_unit == NPY_FR_GENERIC) { - return src_unit == dst_unit; + return src_unit == NPY_FR_GENERIC; } else { return (src_unit <= dst_unit) && |
