diff --git a/.travis.yml b/.travis.yml index 7cd4cfd335..f38d218a0a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,6 +27,7 @@ jobs: - { python: 3.6, env: TOXENV=accounts-users-and-ratings } - { python: 3.6, env: TOXENV=main } - { python: 3.6, env: TOXENV=amo-lib-locales-and-signing } + - { python: 3.6, env: TOXENV=assets DJANGO=django22 } env: global: diff --git a/Makefile-docker b/Makefile-docker index 84fec69f7a..35ca174a84 100644 --- a/Makefile-docker +++ b/Makefile-docker @@ -120,7 +120,7 @@ install_python_test_dependencies: # Can't use --progress-bar=off for system packages as long as our docker image # doesn't have pip 10 by default. $(PIP_COMMAND) install --no-deps --exists-action=w -r requirements/system.txt - $(PIP_COMMAND) install --progress-bar=off --no-deps --exists-action=w -r requirements/prod_py${PYTHON_VERSION_MAJOR}.txt + $(PIP_COMMAND) install --progress-bar=off --no-deps --exists-action=w -r requirements/prod_py${PYTHON_VERSION_MAJOR}${DJANGO}.txt $(PIP_COMMAND) install --progress-bar=off --no-deps --exists-action=w -r requirements/tests.txt .PHONY: install_python_dev_dependencies diff --git a/requirements/prod_common.txt b/requirements/prod_common.txt index 8758dd4f70..6b260c8971 100644 --- a/requirements/prod_common.txt +++ b/requirements/prod_common.txt @@ -1,10 +1,6 @@ Babel==2.6.0 \ --hash=sha256:6778d85147d5d85345c14a26aada5e478ab04e39b078b0745ee6870c2b5cf669 \ --hash=sha256:8cba50f48c529ca3fa18cf81fa9403be176d374ac4d60738b839122dfaaa3d23 -# Django is required by django-aesfield, django-cache-nuggets, django-csp, django-mozilla-product-details, django-tables2, nobot -Django==1.11.20 \ - --hash=sha256:0a73696e0ac71ee6177103df984f9c1e07cd297f080f8ec4dc7c6f3fb74395b5 \ - --hash=sha256:43a99da08fee329480d27860d68279945b7d8bf7b537388ee2c8938c709b2041 # pyup: >=1.11,<2.0 # Jinja2 is required by Sphinx Jinja2==2.10 \ --hash=sha256:74c935a1b8bb9a3947c50a54766a969d4846290e1e788ea44c1392163723c3bd \ diff --git a/requirements/prod_py2.txt b/requirements/prod_py2.txt index 4ee7e9e16b..00dd34d7eb 100644 --- a/requirements/prod_py2.txt +++ b/requirements/prod_py2.txt @@ -1,5 +1,8 @@ -r prod_common.txt +Django==1.11.20 \ + --hash=sha256:0a73696e0ac71ee6177103df984f9c1e07cd297f080f8ec4dc7c6f3fb74395b5 \ + --hash=sha256:43a99da08fee329480d27860d68279945b7d8bf7b537388ee2c8938c709b2041 # pyup: >=1.11,<2.0 # futures is required by s3transfer futures==3.2.0 \ --hash=sha256:9ec02aa7d674acb8618afb127e27fde7fc68994c0437ad759fa094a574adb265 \ diff --git a/requirements/prod_py3.txt b/requirements/prod_py3.txt index 64959d82df..030aac678d 100644 --- a/requirements/prod_py3.txt +++ b/requirements/prod_py3.txt @@ -1,4 +1,8 @@ -r prod_common.txt + +Django==1.11.20 \ + --hash=sha256:0a73696e0ac71ee6177103df984f9c1e07cd297f080f8ec4dc7c6f3fb74395b5 \ + --hash=sha256:43a99da08fee329480d27860d68279945b7d8bf7b537388ee2c8938c709b2041 # pyup: >=1.11,<2.0 # atpublic is required by flufl.lock atpublic==1.0 \ --hash=sha256:7dca670499e9a9d3aae5a8914bc799475fe24be3bcd29c8129642dda665f7a44 diff --git a/requirements/prod_py3django22.txt b/requirements/prod_py3django22.txt new file mode 100644 index 0000000000..533f6b36ba --- /dev/null +++ b/requirements/prod_py3django22.txt @@ -0,0 +1,10 @@ +-r prod_common.txt + +Django==2.2b1 \ + --hash=sha256:58819ca72a13b963c16383687421261657abe5754aad9ad66166a921dd17559f \ + --hash=sha256:62644444551e8e6fd36600e741a4d24dd2b4b58acf7bae8847a8da952468d771 +# atpublic is required by flufl.lock +atpublic==1.0 \ + --hash=sha256:7dca670499e9a9d3aae5a8914bc799475fe24be3bcd29c8129642dda665f7a44 +flufl.lock==3.2 \ + --hash=sha256:a8d66accc9ab41f09961cd8f8db39f9c28e97e2769659a3567c63930a869ff5b diff --git a/src/olympia/addons/forms.py b/src/olympia/addons/forms.py index fc8e134cec..8aae81a449 100644 --- a/src/olympia/addons/forms.py +++ b/src/olympia/addons/forms.py @@ -182,9 +182,9 @@ class AddonFormBase(TranslationFormMixin, forms.ModelForm): class CategoryForm(forms.Form): - application = forms.TypedChoiceField(amo.APPS_CHOICES, coerce=int, - widget=forms.HiddenInput, - required=True) + application = forms.TypedChoiceField( + choices=amo.APPS_CHOICES, coerce=int, widget=forms.HiddenInput, + required=True) categories = forms.ModelMultipleChoiceField( queryset=Category.objects.all(), widget=CategoriesSelectMultiple) diff --git a/src/olympia/amo/fields.py b/src/olympia/amo/fields.py index 690e376534..8f57fda1bd 100644 --- a/src/olympia/amo/fields.py +++ b/src/olympia/amo/fields.py @@ -72,8 +72,8 @@ class ColorField(fields.CharField): widget = ColorWidget def __init__(self, max_length=7, min_length=None, *args, **kwargs): - super(ColorField, self).__init__(max_length, min_length, *args, - **kwargs) + super(ColorField, self).__init__( + *args, max_length=max_length, min_length=min_length, **kwargs) def clean(self, value): super(ColorField, self).clean(value) diff --git a/src/olympia/amo/management/commands/compress_assets.py b/src/olympia/amo/management/commands/compress_assets.py index d6046b0b20..90cfb9a723 100644 --- a/src/olympia/amo/management/commands/compress_assets.py +++ b/src/olympia/amo/management/commands/compress_assets.py @@ -46,7 +46,7 @@ class Command(BaseCommand): def add_arguments(self, parser): """Handle command arguments.""" parser.add_argument( - 'force', action='store_true', + '--force', action='store_true', help='Ignores modified/created dates and forces compression.') def generate_build_id(self): diff --git a/src/olympia/core/db/mysql/base.py b/src/olympia/core/db/mysql/base.py index b95bfe6a25..a1b22188b6 100644 --- a/src/olympia/core/db/mysql/base.py +++ b/src/olympia/core/db/mysql/base.py @@ -31,6 +31,12 @@ class DatabaseWrapper(MySQLDBWrapper): introspection_class = DatabaseIntrospection SchemaEditorClass = DatabaseSchemaEditor - _data_types = dict( - MySQLDBWrapper._data_types, - PositiveAutoField='integer UNSIGNED AUTO_INCREMENT') + # data_types is _data_types in =mysql5.6.4 is supports_microsecond_precision=True. + data_types = dict( + getattr(MySQLDBWrapper, '_data_types', MySQLDBWrapper.data_types), + PositiveAutoField='integer UNSIGNED AUTO_INCREMENT', + DateTimeField='datetime(6)', + TimeField='time(6)') + _data_types = data_types diff --git a/src/olympia/lib/misc/urlconf_decorator.py b/src/olympia/lib/misc/urlconf_decorator.py index 749145e78d..98122b187d 100644 --- a/src/olympia/lib/misc/urlconf_decorator.py +++ b/src/olympia/lib/misc/urlconf_decorator.py @@ -20,16 +20,21 @@ wrapped around each callback in the urlconf as if you had @decorator above the function. """ -from django.urls import RegexURLPattern, RegexURLResolver +try: + from django.urls import URLPattern, URLResolver +except ImportError: + # django1.11 + from django.urls import ( + RegexURLPattern as URLPattern, RegexURLResolver as URLResolver) def decorate(decorator, urlconf): if isinstance(urlconf, (list, tuple)): for item in urlconf: decorate(decorator, item) - elif isinstance(urlconf, RegexURLResolver): + elif isinstance(urlconf, URLResolver): for item in urlconf.url_patterns: decorate(decorator, item) - elif isinstance(urlconf, RegexURLPattern): + elif isinstance(urlconf, URLPattern): urlconf._callback = decorator(urlconf.callback) return urlconf diff --git a/src/olympia/ratings/forms.py b/src/olympia/ratings/forms.py index 7cdcb5ef3f..a28e7f38f9 100644 --- a/src/olympia/ratings/forms.py +++ b/src/olympia/ratings/forms.py @@ -41,7 +41,7 @@ class RatingForm(RatingReplyForm): label='Review', ) rating = forms.ChoiceField( - zip(range(1, 6), range(1, 6)), label=_(u'Rating') + choices=zip(range(1, 6), range(1, 6)), label=_(u'Rating') ) # re.L flag has been removed in py3.6 as Unicode matching is already # enabled by default for Unicode (str) patterns. diff --git a/src/olympia/stats/models.py b/src/olympia/stats/models.py index 38216c6583..db3a242d76 100644 --- a/src/olympia/stats/models.py +++ b/src/olympia/stats/models.py @@ -78,7 +78,7 @@ class ThemeUpdateCountManager(models.Manager): class ThemeUpdateCount(StatsSearchMixin, models.Model): """Daily users taken from the ADI data (coming from Hive).""" id = PositiveAutoField(primary_key=True) - addon = models.ForeignKey('addons.Addon') + addon = models.ForeignKey('addons.Addon', on_delete=models.CASCADE) count = models.PositiveIntegerField() date = models.DateField() diff --git a/src/olympia/zadmin/forms.py b/src/olympia/zadmin/forms.py index 1483a3bdcc..076772bba1 100644 --- a/src/olympia/zadmin/forms.py +++ b/src/olympia/zadmin/forms.py @@ -23,7 +23,7 @@ class FeaturedCollectionForm(forms.ModelForm): (idx, LANGUAGE_MAPPING[idx]['native']) for idx in settings.LANGUAGE_MAPPING) - application = forms.ChoiceField(amo.APPS_CHOICES) + application = forms.ChoiceField(choices=amo.APPS_CHOICES) collection = forms.CharField(widget=forms.HiddenInput) locale = forms.ChoiceField(choices=LOCALES, required=False) diff --git a/tox.ini b/tox.ini index 2e484f8848..63d05b3a1f 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,12 @@ [tox] envlist = - es, devhub, main, ui-tests, docs, assets, codestyle + es, + devhub, + main, + ui-tests, + docs, + assets, + codestyle addons-versions-and-files, amo-lib-locales-and-signin, reviewers-and-zadmin,