diff --git a/.github/workflows/continous-integration.yml b/.github/workflows/continous-integration.yml index 04d2130d8..7389a015b 100644 --- a/.github/workflows/continous-integration.yml +++ b/.github/workflows/continous-integration.yml @@ -69,7 +69,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: - python-version: 3.9.9 + python-version: 3.11 cache: "pip" - uses: actions/setup-node@v3 with: @@ -108,9 +108,6 @@ jobs: run: mypy network-api - name: Run Tests run: cd network-api && pytest -n auto -v --ds=networkapi.settings -cov=network-api/networkapi --cov-report=term-missing - - name: Coveralls - run: coveralls - continue-on-error: true test_integration: name: Integration testing @@ -155,7 +152,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: - python-version: 3.9.9 + python-version: 3.11 cache: "pip" - uses: actions/setup-node@v3 diff --git a/Dockerfile b/Dockerfile index 8343235c5..3b8093bea 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,7 +27,7 @@ RUN npm run build # Note: This stage builds the base image for production. Presently we are not # using this on the production site, but only use it as base for the dev build. # Pin "bullseye" as it matches Ubuntu 20.04 -- Heroku 20 stack currently used in production. -FROM python:3.9.9-slim-bullseye as base +FROM python:3.11-slim-bullseye as base # Install dependencies in a virtualenv ENV VIRTUAL_ENV=/app/dockerpythonvenv @@ -83,7 +83,7 @@ USER mozilla # Install your app's Python requirements. RUN python -m venv $VIRTUAL_ENV -RUN pip install -U pip==20.0.2 && pip install pip-tools +RUN pip install -U pip==23.3.2 && pip install pip-tools # Normally we won't install dev dependencies in production, but we do it here to optimise # docker build cache for local build COPY --chown=mozilla ./requirements.txt ./dev-requirements.txt ./ diff --git a/app.json b/app.json index 09af1c130..3bb54d931 100644 --- a/app.json +++ b/app.json @@ -1,6 +1,7 @@ { "name": "Mozilla Foundation site", "description": "Mozilla Foundation site", + "stack": "heroku-22", "addons": [ "heroku-postgresql:basic --version=15" ], diff --git a/dev-requirements.in b/dev-requirements.in index 6b395dbb7..195255952 100644 --- a/dev-requirements.in +++ b/dev-requirements.in @@ -1,6 +1,5 @@ -c requirements.txt black -coveralls django-debug-toolbar djhtml djlint diff --git a/dev-requirements.txt b/dev-requirements.txt index b338dbbeb..ff1e9bb04 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.9 +# This file is autogenerated by pip-compile with Python 3.11 # by the following command: # # pip-compile dev-requirements.in @@ -10,26 +10,16 @@ asgiref==3.7.2 # django black==23.11.0 # via -r dev-requirements.in -certifi==2023.7.22 - # via - # -c requirements.txt - # requests -charset-normalizer==2.0.12 - # via - # -c requirements.txt - # requests click==8.1.3 # via # black # djlint colorama==0.4.6 # via djlint -coverage[toml]==5.5 +coverage[toml]==7.4.1 # via - # coveralls + # coverage # pytest-cov -coveralls==3.3.1 - # via -r dev-requirements.in cssbeautifier==1.14.7 # via djlint django==4.2.9 @@ -42,14 +32,10 @@ djhtml==3.0.6 # via -r dev-requirements.in djlint==1.19.16 # via -r dev-requirements.in -docopt==0.6.2 - # via coveralls editorconfig==0.12.3 # via # cssbeautifier # jsbeautifier -exceptiongroup==1.1.1 - # via pytest execnet==1.9.0 # via pytest-xdist flake8==7.0.0 @@ -60,10 +46,6 @@ html-tag-names==0.1.2 # via djlint html-void-elements==0.1.0 # via djlint -idna==3.3 - # via - # -c requirements.txt - # requests iniconfig==2.0.0 # via pytest isort==5.13.2 @@ -121,10 +103,6 @@ pyyaml==6.0.1 # djlint regex==2022.10.31 # via djlint -requests==2.31.0 - # via - # -c requirements.txt - # coveralls six==1.16.0 # via # -c requirements.txt @@ -137,16 +115,6 @@ sqlparse==0.4.4 # django-debug-toolbar termcolor==2.3.0 # via pytest-sugar -toml==0.10.2 - # via - # -c requirements.txt - # coverage -tomli==2.0.1 - # via - # black - # djlint - # mypy - # pytest tqdm==4.63.0 # via # -c requirements.txt @@ -160,8 +128,6 @@ types-urllib3==1.26.16 typing-extensions==4.4.0 # via # -c requirements.txt - # asgiref - # black # mypy urllib3==1.26.18 # via diff --git a/mypy.ini b/mypy.ini index 3510a0407..388b0a08f 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1,5 +1,5 @@ [mypy] -python_version = 3.9 +python_version = 3.11 ignore_missing_imports = True follow_imports = silent exclude = (?x)( diff --git a/network-api/networkapi/campaign/migrations/0001_squashed_0005_auto_20180626_1435.py b/network-api/networkapi/campaign/migrations/0001_squashed_0005_auto_20180626_1435.py index 85a10db41..e22d5f534 100644 --- a/network-api/networkapi/campaign/migrations/0001_squashed_0005_auto_20180626_1435.py +++ b/network-api/networkapi/campaign/migrations/0001_squashed_0005_auto_20180626_1435.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.14 on 2018-07-23 17:32 -from __future__ import unicode_literals from django.db import migrations diff --git a/network-api/networkapi/donate_banner/tests.py b/network-api/networkapi/donate_banner/tests.py index 2c9696ca5..aa20d27a8 100644 --- a/network-api/networkapi/donate_banner/tests.py +++ b/network-api/networkapi/donate_banner/tests.py @@ -48,8 +48,8 @@ class TestDonateBannerSnippetChooser(WagtailTestUtils, TestCase): results = response.context["results"] # Chooser does not include every banner, but only the default langauge oness - self.assertNotEquals(len(results), all_banners.count()) - self.assertEquals(len(results), default_banners.count()) + self.assertNotEqual(len(results), all_banners.count()) + self.assertEqual(len(results), default_banners.count()) self.assertNotIn(translated_banner, results) self.assertIn(self.banners[0], results) diff --git a/network-api/networkapi/highlights/migrations/0001_squashed_0007_nullify_homepage.py b/network-api/networkapi/highlights/migrations/0001_squashed_0007_nullify_homepage.py index 847a7cfcd..3d9ec706a 100644 --- a/network-api/networkapi/highlights/migrations/0001_squashed_0007_nullify_homepage.py +++ b/network-api/networkapi/highlights/migrations/0001_squashed_0007_nullify_homepage.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.14 on 2018-07-23 17:33 -from __future__ import unicode_literals import wagtail.fields from django.db import migrations, models diff --git a/network-api/networkapi/news/migrations/0001_squashed_0013_remove_news_glyph.py b/network-api/networkapi/news/migrations/0001_squashed_0013_remove_news_glyph.py index 2b65ca6ee..2f45697d2 100644 --- a/network-api/networkapi/news/migrations/0001_squashed_0013_remove_news_glyph.py +++ b/network-api/networkapi/news/migrations/0001_squashed_0013_remove_news_glyph.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.14 on 2018-07-26 03:52 -from __future__ import unicode_literals from django.db import migrations, models diff --git a/network-api/networkapi/news/migrations/0002_remove_news_featured.py b/network-api/networkapi/news/migrations/0002_remove_news_featured.py index 09b6cc715..204e45402 100644 --- a/network-api/networkapi/news/migrations/0002_remove_news_featured.py +++ b/network-api/networkapi/news/migrations/0002_remove_news_featured.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2019-03-20 17:47 -from __future__ import unicode_literals from django.db import migrations diff --git a/network-api/networkapi/news/migrations/0003_news_featured.py b/network-api/networkapi/news/migrations/0003_news_featured.py index 4c35fa470..f56eb4c35 100644 --- a/network-api/networkapi/news/migrations/0003_news_featured.py +++ b/network-api/networkapi/news/migrations/0003_news_featured.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2019-04-08 17:52 -from __future__ import unicode_literals from django.db import migrations, models diff --git a/network-api/networkapi/s3_file_storage/storage.py b/network-api/networkapi/s3_file_storage/storage.py index eda9c4f8d..35ea7c02f 100644 --- a/network-api/networkapi/s3_file_storage/storage.py +++ b/network-api/networkapi/s3_file_storage/storage.py @@ -37,7 +37,7 @@ class S3MediaStorage(S3Boto3Storage): k = self.bucket.copy_key(new_key_name, self.bucket.name, old_key_name) if not k: - raise "Couldn't copy '%s' to '%s'" % (old_file_name, new_file_name) + raise "Couldn't copy '{}' to '{}'".format(old_file_name, new_file_name) self.delete(old_file_name) diff --git a/network-api/networkapi/wagtailpages/pagemodels/buyersguide/utils.py b/network-api/networkapi/wagtailpages/pagemodels/buyersguide/utils.py index b2f938358..a18de9040 100644 --- a/network-api/networkapi/wagtailpages/pagemodels/buyersguide/utils.py +++ b/network-api/networkapi/wagtailpages/pagemodels/buyersguide/utils.py @@ -91,7 +91,7 @@ def _localize_category_parent(categories): """ BuyersGuideProductCategory = apps.get_model(app_label="wagtailpages", model_name="BuyersGuideProductCategory") - parents_ids = list(set([category.parent.pk for category in categories if category.parent])) + parents_ids = list({category.parent.pk for category in categories if category.parent}) parents = BuyersGuideProductCategory.objects.filter(id__in=parents_ids) parents = localize_queryset(parents) parents_cache = {parent.translation_key: parent for parent in parents} diff --git a/network-api/networkapi/wagtailpages/pagemodels/customblocks/latest_profile_list.py b/network-api/networkapi/wagtailpages/pagemodels/customblocks/latest_profile_list.py index d274df863..e6f70a0c1 100644 --- a/network-api/networkapi/wagtailpages/pagemodels/customblocks/latest_profile_list.py +++ b/network-api/networkapi/wagtailpages/pagemodels/customblocks/latest_profile_list.py @@ -85,7 +85,7 @@ class LatestProfileList(blocks.StructBlock): profile["entry_count"] = False profile["user_bio_long"] = False - except (IOError, ValueError) as exception: + except (OSError, ValueError) as exception: print(str(exception)) pass diff --git a/network-api/networkapi/wagtailpages/pagemodels/customblocks/profile_by_id.py b/network-api/networkapi/wagtailpages/pagemodels/customblocks/profile_by_id.py index d2aab294a..bfd833550 100644 --- a/network-api/networkapi/wagtailpages/pagemodels/customblocks/profile_by_id.py +++ b/network-api/networkapi/wagtailpages/pagemodels/customblocks/profile_by_id.py @@ -36,7 +36,7 @@ class ProfileById(blocks.StructBlock): profiles = [as_dict[id] for id in ids.split(",") if id in as_dict] - except (IOError, ValueError) as exception: + except (OSError, ValueError) as exception: print(str(exception)) pass diff --git a/network-api/networkapi/wagtailpages/pagemodels/customblocks/profile_directory.py b/network-api/networkapi/wagtailpages/pagemodels/customblocks/profile_directory.py index eb2bff418..8befb1f1e 100644 --- a/network-api/networkapi/wagtailpages/pagemodels/customblocks/profile_directory.py +++ b/network-api/networkapi/wagtailpages/pagemodels/customblocks/profile_directory.py @@ -165,7 +165,7 @@ class TabbedProfileDirectory(blocks.StructBlock): profile["entry_count"] = False profile["user_bio_long"] = False - except (IOError, ValueError) as exception: + except (OSError, ValueError) as exception: print(str(exception)) pass diff --git a/network-api/networkapi/wagtailpages/pagemodels/index.py b/network-api/networkapi/wagtailpages/pagemodels/index.py index dd0cac817..972c03b13 100644 --- a/network-api/networkapi/wagtailpages/pagemodels/index.py +++ b/network-api/networkapi/wagtailpages/pagemodels/index.py @@ -161,7 +161,7 @@ class IndexPage(RoutablePageMixin, BasePage): if hasattr(entry, "tags") and not # Determine whether there is any overlap between 'all tags' and # the tags specified. This effects ANY matching (rather than ALL). - set([tag.slug for tag in entry.tags.all()]).isdisjoint(terms) + {tag.slug for tag in entry.tags.all()}.isdisjoint(terms) ] return entries diff --git a/network-api/networkapi/wagtailpages/pagemodels/profiles.py b/network-api/networkapi/wagtailpages/pagemodels/profiles.py index 1adf543b1..6ebb5ff0c 100644 --- a/network-api/networkapi/wagtailpages/pagemodels/profiles.py +++ b/network-api/networkapi/wagtailpages/pagemodels/profiles.py @@ -55,7 +55,7 @@ class Profile(index.Indexed, TranslatableMixin, models.Model): def save(self, *args, **kwargs): self.slug = slugify(self.name) - super(Profile, self).save(*args, **kwargs) + super().save(*args, **kwargs) self._meta.model.objects.filter(id=self.id).update(slug=Concat(F("slug"), Value("-"), F("id"))) class Meta(TranslatableMixin.Meta): diff --git a/requirements.txt b/requirements.txt index ab5471787..3eb045ab1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.9 +# This file is autogenerated by pip-compile with Python 3.11 # by the following command: # # pip-compile @@ -137,8 +137,6 @@ html5lib==1.1 # via wagtail idna==3.3 # via requests -importlib-metadata==6.8.0 - # via markdown jmespath==0.10.0 # via # boto3 @@ -242,7 +240,6 @@ tqdm==4.63.0 # via wagtail-inventory typing-extensions==4.4.0 # via - # asgiref # dj-database-url # wagtail-localize ua-parser==0.18.0 @@ -292,8 +289,8 @@ webencodings==0.5.1 whitenoise==6.6.0 # via -r requirements.in willow[heif]==1.6.3 - # via wagtail -wrapt==1.13.3 + # via + # wagtail + # willow +wrapt==1.16.0 # via scout-apm -zipp==3.16.2 - # via importlib-metadata diff --git a/runtime.txt b/runtime.txt index 425359e69..1f79d441f 100644 --- a/runtime.txt +++ b/runtime.txt @@ -1 +1 @@ -python-3.9.9 +python-3.11.7 diff --git a/tasks.py b/tasks.py index 4275f5805..4d3188ce4 100644 --- a/tasks.py +++ b/tasks.py @@ -47,12 +47,12 @@ locale_abstraction_instructions_js = " ".join( def create_env_file(env_file): """Create or update an .env to work with a docker environment""" - with open(env_file, "r") as f: + with open(env_file) as f: env_vars = f.read() # We also need to make sure to use the correct db values based on our docker settings. username = dbname = "postgres" - with open("docker-compose.yml", "r") as d: + with open("docker-compose.yml") as d: docker_compose = d.read() username = re.search("POSTGRES_USER=(.*)", docker_compose).group(1) or username dbname = re.search("POSTGRES_DB=(.*)", docker_compose).group(1) or dbname