Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

removed redundant timeattr check and added tests to ensure datetime/c… #5396

Merged
merged 7 commits into from
Jul 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/src/whatsnew/latest.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ This document explains the changes made to Iris for this release
🐛 Bugs Fixed
=============

#. N/A
#. `@acchamber`_ removed some obsolete code that prevented extraction of time points
from cubes with bounded times (:pull:`5175`)


💣 Incompatible Changes
Expand Down Expand Up @@ -96,6 +97,7 @@ This document explains the changes made to Iris for this release
(:pull:`5214`)



.. comment
Whatsnew author names (@github name) in alphabetical order. Note that,
core dev names are automatically included by the common_links.inc:
Expand Down
14 changes: 0 additions & 14 deletions lib/iris/coords.py
Original file line number Diff line number Diff line change
Expand Up @@ -1464,12 +1464,6 @@ def __common_cmp__(self, other, operator_method):
# - Simple matching
me = self.point
else:
if hasattr(other, "timetuple"):
raise TypeError(
"Cannot determine whether a point lies "
"within a bounded region for "
"datetime-like objects."
)
# Point-and-bound vs number
# - Match if "within" the Cell
if operator_method in [operator.gt, operator.le]:
Expand Down Expand Up @@ -1510,14 +1504,6 @@ def contains_point(self, point):
"""
if self.bound is None:
raise ValueError("Point cannot exist inside an unbounded cell.")
if hasattr(point, "timetuple") or np.any(
[hasattr(val, "timetuple") for val in self.bound]
):
raise TypeError(
"Cannot determine whether a point lies within "
"a bounded region for datetime-like objects."
)

trexfeathers marked this conversation as resolved.
Show resolved Hide resolved
return np.min(self.bound) <= point <= np.max(self.bound)


Expand Down
163 changes: 131 additions & 32 deletions lib/iris/tests/unit/coords/test_Cell.py
acchamber marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import iris.tests as tests # isort:skip

import datetime
from unittest import mock

import cftime
import numpy as np
Expand All @@ -31,9 +30,7 @@ def assert_raises_on_comparison(self, cell, other, exception_type, regexp):
cell >= other

def test_PartialDateTime_bounded_cell(self):
# Check that bounded comparisons to a PartialDateTime
# raise an exception. These are not supported as they
# depend on the calendar.
# Check bounded cell comparisons to a PartialDateTime
dt = PartialDateTime(month=6)
cell = Cell(
datetime.datetime(2010, 1, 1),
Expand All @@ -42,8 +39,23 @@ def test_PartialDateTime_bounded_cell(self):
datetime.datetime(2011, 1, 1),
],
)
self.assertGreater(dt, cell)
self.assertGreaterEqual(dt, cell)
self.assertLess(cell, dt)
self.assertLessEqual(cell, dt)

def test_cftime_calender_bounded_cell(self):
# Check that cell comparisons fail with different calendars
dt = cftime.datetime(2010, 3, 1, calendar="360_day")
cell = Cell(
datetime.datetime(2010, 1, 1),
bound=[
datetime.datetime(2010, 1, 1),
datetime.datetime(2011, 1, 1),
],
)
self.assert_raises_on_comparison(
cell, dt, TypeError, "bounded region for datetime"
cell, dt, TypeError, "different calendars"
)

def test_PartialDateTime_unbounded_cell(self):
Expand All @@ -56,7 +68,7 @@ def test_PartialDateTime_unbounded_cell(self):
self.assertGreaterEqual(dt, cell)

def test_datetime_unbounded_cell(self):
# Check that cell comparison works with datetimes.
# Check that cell comparison works with datetimes & cftimes.
dt = datetime.datetime(2000, 6, 15)
cell = Cell(cftime.datetime(2000, 1, 1))
self.assertGreater(dt, cell)
Expand Down Expand Up @@ -87,29 +99,40 @@ def test_len_1_numpy_array(self):

class Test___eq__(tests.IrisTest):
def test_datetimelike(self):
# Check that cell equality works with objects with a "timetuple".
dt = mock.Mock(timetuple=mock.Mock())
cell = mock.MagicMock(
spec=Cell, point=datetime.datetime(2010, 3, 21), bound=None
# Check that cell equality works with different datetime objects
# using the same calendar
point = cftime.datetime(2010, 1, 1, calendar="gregorian")
cell = Cell(
datetime.datetime(2010, 1, 1),
bound=None,
)
_ = cell == dt
cell.__eq__.assert_called_once_with(dt)
self.assertEqual(cell, point)

def test_datetimelike_bounded_cell(self):
# Check that equality with a datetime-like bounded cell
# raises an error. This is not supported as it
# depends on the calendar which is not always known from
# the datetime-like bound objects.
other = mock.Mock(timetuple=mock.Mock())
# Check that cell equality works with bounded cells using different datetime objects
point = cftime.datetime(2010, 1, 1, calendar="gregorian")
cell = Cell(
datetime.datetime(2010, 1, 1),
bound=[
datetime.datetime(2010, 1, 1),
datetime.datetime(2011, 1, 1),
],
acchamber marked this conversation as resolved.
Show resolved Hide resolved
)
self.assertEqual(cell, point)

def test_datetimelike_calenders_cell(self):
# Check that equality with a cell with a different calendar
# raises an error. This is not supported
point = cftime.datetime(2010, 1, 1, calendar="360_day")
cell = Cell(
point=object(),
datetime.datetime(2010, 1, 1),
bound=[
mock.Mock(timetuple=mock.Mock()),
mock.Mock(timetuple=mock.Mock()),
datetime.datetime(2010, 1, 1),
datetime.datetime(2011, 1, 1),
],
)
with self.assertRaisesRegex(TypeError, "bounded region for datetime"):
cell == other
with self.assertRaisesRegex(TypeError, "different calendars"):
cell >= point

def test_PartialDateTime_other(self):
cell = Cell(datetime.datetime(2010, 3, 2))
Expand All @@ -120,24 +143,100 @@ def test_PartialDateTime_other(self):


class Test_contains_point(tests.IrisTest):
acchamber marked this conversation as resolved.
Show resolved Hide resolved
trexfeathers marked this conversation as resolved.
Show resolved Hide resolved
def test_datetimelike_bounded_cell(self):
point = object()
"""
Test that contains_point works for combinations of datetime,
cf.datatime, and PartialDateTime objects"""

def test_datetime_PartialDateTime_point(self):
point = PartialDateTime(month=6)
cell = Cell(
point=object(),
datetime.datetime(2010, 1, 1),
bound=[
mock.Mock(timetuple=mock.Mock()),
mock.Mock(timetuple=mock.Mock()),
datetime.datetime(2010, 1, 1),
datetime.datetime(2011, 1, 1),
],
)
with self.assertRaisesRegex(TypeError, "bounded region for datetime"):
self.assertFalse(cell.contains_point(point))

def test_datetime_cftime_standard_point(self):
point = cftime.datetime(2010, 6, 15)
cell = Cell(
datetime.datetime(2010, 1, 1),
bound=[
datetime.datetime(2010, 1, 1),
datetime.datetime(2011, 1, 1),
],
)
self.assertTrue(cell.contains_point(point))

def test_datetime_cftime_360day_point(self):
point = cftime.datetime(2010, 6, 15, calendar="360_day")
cell = Cell(
datetime.datetime(2010, 1, 1),
bound=[
datetime.datetime(2010, 1, 1),
datetime.datetime(2011, 1, 1),
],
)
with self.assertRaisesRegex(TypeError, "different calendars"):
cell.contains_point(point)

def test_datetimelike_point(self):
point = mock.Mock(timetuple=mock.Mock())
cell = Cell(point=object(), bound=[object(), object()])
with self.assertRaisesRegex(TypeError, "bounded region for datetime"):
def test_cftime_standard_PartialDateTime_point(self):
point = PartialDateTime(month=6)
cell = Cell(
cftime.datetime(2010, 1, 1),
bound=[
cftime.datetime(2010, 1, 1),
cftime.datetime(2011, 1, 1),
],
)
self.assertFalse(cell.contains_point(point))

def test_cftime_360day_PartialDateTime_point(self):
point = PartialDateTime(month=6)
cell = Cell(
cftime.datetime(2010, 1, 1, calendar="360_day"),
bound=[
cftime.datetime(2010, 1, 1, calendar="360_day"),
cftime.datetime(2011, 1, 1, calendar="360_day"),
],
)
self.assertFalse(cell.contains_point(point))

def test_cftime_standard_datetime_point(self):
point = datetime.datetime(2010, 6, 1)
cell = Cell(
cftime.datetime(2010, 1, 1),
bound=[
cftime.datetime(2010, 1, 1),
cftime.datetime(2011, 1, 1),
],
)
self.assertTrue(cell.contains_point(point))

def test_cftime_360day_datetime_point(self):
point = datetime.datetime(2010, 6, 1)
cell = Cell(
cftime.datetime(2010, 1, 1, calendar="360_day"),
bound=[
cftime.datetime(2010, 1, 1, calendar="360_day"),
cftime.datetime(2011, 1, 1, calendar="360_day"),
],
)
with self.assertRaisesRegex(TypeError, "different calendars"):
cell.contains_point(point)

def test_cftime_360_day_cftime_360day_point(self):
point = cftime.datetime(2010, 6, 15, calendar="360_day")
cell = Cell(
cftime.datetime(2010, 1, 1, calendar="360_day"),
bound=[
cftime.datetime(2010, 1, 1, calendar="360_day"),
cftime.datetime(2011, 1, 1, calendar="360_day"),
],
)
self.assertTrue(cell.contains_point(point))


class Test_numpy_comparison(tests.IrisTest):
"""
Expand Down