diff --git a/AUTHORS b/AUTHORS index d8a07764a5..3e96b5759c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -166,4 +166,5 @@ Nicholas Dupoux John Eskew Juanan Pereira Clinton Blackburn -Dennis Jen \ No newline at end of file +Dennis Jen +Filippo Valsorda diff --git a/common/lib/xmodule/xmodule/fields.py b/common/lib/xmodule/xmodule/fields.py index 74d7a61b7d..a1b7496bf8 100644 --- a/common/lib/xmodule/xmodule/fields.py +++ b/common/lib/xmodule/xmodule/fields.py @@ -80,6 +80,8 @@ class Date(Field): else: raise TypeError("Cannot convert {!r} to json".format(value)) + enforce_type = from_json + TIMEDELTA_REGEX = re.compile(r'^((?P\d+?) day(?:s?))?(\s)?((?P\d+?) hour(?:s?))?(\s)?((?P\d+?) minute(?:s)?)?(\s)?((?P\d+?) second(?:s)?)?$') @@ -117,6 +119,15 @@ class Timedelta(Field): values.append("%d %s" % (cur_value, attr)) return ' '.join(values) + def enforce_type(self, value): + """ + Ensure that when set explicitly the Field is set to a timedelta + """ + if isinstance(value, datetime.timedelta) or value is None: + return value + + return self.from_json(value) + class RelativeTime(Field): """ @@ -219,3 +230,12 @@ class RelativeTime(Field): if len(stringified) == 7: stringified = '0' + stringified return stringified + + def enforce_type(self, value): + """ + Ensure that when set explicitly the Field is set to a timedelta + """ + if isinstance(value, datetime.timedelta) or value is None: + return value + + return self.from_json(value) diff --git a/common/lib/xmodule/xmodule/tests/test_fields.py b/common/lib/xmodule/xmodule/tests/test_fields.py index 47318ee4c5..d00d8f85c7 100644 --- a/common/lib/xmodule/xmodule/tests/test_fields.py +++ b/common/lib/xmodule/xmodule/tests/test_fields.py @@ -41,6 +41,19 @@ class DateTest(unittest.TestCase): DateTest.date.from_json("2013-01-01T00:00:00+01:00"), datetime.timedelta(hours=1, seconds=1)) + def test_enforce_type(self): + self.assertEqual(DateTest.date.enforce_type(None), None) + self.assertEqual(DateTest.date.enforce_type(""), None) + self.assertEqual(DateTest.date.enforce_type("2012-12-31T23:00:01"), + datetime.datetime(2012, 12, 31, 23, 0, 1, tzinfo=UTC())) + self.assertEqual(DateTest.date.enforce_type(1234567890000), + datetime.datetime(2009, 2, 13, 23, 31, 30, tzinfo=UTC())) + self.assertEqual(DateTest.date.enforce_type( + datetime.datetime(2014, 5, 9, 21, 1, 27, tzinfo=UTC())), + datetime.datetime(2014, 5, 9, 21, 1, 27, tzinfo=UTC())) + with self.assertRaises(TypeError): + DateTest.date.enforce_type([1]) + def test_return_None(self): self.assertIsNone(DateTest.date.from_json("")) self.assertIsNone(DateTest.date.from_json(None)) @@ -102,6 +115,16 @@ class TimedeltaTest(unittest.TestCase): datetime.timedelta(days=1, seconds=46799) ) + def test_enforce_type(self): + self.assertEqual(TimedeltaTest.delta.enforce_type(None), None) + self.assertEqual(TimedeltaTest.delta.enforce_type( + datetime.timedelta(days=1, seconds=46799)), + datetime.timedelta(days=1, seconds=46799)) + self.assertEqual(TimedeltaTest.delta.enforce_type('1 day 46799 seconds'), + datetime.timedelta(days=1, seconds=46799)) + with self.assertRaises(TypeError): + TimedeltaTest.delta.enforce_type([1]) + def test_to_json(self): self.assertEqual( '1 days 46799 seconds', @@ -143,6 +166,16 @@ class RelativeTimeTest(unittest.TestCase): with self.assertRaises(ValueError): RelativeTimeTest.delta.from_json("77:77:77") + def test_enforce_type(self): + self.assertEqual(RelativeTimeTest.delta.enforce_type(None), None) + self.assertEqual(RelativeTimeTest.delta.enforce_type( + datetime.timedelta(days=1, seconds=46799)), + datetime.timedelta(days=1, seconds=46799)) + self.assertEqual(RelativeTimeTest.delta.enforce_type('0:05:07'), + datetime.timedelta(seconds=307)) + with self.assertRaises(TypeError): + RelativeTimeTest.delta.enforce_type([1]) + def test_to_json(self): self.assertEqual( "01:02:03", diff --git a/requirements/edx/github.txt b/requirements/edx/github.txt index b0c77e8018..a70b5cd04d 100644 --- a/requirements/edx/github.txt +++ b/requirements/edx/github.txt @@ -17,7 +17,7 @@ -e git+https://github.com/appliedsec/pygeoip.git@95e69341cebf5a6a9fbf7c4f5439d458898bdc3b#egg=pygeoip # Our libraries: --e git+https://github.com/edx/XBlock.git@aed7a2c51a59836e435259ad0fb41f8e865fa530#egg=XBlock +-e git+https://github.com/edx/XBlock.git@f0e53538be7ce90584a03cc7dd3f06bd43e12ac2#egg=XBlock -e git+https://github.com/edx/codejail.git@71f5c5616e2a73ae8cecd1ff2362774a773d3665#egg=codejail -e git+https://github.com/edx/diff-cover.git@v0.5.0#egg=diff_cover -e git+https://github.com/edx/js-test-tool.git@v0.1.5#egg=js_test_tool