From 048203875617175a74c49f49958522c9bd655e77 Mon Sep 17 00:00:00 2001 From: Filippo Valsorda Date: Sat, 5 Apr 2014 01:07:58 +0200 Subject: [PATCH 1/5] Enforce type of the XBlocks Fields when set This updates the XBlock dependency to edX/XBlock@*** and add the newly introduced enforce_type methods --- common/lib/xmodule/xmodule/fields.py | 25 +++++++++++++++++++++---- requirements/edx/github.txt | 2 +- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/common/lib/xmodule/xmodule/fields.py b/common/lib/xmodule/xmodule/fields.py index 74d7a61b7d..561d37145d 100644 --- a/common/lib/xmodule/xmodule/fields.py +++ b/common/lib/xmodule/xmodule/fields.py @@ -68,10 +68,7 @@ class Date(Field): """ if value is None: return None - if isinstance(value, time.struct_time): - # struct_times are always utc - return time.strftime('%Y-%m-%dT%H:%M:%SZ', value) - elif isinstance(value, datetime.datetime): + if isinstance(value, datetime.datetime): if value.tzinfo is None or value.utcoffset().total_seconds() == 0: # isoformat adds +00:00 rather than Z return value.strftime('%Y-%m-%dT%H:%M:%SZ') @@ -80,6 +77,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 +116,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 +227,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/requirements/edx/github.txt b/requirements/edx/github.txt index b0c77e8018..cfc9cdd88b 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/FiloSottile/XBlock.git@a9158e9887217abe27e451d1ff82c0d9f98c0bd6#egg=XBlock # TODO: put here the edx/XBlock#200 merge commit -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 From 5edfc479b1fd9121305f9be572a17fad4bdde40c Mon Sep 17 00:00:00 2001 From: Filippo Valsorda Date: Fri, 9 May 2014 22:36:15 +0200 Subject: [PATCH 2/5] Add xmodule fields enforce_type tests --- .../lib/xmodule/xmodule/tests/test_fields.py | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) 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", From a9930bf34a01e355072ca40c94798f3b614419f1 Mon Sep 17 00:00:00 2001 From: Filippo Valsorda Date: Fri, 18 Jul 2014 09:47:12 -0400 Subject: [PATCH 3/5] Make enforce_type an optional flag, to avoid conflicts --- common/lib/xmodule/xmodule/fields.py | 5 ++++- requirements/edx/github.txt | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/common/lib/xmodule/xmodule/fields.py b/common/lib/xmodule/xmodule/fields.py index 561d37145d..a1b7496bf8 100644 --- a/common/lib/xmodule/xmodule/fields.py +++ b/common/lib/xmodule/xmodule/fields.py @@ -68,7 +68,10 @@ class Date(Field): """ if value is None: return None - if isinstance(value, datetime.datetime): + if isinstance(value, time.struct_time): + # struct_times are always utc + return time.strftime('%Y-%m-%dT%H:%M:%SZ', value) + elif isinstance(value, datetime.datetime): if value.tzinfo is None or value.utcoffset().total_seconds() == 0: # isoformat adds +00:00 rather than Z return value.strftime('%Y-%m-%dT%H:%M:%SZ') diff --git a/requirements/edx/github.txt b/requirements/edx/github.txt index cfc9cdd88b..054fdbfef4 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/FiloSottile/XBlock.git@a9158e9887217abe27e451d1ff82c0d9f98c0bd6#egg=XBlock # TODO: put here the edx/XBlock#200 merge commit +-e git+https://github.com/FiloSottile/XBlock.git@ee9aaa5e1cc267de62b0e9cb638461a55e630af9#egg=XBlock # TODO: put here the edx/XBlock#200 merge commit -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 From 6378c01a47d070bcdb14900421a59e6fddc253e1 Mon Sep 17 00:00:00 2001 From: Filippo Valsorda Date: Tue, 5 Aug 2014 09:58:33 -0400 Subject: [PATCH 4/5] enforce-type: set the edx/XBlock#200 merge hash --- requirements/edx/github.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/edx/github.txt b/requirements/edx/github.txt index 054fdbfef4..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/FiloSottile/XBlock.git@ee9aaa5e1cc267de62b0e9cb638461a55e630af9#egg=XBlock # TODO: put here the edx/XBlock#200 merge commit +-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 From 5c455f2a02ec9402d595cacf56b39d68f28ef0bc Mon Sep 17 00:00:00 2001 From: Filippo Valsorda Date: Tue, 5 Aug 2014 10:01:57 -0400 Subject: [PATCH 5/5] Add my name to AUTHORS --- AUTHORS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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