diff --git a/openedx/core/djangoapps/content/block_structure/block_structure.py b/openedx/core/djangoapps/content/block_structure/block_structure.py index a8d10c4d81fb..07bb62d98953 100644 --- a/openedx/core/djangoapps/content/block_structure/block_structure.py +++ b/openedx/core/djangoapps/content/block_structure/block_structure.py @@ -11,9 +11,12 @@ from copy import deepcopy +from datetime import datetime from functools import partial from logging import getLogger +from dateutil.tz import tzlocal + from openedx.core.lib.graph_traversals import traverse_post_order, traverse_topologically from .exceptions import TransformerException @@ -464,7 +467,8 @@ def get_xblock_field(self, usage_key, field_name, default=None): not found. """ block_data = self._block_data_map.get(usage_key) - return getattr(block_data, field_name, default) if block_data else default + xblock_field = getattr(block_data, field_name, default) if block_data else default + return self._make_datetime_field_compatible(xblock_field) def override_xblock_field(self, usage_key, field_name, override_data): """ @@ -554,7 +558,8 @@ def get_transformer_block_field(self, usage_key, transformer, key, default=None) transformer_data = self.get_transformer_block_data(usage_key, transformer) except KeyError: return default - return getattr(transformer_data, key, default) + field = getattr(transformer_data, key, default) + return self._make_datetime_field_compatible(field) def set_transformer_block_field(self, usage_key, transformer, key, value): """ @@ -763,6 +768,22 @@ def _get_or_create_block(self, usage_key): self._block_data_map[usage_key] = block_data return block_data + def _make_datetime_field_compatible(self, field): + """ + Creates a new datetime object to avoid issues occurring due to upgrading + python-datetuil version from 2.4.0 + + More info: https://openedx.atlassian.net/browse/BOM-2245 + """ + if isinstance(field, datetime): + if isinstance(field.tzinfo, tzlocal) and not hasattr(field.tzinfo, '_hasdst'): + return datetime( + year=field.year, month=field.month, day=field.day, + hour=field.hour, minute=field.minute, second=field.second, + tzinfo=tzlocal() + ) + return field + class BlockStructureModulestoreData(BlockStructureBlockData): """ diff --git a/requirements/common_constraints.txt b/requirements/common_constraints.txt index 72021fe71f92..93ecbec6054a 100644 --- a/requirements/common_constraints.txt +++ b/requirements/common_constraints.txt @@ -25,3 +25,6 @@ Django<4.0 elasticsearch<7.14.0 setuptools<60 + +# django-simple-history>3.0.0 adds indexing and causes a lot of migrations to be affected +django-simple-history==3.0.0 diff --git a/requirements/constraints.txt b/requirements/constraints.txt index dc2c38eed6ad..877103718256 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -33,9 +33,6 @@ django-storages<1.9 # for them. edx-enterprise==3.42.5 -# Newer versions need a more recent version of python-dateutil -freezegun==0.3.12 - # 4.5.1 introduced a bug when used together with xmlsec: https://bugs.launchpad.net/lxml/+bug/1880251 # Tests passed, but hit a problem in stage lxml<4.5.1 @@ -46,14 +43,8 @@ oauthlib==3.0.1 # django-auth-toolkit==1.3.3 requires oauthlib>=3.1.0 which is pinned because of test failures django-oauth-toolkit<=1.3.2 -# Upgrading to 2.5.3 on 2020-01-03 triggered "'tzlocal' object has no attribute '_std_offset'" errors in production -python-dateutil==2.4.0 -# matplotlib>=3.4.0 requires python-dateutil>=2.7 +# Will be updated once we update python-dateutil package matplotlib<3.4.0 -# pandas>0.22.0 requires python-dateutil>=2.5.0 -pandas==0.22.0 -# networkx>=2.6 requires pandas>=1.1 -networkx<2.6 # Constraint from astroid 2.3.3 wrapt==1.11.* diff --git a/requirements/edx-sandbox/py38.txt b/requirements/edx-sandbox/py38.txt index 83ccef76478a..39dc6dd3a18c 100644 --- a/requirements/edx-sandbox/py38.txt +++ b/requirements/edx-sandbox/py38.txt @@ -18,8 +18,6 @@ cryptography==36.0.2 # via -r requirements/edx-sandbox/py38.in cycler==0.11.0 # via matplotlib -decorator==4.4.2 - # via networkx joblib==1.1.0 # via nltk kiwisolver==1.4.2 @@ -39,10 +37,8 @@ matplotlib==3.3.4 # -r requirements/edx-sandbox/py38.in mpmath==1.2.1 # via sympy -networkx==2.5.1 - # via - # -c requirements/edx-sandbox/../constraints.txt - # -r requirements/edx-sandbox/py38.in +networkx==2.8.2 + # via -r requirements/edx-sandbox/py38.in nltk==3.7 # via # -r requirements/edx-sandbox/py38.in @@ -67,9 +63,7 @@ pyparsing==3.0.7 # matplotlib # openedx-calc python-dateutil==2.4.0 - # via - # -c requirements/edx-sandbox/../constraints.txt - # matplotlib + # via matplotlib random2==1.0.1 # via -r requirements/edx-sandbox/py38.in regex==2022.3.15 diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index 2203f181f0e8..f8050f102899 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -211,6 +211,7 @@ django==3.2.13 # django-wiki # djangorestframework # drf-jwt + # drf-nested-routers # drf-yasg # edx-ace # edx-api-doc-tools @@ -349,6 +350,7 @@ django-ses==3.0.1 # via -r requirements/edx/base.in django-simple-history==3.0.0 # via + # -c requirements/edx/../common_constraints.txt # -r requirements/edx/base.in # edx-enterprise # edx-name-affirmation @@ -386,8 +388,8 @@ djangorestframework==3.12.4 # blockstore # django-config-models # django-user-tasks - # djangorestframework-expander # drf-jwt + # drf-nested-routers # drf-yasg # edx-api-doc-tools # edx-completion @@ -399,8 +401,6 @@ djangorestframework==3.12.4 # edx-submissions # ora2 # super-csv -djangorestframework-expander==0.2.3 - # via blockstore djangorestframework-xml==2.0.0 # via edx-enterprise docopt==0.6.2 @@ -414,7 +414,9 @@ done-xblock==2.0.4 drf-jwt==1.19.2 # via edx-drf-extensions drf-nested-routers==0.93.4 - # via blockstore + # via + # -r requirements/edx/base.in + # blockstore drf-yasg==1.20.0 # via edx-api-doc-tools edx-ace==1.5.0 @@ -424,7 +426,9 @@ edx-api-doc-tools==1.6.0 # -r requirements/edx/base.in # blockstore edx-auth-backends==4.1.0 - # via -r requirements/edx/base.in + # via + # -r requirements/edx/base.in + # blockstore edx-braze-client==0.1.3 # via -r requirements/edx/base.in edx-bulk-grades==1.0.0 @@ -448,6 +452,7 @@ edx-django-sites-extensions==4.0.0 # via -r requirements/edx/base.in edx-django-utils==4.6.0 # via + # -r requirements/edx/base.in # -r requirements/edx/github.in # blockstore # django-config-models @@ -704,11 +709,12 @@ multidict==6.0.2 # aiohttp # yarl mysqlclient==2.1.0 - # via -r requirements/edx/base.in -newrelic==7.10.0.175 # via # -r requirements/edx/base.in # blockstore +newrelic==7.10.0.175 + # via + # -r requirements/edx/base.in # edx-django-utils nltk==3.7 # via @@ -838,9 +844,8 @@ pysrt==1.1.2 # via # -r requirements/edx/base.in # edxval -python-dateutil==2.4.0 +python-dateutil==2.8.2 # via - # -c requirements/edx/../constraints.txt # -r requirements/edx/base.in # analytics-python # botocore diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index eb8b3e284e08..715e378be0a9 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -298,6 +298,7 @@ django==3.2.13 # django-wiki # djangorestframework # drf-jwt + # drf-nested-routers # drf-yasg # edx-ace # edx-api-doc-tools @@ -373,7 +374,9 @@ django-crum==0.7.9 django-debug-toolbar==3.2.4 # via -r requirements/edx/development.in django-environ==0.8.1 - # via blockstore + # via + # -r requirements/edx/testing.txt + # blockstore django-fernet-fields==0.6 # via # -r requirements/edx/testing.txt @@ -448,6 +451,7 @@ django-ses==3.0.1 # via -r requirements/edx/testing.txt django-simple-history==3.0.0 # via + # -c requirements/edx/../common_constraints.txt # -r requirements/edx/testing.txt # edx-enterprise # edx-name-affirmation @@ -485,8 +489,8 @@ djangorestframework==3.12.4 # blockstore # django-config-models # django-user-tasks - # djangorestframework-expander # drf-jwt + # drf-nested-routers # drf-yasg # edx-api-doc-tools # edx-completion @@ -498,8 +502,6 @@ djangorestframework==3.12.4 # edx-submissions # ora2 # super-csv -djangorestframework-expander==0.2.3 - # via blockstore djangorestframework-xml==2.0.0 # via # -r requirements/edx/testing.txt @@ -536,11 +538,11 @@ edx-api-doc-tools==1.6.0 # -r requirements/edx/testing.txt # blockstore edx-auth-backends==4.1.0 - # via -r requirements/edx/testing.txt -edx-braze-client==0.1.3 # via # -r requirements/edx/testing.txt # blockstore +edx-braze-client==0.1.3 + # via -r requirements/edx/testing.txt edx-bulk-grades==1.0.0 # via # -r requirements/edx/testing.txt @@ -704,9 +706,7 @@ filelock==3.6.0 # tox # virtualenv freezegun==0.3.12 - # via - # -c requirements/edx/../constraints.txt - # -r requirements/edx/testing.txt + # via -r requirements/edx/testing.txt frozenlist==1.3.0 # via # -r requirements/edx/testing.txt @@ -950,11 +950,12 @@ mypy==0.942 mypy-extensions==0.4.3 # via mypy mysqlclient==2.1.0 - # via -r requirements/edx/testing.txt -newrelic==7.10.0.175 # via # -r requirements/edx/testing.txt # blockstore +newrelic==7.10.0.175 + # via + # -r requirements/edx/testing.txt # edx-django-utils nltk==3.7 # via @@ -1067,7 +1068,9 @@ py2neo==2021.2.3 # -c requirements/edx/../constraints.txt # -r requirements/edx/testing.txt pyblake2==1.1.2 - # via blockstore + # via + # -r requirements/edx/testing.txt + # blockstore pycodestyle==2.8.0 # via -r requirements/edx/testing.txt pycountry==22.3.5 @@ -1194,9 +1197,8 @@ pytest-randomly==3.11.0 # via -r requirements/edx/testing.txt pytest-xdist[psutil]==2.5.0 # via -r requirements/edx/testing.txt -python-dateutil==2.4.0 +python-dateutil==2.8.2 # via - # -c requirements/edx/../constraints.txt # -r requirements/edx/testing.txt # analytics-python # botocore diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index 6fd70e98aca0..d531db258e52 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -79,7 +79,6 @@ attrs==21.4.0 # blockstore # edx-ace # openedx-events - # outcome # pytest babel==2.9.1 # via @@ -284,6 +283,7 @@ distlib==0.3.4 # django-wiki # djangorestframework # drf-jwt + # drf-nested-routers # drf-yasg # edx-ace # edx-api-doc-tools @@ -434,6 +434,7 @@ django-ses==3.0.1 # via -r requirements/edx/base.txt django-simple-history==3.0.0 # via + # -c requirements/edx/../common_constraints.txt # -r requirements/edx/base.txt # edx-enterprise # edx-name-affirmation @@ -471,8 +472,8 @@ djangorestframework==3.12.4 # blockstore # django-config-models # django-user-tasks - # djangorestframework-expander # drf-jwt + # drf-nested-routers # drf-yasg # edx-api-doc-tools # edx-completion @@ -484,10 +485,6 @@ djangorestframework==3.12.4 # edx-submissions # ora2 # super-csv -djangorestframework-expander==0.2.3 - # via - # -r requirements/edx/base.txt - # blockstore djangorestframework-xml==2.0.0 # via # -r requirements/edx/base.txt @@ -522,11 +519,11 @@ edx-api-doc-tools==1.6.0 # -r requirements/edx/base.txt # blockstore edx-auth-backends==4.1.0 - # via -r requirements/edx/base.txt -edx-braze-client==0.1.3 # via # -r requirements/edx/base.txt # blockstore +edx-braze-client==0.1.3 + # via -r requirements/edx/base.txt edx-bulk-grades==1.0.0 # via # -r requirements/edx/base.txt @@ -682,9 +679,7 @@ filelock==3.6.0 # tox # virtualenv freezegun==0.3.12 - # via - # -c requirements/edx/../constraints.txt - # -r requirements/edx/testing.in + # via -r requirements/edx/testing.in frozenlist==1.3.0 # via # -r requirements/edx/base.txt @@ -900,11 +895,12 @@ multidict==6.0.2 # aiohttp # yarl mysqlclient==2.1.0 - # via -r requirements/edx/base.txt -newrelic==7.10.0.175 # via # -r requirements/edx/base.txt # blockstore +newrelic==7.10.0.175 + # via + # -r requirements/edx/base.txt # edx-django-utils nltk==3.7 # via @@ -1126,9 +1122,8 @@ pytest-randomly==3.11.0 # via -r requirements/edx/testing.in pytest-xdist[psutil]==2.5.0 # via -r requirements/edx/testing.in -python-dateutil==2.4.0 +python-dateutil==2.8.2 # via - # -c requirements/edx/../constraints.txt # -r requirements/edx/base.txt # analytics-python # botocore