Skip to content

Commit

Permalink
Remove deprecated Date, Time and Datetime behaviour (#1736)
Browse files Browse the repository at this point in the history
This PR updates the `Date`, `Time` and `Datetime` trait types for
previous deprecations:

- the `Date` trait type will now no longer accept `datetime` instances
unless `allow_datetime=True` is used
- the `Date`, `Time` and `Datetime` trait types will now no longer
accept a value of `None` unless `allow_none=True` is used

**Checklist**
- [x] Tests
- [x] Update API reference (`docs/source/traits_api_reference`) - no
changes needed
- [x] Update User manual (`docs/source/traits_user_manual`)
- [x] Update type annotation hints in stub files - no changes needed
  • Loading branch information
mdickinson committed Apr 17, 2023
1 parent 8851999 commit 7eefaa2
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 141 deletions.
6 changes: 3 additions & 3 deletions docs/source/traits_user_manual/defining.rst
Original file line number Diff line number Diff line change
Expand Up @@ -307,11 +307,11 @@ the table.
| Constant | Constant(*value*\ [, \*\*\ *metadata*]) |
+------------------+----------------------------------------------------------+
| Date | Date(*value*\ [, *default_value* = None, |
| | *allow_datetime* = None, *allow_none* = None, |
| | *allow_datetime* = False, *allow_none* = False, |
| | \*\*\ *metadata*]) |
+------------------+----------------------------------------------------------+
| Datetime | Datetime(*value*\ [, *default_value* = None, |
| | *allow_none* = None, \*\*\ *metadata*]) |
| | *allow_none* = False, \*\*\ *metadata*]) |
+------------------+----------------------------------------------------------+
| Dict | Dict([*key_trait* = None, *value_trait* = None, |
| | *value* = None, *items* = True, \*\*\ *metadata*]) |
Expand Down Expand Up @@ -394,7 +394,7 @@ the table.
| This | n/a |
+------------------+----------------------------------------------------------+
| Time | Time(*value*\ [, *default_value* = None, |
| | *allow_none* = None, \*\*\ *metadata*]) |
| | *allow_none* = False, \*\*\ *metadata*]) |
+------------------+----------------------------------------------------------+
| ToolbarButton | ToolbarButton([*label* = '', *image* = None, *style* = |
| | 'toolbar', *orientation* = 'vertical', *width_padding* = |
Expand Down
39 changes: 13 additions & 26 deletions traits/tests/test_date.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,28 +71,22 @@ def test_assign_non_date(self):
with self.assertRaises(TraitError) as exception_context:
obj.simple_date = "1975-2-13"
message = str(exception_context.exception)
self.assertIn("must be a date or None, but", message)
self.assertIn("must be a non-datetime date, but", message)

def test_assign_none_with_allow_none_not_given(self):
obj = HasDateTraits(simple_date=UNIX_EPOCH)
self.assertIsNotNone(obj.simple_date)
with self.assertWarns(DeprecationWarning) as warnings_cm:
with self.assertRaises(TraitError) as exception_context:
obj.simple_date = None
self.assertIsNone(obj.simple_date)

_, _, this_module = __name__.rpartition(".")
self.assertIn(this_module, warnings_cm.filename)
self.assertIn(
"None will no longer be accepted",
str(warnings_cm.warning),
)
self.assertEqual(obj.simple_date, UNIX_EPOCH)
message = str(exception_context.exception)
self.assertIn("must be a non-datetime date, but", message)

def test_assign_none_with_allow_none_false(self):
obj = HasDateTraits(none_prohibited=UNIX_EPOCH)
with self.assertRaises(TraitError) as exception_context:
obj.none_prohibited = None
message = str(exception_context.exception)
self.assertIn("must be a date, but", message)
self.assertIn("must be a non-datetime date, but", message)

def test_assign_none_with_allow_none_true(self):
obj = HasDateTraits(none_allowed=UNIX_EPOCH)
Expand All @@ -106,7 +100,7 @@ def test_assign_datetime_with_allow_datetime_false(self):
with self.assertRaises(TraitError) as exception_context:
obj.datetime_prohibited = test_datetime
message = str(exception_context.exception)
self.assertIn("must be a non-datetime date or None, but", message)
self.assertIn("must be a non-datetime date, but", message)

def test_assign_datetime_with_allow_datetime_true(self):
test_datetime = datetime.datetime(1975, 2, 13)
Expand All @@ -117,21 +111,14 @@ def test_assign_datetime_with_allow_datetime_true(self):
def test_assign_datetime_with_allow_datetime_not_given(self):
# For traits where "allow_datetime" is not specified, a
# DeprecationWarning should be issued on assignment of datetime.
test_date = datetime.date(2023, 1, 11)
test_datetime = datetime.datetime(1975, 2, 13)
obj = HasDateTraits()
with self.assertWarns(DeprecationWarning) as warnings_cm:
# Note: the warning depends on the type, not the value; this case
# should warn even though the time component of the datetime is
# zero.
obj = HasDateTraits(simple_date=test_date)
with self.assertRaises(TraitError) as exception_context:
obj.simple_date = test_datetime
self.assertEqual(obj.simple_date, test_datetime)

_, _, this_module = __name__.rpartition(".")
self.assertIn(this_module, warnings_cm.filename)
self.assertIn(
"datetime instances will no longer be accepted",
str(warnings_cm.warning),
)
self.assertEqual(obj.simple_date, test_date)
message = str(exception_context.exception)
self.assertIn("must be a non-datetime date, but", message)

def test_allow_none_false_allow_datetime_false(self):
obj = HasDateTraits(strict=UNIX_EPOCH)
Expand Down
19 changes: 7 additions & 12 deletions traits/tests/test_datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,34 +63,29 @@ def test_assign_non_datetime(self):
with self.assertRaises(TraitError) as exception_context:
obj.simple_datetime = "2021-02-05 12:00:00"
message = str(exception_context.exception)
self.assertIn("must be a datetime or None, but", message)
self.assertIn("must be a datetime, but", message)

def test_assign_date(self):
obj = HasDatetimeTraits()
with self.assertRaises(TraitError) as exception_context:
obj.simple_datetime = datetime.date(1975, 2, 13)
message = str(exception_context.exception)
self.assertIn("must be a datetime or None, but", message)
self.assertIn("must be a datetime, but", message)
self.assertIsNone(obj.simple_datetime)

def test_assign_none_with_allow_none_not_given(self):
obj = HasDatetimeTraits(simple_datetime=UNIX_EPOCH)
self.assertIsNotNone(obj.simple_datetime)
with self.assertWarns(DeprecationWarning) as warnings_cm:
with self.assertRaises(TraitError) as exception_context:
obj.simple_datetime = None
self.assertIsNone(obj.simple_datetime)

_, _, this_module = __name__.rpartition(".")
self.assertIn(this_module, warnings_cm.filename)
self.assertIn(
"None will no longer be accepted",
str(warnings_cm.warning),
)
self.assertEqual(obj.simple_datetime, UNIX_EPOCH)
message = str(exception_context.exception)
self.assertIn("must be a datetime, but", message)

def test_assign_none_with_allow_none_false(self):
obj = HasDatetimeTraits(none_prohibited=UNIX_EPOCH)
with self.assertRaises(TraitError) as exception_context:
obj.none_prohibited = None
self.assertEqual(obj.none_prohibited, UNIX_EPOCH)
message = str(exception_context.exception)
self.assertIn("must be a datetime, but", message)

Expand Down
19 changes: 7 additions & 12 deletions traits/tests/test_time.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,34 +63,29 @@ def test_assign_non_time(self):
with self.assertRaises(TraitError) as exception_context:
obj.simple_time = "12:00:00"
message = str(exception_context.exception)
self.assertIn("must be a time or None, but", message)
self.assertIn("must be a time, but", message)

def test_assign_datetime(self):
obj = HasTimeTraits()
with self.assertRaises(TraitError) as exception_context:
obj.simple_time = datetime.datetime(1975, 2, 13)
message = str(exception_context.exception)
self.assertIn("must be a time or None, but", message)
self.assertIn("must be a time, but", message)
self.assertIsNone(obj.simple_time)

def test_assign_none_with_allow_none_not_given(self):
obj = HasTimeTraits(simple_time=UNIX_EPOCH)
self.assertIsNotNone(obj.simple_time)
with self.assertWarns(DeprecationWarning) as warnings_cm:
with self.assertRaises(TraitError) as exception_context:
obj.simple_time = None
self.assertIsNone(obj.simple_time)

_, _, this_module = __name__.rpartition(".")
self.assertIn(this_module, warnings_cm.filename)
self.assertIn(
"None will no longer be accepted",
str(warnings_cm.warning),
)
self.assertEqual(obj.simple_time, UNIX_EPOCH)
message = str(exception_context.exception)
self.assertIn("must be a time, but", message)

def test_assign_none_with_allow_none_false(self):
obj = HasTimeTraits(none_prohibited=UNIX_EPOCH)
with self.assertRaises(TraitError) as exception_context:
obj.none_prohibited = None
self.assertEqual(obj.none_prohibited, UNIX_EPOCH)
message = str(exception_context.exception)
self.assertIn("must be a time, but", message)

Expand Down

0 comments on commit 7eefaa2

Please sign in to comment.