Fix #11057: Update codebase to prefer python3 syntax (#11086)

* Update `super()` calls

* Update for use f-strings

* Remove utf-8 comments

* Import from built-in `unittest.mock`

* Use native dict and set syntax

* Update exception errors

* Remove six compatibility code

* Remove explicit utf-8 encoding

* Use `yield from`
This commit is contained in:
Rob Hudson 2022-01-11 10:21:16 -05:00 коммит произвёл GitHub
Родитель 866e82c37d
Коммит 2177e4d2dc
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
148 изменённых файлов: 291 добавлений и 383 удалений

Просмотреть файл

@ -49,7 +49,7 @@ class SimpleDictCache(LocMemCache):
def incr(self, key, delta=1, version=None):
value = self.get(key, version=version)
if value is None:
raise ValueError("Key '%s' not found" % key)
raise ValueError(f"Key '{key}' not found")
new_value = value + delta
key = self.make_key(key, version=version)
with self._lock:

Просмотреть файл

@ -38,7 +38,7 @@ cfg = {
"prod": {
"()": commonware.log.Formatter,
"datefmt": "%H:%M:%s",
"format": "%s %s: [%%(REMOTE_ADDR)s] %s" % (hostname, settings.SYSLOG_TAG, base_fmt),
"format": f"{hostname} {settings.SYSLOG_TAG}: [%(REMOTE_ADDR)s] {base_fmt}",
},
"cef": {
"()": cef.SysLogFormatter,

Просмотреть файл

@ -16,7 +16,7 @@ from bedrock.utils.management.decorators import alert_sentry_on_exception
def get_config_file_name(app_name=None):
app_name = app_name or settings.APP_NAME or "bedrock-dev"
return os.path.join(settings.WWW_CONFIG_PATH, "waffle_configs", "%s.env" % app_name)
return os.path.join(settings.WWW_CONFIG_PATH, "waffle_configs", f"{app_name}.env")
def get_config_values():
@ -61,7 +61,7 @@ class Command(BaseCommand):
count = refresh_db_values()
if count:
self.output("%s configs successfully loaded" % count)
self.output(f"{count} configs successfully loaded")
else:
self.output("No configs found. Please try again later.")

Просмотреть файл

@ -105,7 +105,7 @@ class BasicAuthMiddleware:
response = HttpResponse(status=401, content="<h1>Unauthorized. This site is in private demo mode.</h1>")
realm = settings.APP_NAME or "bedrock-demo"
response["WWW-Authenticate"] = 'Basic realm="{}"'.format(realm)
response["WWW-Authenticate"] = f'Basic realm="{realm}"'
return response

Просмотреть файл

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -13,7 +13,7 @@ class ConfigValue(models.Model):
app_label = "base"
def __str__(self):
return "%s=%s" % (self.name, self.value)
return f"{self.name}={self.value}"
def get_config_dict():

Просмотреть файл

@ -124,7 +124,7 @@ def js_bundle(name):
Bundles are defined in the "media/static-bundles.json" file.
"""
path = "js/{}.js".format(name)
path = f"js/{name}.js"
path = staticfiles_storage.url(path)
return jinja2.Markup(JS_TEMPLATE % path)
@ -135,7 +135,7 @@ def css_bundle(name):
Bundles are defined in the "media/static-bundles.json" file.
"""
path = "css/{}.css".format(name)
path = f"css/{name}.css"
path = staticfiles_storage.url(path)
return jinja2.Markup(CSS_TEMPLATE % path)

Просмотреть файл

@ -2,10 +2,11 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from unittest.mock import patch
from django.test import TestCase, override_settings
from django_jinja.backend import Jinja2
from mock import patch
from bedrock.base.templatetags import helpers

Просмотреть файл

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
@ -33,7 +31,7 @@ def custom_key_func(key, key_prefix, version):
_caches_setting_base = {
"default": {},
"prefix": {"KEY_PREFIX": "cacheprefix{}".format(os.getpid())},
"prefix": {"KEY_PREFIX": f"cacheprefix{os.getpid()}"},
"v2": {"VERSION": 2},
"custom_key": {"KEY_FUNCTION": custom_key_func},
"custom_key2": {"KEY_FUNCTION": "bedrock.base.tests.test_simple_dict_cache.custom_key_func"},
@ -49,7 +47,7 @@ def caches_setting_for_tests(base=None, **params):
# This results in the following search order:
# params -> _caches_setting_base -> base
base = base or {}
setting = dict((k, base.copy()) for k in _caches_setting_base.keys())
setting = {k: base.copy() for k in _caches_setting_base.keys()}
for key, cache_params in setting.items():
cache_params.update(_caches_setting_base[key])
cache_params.update(params)
@ -324,11 +322,11 @@ class SimpleDictCacheTests(TestCase):
# Create initial cache key entries. This will overflow the cache,
# causing a cull.
for i in range(1, initial_count):
cull_cache.set("cull%d" % i, "value", 1000)
cull_cache.set(f"cull{i}", "value", 1000)
count = 0
# Count how many keys are left in the cache.
for i in range(1, initial_count):
if "cull%d" % i in cull_cache: # noqa
if f"cull{i}" in cull_cache: # noqa
count = count + 1
self.assertEqual(count, final_count)

Просмотреть файл

@ -1,15 +1,15 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from unittest.mock import Mock, patch
from django.test import TestCase
from django.test.client import RequestFactory
from django.test.utils import override_settings
from django.urls import re_path
import pytest
from mock import Mock, patch
from bedrock.base.urlresolvers import Prefixer, find_supported, reverse, split_path
@ -47,7 +47,7 @@ class TestReverse(TestCase):
def test_unicode_url(self, get_url_prefix):
# If the prefixer returns a unicode URL it should be escaped and cast
# as a str object.
get_url_prefix.return_value = FakePrefixer(lambda p: "/Françoi%s" % p)
get_url_prefix.return_value = FakePrefixer(lambda p: f"/Françoi{p}")
result = reverse("test.view")
# Ensure that UTF-8 characters are escaped properly.

Просмотреть файл

@ -2,9 +2,9 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from django.conf import settings
from unittest.mock import patch
from mock import patch
from django.conf import settings
from bedrock.base import waffle

Просмотреть файл

@ -2,8 +2,9 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from unittest.mock import patch
from everett.manager import ConfigManager, ConfigurationMissingError
from mock import patch
from bedrock.base import waffle_config
from bedrock.mozorg.tests import TestCase

Просмотреть файл

@ -52,10 +52,7 @@ DB_INFO_FILE = getenv("AWS_DB_JSON_DATA_FILE", f"{settings.DATA_PATH}/bedrock_db
GIT_SHA = getenv("GIT_SHA")
BUCKET_NAME = getenv("AWS_DB_S3_BUCKET", "bedrock-db-dev")
REGION_NAME = os.getenv("AWS_DB_REGION", "us-west-2")
S3_BASE_URL = "https://s3-{}.amazonaws.com/{}".format(
REGION_NAME,
BUCKET_NAME,
)
S3_BASE_URL = f"https://s3-{REGION_NAME}.amazonaws.com/{BUCKET_NAME}"
def get_l10n_repo_info():
@ -84,9 +81,9 @@ def get_extra_server_info():
"git_sha": GIT_SHA,
}
try:
with open(DB_INFO_FILE, "r") as fp:
with open(DB_INFO_FILE) as fp:
db_info = json.load(fp)
except (IOError, ValueError):
except (OSError, ValueError):
pass
else:
last_updated_timestamp = datetime.fromtimestamp(db_info["updated"])
@ -94,7 +91,7 @@ def get_extra_server_info():
db_info["last_update"] = timeago.format(last_updated_timestamp)
db_info["file_url"] = get_db_file_url(db_info["file_name"])
for key, value in db_info.items():
server_info["db_%s" % key] = value
server_info[f"db_{key}"] = value
return server_info

Просмотреть файл

@ -16,9 +16,8 @@ class LatestPositionsFeed(Feed):
title = "Current Mozilla job openings"
description = "The current list of job openings, available internships and contract opportunities at Mozilla."
feed_copyright = (
"Portions of this content are ©1998–%s by individual "
"mozilla.org contributors. Content available under a "
"Creative Commons license." % date.today().year
f"Portions of this content are ©1998–{date.today().year} by individual "
"mozilla.org contributors. Content available under a Creative Commons license."
)
def link(self):

Просмотреть файл

@ -13,7 +13,7 @@ class PositionFilterForm(forms.Form):
location = forms.ChoiceField(widget=forms.Select(attrs={"autocomplete": "off"}))
def __init__(self, *args, **kwargs):
super(PositionFilterForm, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
# Populate position type choices dynamically.
locations = Position.locations()

Просмотреть файл

@ -29,7 +29,7 @@ class Position(models.Model):
)
def __str__(self):
return "{}@{}".format(self.job_id, self.source)
return f"{self.job_id}@{self.source}"
@property
def location_list(self):
@ -45,7 +45,7 @@ class Position(models.Model):
@classmethod
def locations(cls):
return sorted(
set(location.strip() for location in chain(*[locations.split(",") for locations in cls.objects.values_list("location", flat=True)]))
{location.strip() for location in chain(*[locations.split(",") for locations in cls.objects.values_list("location", flat=True)])}
)
@classmethod

Просмотреть файл

@ -26,5 +26,5 @@ class PositionFactory(factory.django.DjangoModelFactory):
@factory.lazy_attribute
def apply_url(self):
if self.source == "gh":
url = "https://boards.greenhouse.io/{}/jobs/{}".format(settings.GREENHOUSE_BOARD, self.job_id)
url = f"https://boards.greenhouse.io/{settings.GREENHOUSE_BOARD}/jobs/{self.job_id}"
return url.format(self.job_id)

Просмотреть файл

@ -32,7 +32,7 @@ class Command(BaseCommand):
self.output("Loading content cards into database")
count = ContentCard.objects.refresh()
self.output("%s content cards successfully loaded" % count)
self.output(f"{count} content cards successfully loaded")
repo.set_db_latest()

Просмотреть файл

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -24,7 +24,7 @@ def get_page_content_cards(page_name, locale):
def get_data_from_file_path(file_path):
card_name, locale = file_path.stem.split(".")
page_name = file_path.parts[-2]
page_id = "{}-{}-{}".format(page_name, locale, card_name)
page_id = f"{page_name}-{locale}-{card_name}"
return {
"locale": locale,
"card_name": card_name,
@ -35,7 +35,7 @@ def get_data_from_file_path(file_path):
class ContentCardManager(models.Manager):
def get_card(self, page_name, name, locale="en-US"):
card_id = "{}-{}-{}".format(page_name, locale, name)
card_id = f"{page_name}-{locale}-{name}"
return self.get(id=card_id)
def get_page_cards(self, page_name, locale="en-US"):
@ -82,7 +82,7 @@ class ContentCard(models.Model):
ordering = ("id",)
def __str__(self):
return "{} ({})".format(self.card_name, self.locale)
return f"{self.card_name} ({self.locale})"
@property
def html(self):
@ -94,24 +94,24 @@ class ContentCard(models.Model):
data = {}
data.update(self.data)
if "image" in data:
data["image_url"] = "%scontentcards/img/%s" % (settings.CONTENT_CARDS_URL, data["image"])
data["image_url"] = f"{settings.CONTENT_CARDS_URL}contentcards/img/{data['image']}"
del data["image"]
if "highres_image" in data:
data["highres_image_url"] = "%scontentcards/img/%s" % (settings.CONTENT_CARDS_URL, data["highres_image"])
data["highres_image_url"] = f"{settings.CONTENT_CARDS_URL}contentcards/img/{data['highres_image']}"
del data["highres_image"]
if "ga_title" not in data:
data["ga_title"] = data["title"]
if "media_icon" in data:
data["media_icon"] = "mzp-has-%s" % data["media_icon"]
data["media_icon"] = f"mzp-has-{data['media_icon']}"
if "aspect_ratio" in data:
data["aspect_ratio"] = "mzp-has-aspect-%s" % data["aspect_ratio"]
data["aspect_ratio"] = f"mzp-has-aspect-{data['aspect_ratio']}"
if "size" in data:
data["class"] = "mzp-c-card-%s" % data["size"]
data["class"] = f"mzp-c-card-{data['size']}"
del data["size"]
if "link_url" in data and not URL_RE.match(data["link_url"]):

Просмотреть файл

@ -78,7 +78,7 @@ class TestContentCardModel(TestCase):
def test_get_page_cards(self):
cards = models.ContentCard.objects.get_page_cards("home")
self.assertTrue(all(name in cards for name in ["card_%d" % i for i in range(1, 6)]))
self.assertTrue(all(name in cards for name in [f"card_{i}" for i in range(1, 6)]))
self.assertDictEqual(
cards["card_2"],
{

Просмотреть файл

@ -294,7 +294,7 @@ class LinkRenderer(BaseBlockRenderer):
cta_text = _make_plain_text(node)
data_cta = f' data-cta-type="link" data-cta-text="{cta_text}"'
return '<a href="{0}{1}"{2}{3}>{4}</a>'.format(urlunparse(url), ref, data_cta, rel, self._render_content(node))
return f'<a href="{urlunparse(url)}{ref}"{data_cta}{rel}>{self._render_content(node)}</a>'
def _render_list(tag, content):

Просмотреть файл

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -1,13 +1,12 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from unittest.mock import ANY, patch
from django.test import override_settings
from django.test.client import RequestFactory
from mock import ANY, patch
from bedrock.exp import views
from bedrock.mozorg.tests import TestCase

Просмотреть файл

@ -20,12 +20,12 @@ class ExternalFile:
try:
fileinfo = settings.EXTERNAL_FILES[file_id]
except KeyError:
raise ValueError("No external file with the {0} ID.".format(file_id))
raise ValueError(f"No external file with the {file_id} ID.")
self._cache = caches["externalfiles"]
self.file_id = file_id
self.name = fileinfo["name"]
self.cache_key = "externalfile:{}".format(self.file_id)
self.cache_key = f"externalfile:{self.file_id}"
self.file_path = os.path.join(settings.EXTERNAL_FILES_PATH, self.name)
@property
@ -78,7 +78,7 @@ class ExternalFile:
content = fp.read()
if not content:
raise ValueError("%s is empty" % self.name)
raise ValueError(f"{self.name} is empty")
return self.validate_content(content)
@ -91,7 +91,7 @@ class ExternalFile:
def update(self):
from bedrock.externalfiles.models import ExternalFile as EFModel
log.info("Updating {0}.".format(self.name))
log.info(f"Updating {self.name}.")
content = self.validate_file()
fo = self.file_object
if fo:
@ -100,7 +100,7 @@ class ExternalFile:
else:
EFModel.objects.create(name=self.file_id, content=content)
log.info("Successfully updated {0}.".format(self.name))
log.info(f"Successfully updated {self.name}.")
return True
def clear_cache(self):

Просмотреть файл

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
@ -16,7 +15,7 @@ from bedrock.mozorg.tests import TestCase
class TestExternalFile(TestCase):
@classmethod
def setUpClass(cls):
super(TestExternalFile, cls).setUpClass()
super().setUpClass()
timezone.activate(utc)
def setUp(self):

Просмотреть файл

@ -73,7 +73,7 @@ class FirefoxDesktop(_ProductDetails):
}
def __init__(self, **kwargs):
super(FirefoxDesktop, self).__init__(**kwargs)
super().__init__(**kwargs)
def platforms(self, channel="release", classified=False):
"""
@ -258,8 +258,8 @@ class FirefoxDesktop(_ProductDetails):
# Bug 1345467 - Only allow specifically configured funnelcake builds
if funnelcake_id:
fc_platforms = config("FUNNELCAKE_%s_PLATFORMS" % funnelcake_id, default="", parser=ListOf(str))
fc_locales = config("FUNNELCAKE_%s_LOCALES" % funnelcake_id, default="", parser=ListOf(str))
fc_platforms = config(f"FUNNELCAKE_{funnelcake_id}_PLATFORMS", default="", parser=ListOf(str))
fc_locales = config(f"FUNNELCAKE_{funnelcake_id}_LOCALES", default="", parser=ListOf(str))
include_funnelcake_param = platform in fc_platforms and _locale in fc_locales
# Check if direct download link has been requested
@ -269,15 +269,15 @@ class FirefoxDesktop(_ProductDetails):
transition_url = self.download_base_url_transition
if funnelcake_id:
# include funnelcake in scene 2 URL
transition_url += "?f=%s" % funnelcake_id
transition_url += f"?f={funnelcake_id}"
if locale_in_transition:
transition_url = "/%s%s" % (locale, transition_url)
transition_url = f"/{locale}{transition_url}"
return transition_url
# otherwise build a full download URL
prod_name = "firefox" if channel == "release" else "firefox-%s" % channel
prod_name = "firefox" if channel == "release" else f"firefox-{channel}"
suffix = "latest-ssl"
if is_msi:
suffix = "msi-" + suffix
@ -291,7 +291,7 @@ class FirefoxDesktop(_ProductDetails):
# Use the stub installer for approved platforms
# append funnelcake id to version if we have one
if include_funnelcake_param:
suffix = "stub-f%s" % funnelcake_id
suffix = f"stub-f{funnelcake_id}"
else:
suffix = "stub"
elif channel == "nightly" and locale != "en-US":
@ -301,7 +301,7 @@ class FirefoxDesktop(_ProductDetails):
if is_msi:
suffix = "msi-" + suffix
product = "%s-%s" % (prod_name, suffix)
product = f"{prod_name}-{suffix}"
return "?".join(
[

Просмотреть файл

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -150,7 +150,7 @@ def download_firefox(
alt_channel = "" if channel == "release" else channel
locale = locale or get_locale(ctx["request"])
funnelcake_id = ctx.get("funnelcake_id", False)
dom_id = dom_id or "download-button-%s-%s" % ("desktop" if platform == "all" else platform, channel)
dom_id = dom_id or f"download-button-{'desktop' if platform == 'all' else platform}-{channel}"
# Gather data about the build for each platform
builds = []
@ -174,7 +174,7 @@ def download_firefox(
data = {
"locale_name": locale_name,
"version": version,
"product": "firefox-%s" % platform,
"product": f"firefox-{platform}",
"builds": builds,
"id": dom_id,
"channel": alt_channel,
@ -216,10 +216,10 @@ def download_firefox_thanks(ctx, dom_id=None, locale=None, alt_copy=None, button
# if there's a funnelcake param in the page URL e.g. ?f=123
if funnelcake_id:
# include param in transitional URL e.g. /firefox/download/thanks/?f=123
transition_url += "?f=%s" % funnelcake_id
transition_url += f"?f={funnelcake_id}"
if locale_in_transition:
transition_url = "/%s%s" % (locale, transition_url)
transition_url = f"/{locale}{transition_url}"
download_link_direct = firefox_desktop.get_download_url(
channel,
@ -259,7 +259,7 @@ def download_firefox_desktop_list(ctx, channel="release", dom_id=None, locale=No
the stub installer (for aurora).
"""
dom_id = dom_id or "download-platform-list-%s" % (channel)
dom_id = dom_id or f"download-platform-list-{channel}"
locale = locale or get_locale(ctx["request"])
# Make sure funnelcake_id is not passed as builds are often Windows only.

Просмотреть файл

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
import os
from unittest.mock import Mock, call, patch
from django.core.cache import caches
from django.http import HttpResponse
@ -11,7 +11,6 @@ from django.test.utils import override_settings
from django_jinja.backend import Jinja2
from jinja2 import Markup
from mock import Mock, call, patch
from pyquery import PyQuery as pq
from bedrock.base.urlresolvers import reverse

Просмотреть файл

@ -1,14 +1,12 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
import os
from unittest.mock import Mock, patch
from urllib.parse import parse_qsl, urlparse
from django.core.cache import caches
from mock import Mock, patch
from bedrock.firefox.firefox_details import FirefoxAndroid, FirefoxDesktop, FirefoxIOS
from bedrock.mozorg.tests import TestCase

Просмотреть файл

@ -34,7 +34,7 @@ class TestDownloadButtons(TestCase):
"""Desktop links should have the correct firefox version"""
# valid product strings
keys = [
"firefox-%s" % self.latest_version(),
f"firefox-{self.latest_version()}",
"firefox-stub",
"firefox-latest-ssl",
"firefox-beta-stub",
@ -375,7 +375,7 @@ class TestDownloadList(TestCase):
"""Desktop links should have the correct firefox version"""
# valid product strings
keys = [
"firefox-%s" % self.latest_version(),
f"firefox-{self.latest_version()}",
"firefox-stub",
"firefox-latest-ssl",
"firefox-msi-latest-ssl",
@ -483,9 +483,9 @@ class TestFirefoxURL(TestCase):
def _render(self, platform, page, channel=None):
req = self.rf.get("/")
if channel:
tmpl = "{{ firefox_url('%s', '%s', '%s') }}" % (platform, page, channel)
tmpl = f"{{{{ firefox_url('{platform}', '{page}', '{channel}') }}}}"
else:
tmpl = "{{ firefox_url('%s', '%s') }}" % (platform, page)
tmpl = f"{{{{ firefox_url('{platform}', '{page}') }}}}"
return render(tmpl, {"request": req})
def test_firefox_all(self):

Просмотреть файл

@ -1,10 +1,10 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
import json
import os
from unittest.mock import ANY, patch
from urllib.parse import parse_qs
from django.http import HttpResponse
@ -12,7 +12,6 @@ from django.test import override_settings
from django.test.client import RequestFactory
import querystringsafe_base64
from mock import ANY, patch
from pyquery import PyQuery as pq
from bedrock.firefox import views

Просмотреть файл

@ -84,11 +84,11 @@ urlpatterns = (
re_path(firstrun_re, views.FirstrunView.as_view(), name="firefox.firstrun"),
re_path(whatsnew_re, views.WhatsnewView.as_view(), name="firefox.whatsnew"),
# Release notes
re_path("^firefox/(?:%s/)?(?:%s/)?notes/$" % (platform_re, channel_re), bedrock.releasenotes.views.latest_notes, name="firefox.notes"),
re_path(f"^firefox/(?:{platform_re}/)?(?:{channel_re}/)?notes/$", bedrock.releasenotes.views.latest_notes, name="firefox.notes"),
path("firefox/nightly/notes/feed/", bedrock.releasenotes.views.nightly_feed, name="firefox.nightly.notes.feed"),
re_path("firefox/(?:latest/)?releasenotes/$", bedrock.releasenotes.views.latest_notes, {"product": "firefox"}),
re_path(
"^firefox/(?:%s/)?(?:%s/)?system-requirements/$" % (platform_re, channel_re),
f"^firefox/(?:{platform_re}/)?(?:{channel_re}/)?system-requirements/$",
bedrock.releasenotes.views.latest_sysreq,
{"product": "firefox"},
name="firefox.sysreq",

Просмотреть файл

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
@ -74,7 +72,7 @@ class InstallerHelpView(L10nTemplateView):
ftl_files = ["firefox/installer-help"]
def get_context_data(self, **kwargs):
ctx = super(InstallerHelpView, self).get_context_data(**kwargs)
ctx = super().get_context_data(**kwargs)
installer_lang = self.request.GET.get("installer_lang", None)
installer_channel = self.request.GET.get("channel", None)
ctx["installer_lang"] = None
@ -420,10 +418,10 @@ class FirstrunView(l10n_utils.LangFilesMixin, TemplateView):
if redirect_old_firstrun(version):
return HttpResponsePermanentRedirect(reverse("firefox.new"))
else:
return super(FirstrunView, self).get(*args, **kwargs)
return super().get(*args, **kwargs)
def get_context_data(self, **kwargs):
ctx = super(FirstrunView, self).get_context_data(**kwargs)
ctx = super().get_context_data(**kwargs)
# add version to context for use in templates
ctx["version"] = self.kwargs.get("version") or ""
@ -481,7 +479,7 @@ class WhatsnewView(L10nTemplateView):
variations = ["1", "2", "3"]
def get_context_data(self, **kwargs):
ctx = super(WhatsnewView, self).get_context_data(**kwargs)
ctx = super().get_context_data(**kwargs)
version = self.kwargs.get("version") or ""
pre_release_channels = ["nightly", "developer", "beta"]
channel = detect_channel(version)
@ -512,7 +510,7 @@ class WhatsnewView(L10nTemplateView):
ctx["analytics_version"] = analytics_version
ctx["entrypoint"] = entrypoint
ctx["campaign"] = campaign
ctx["utm_params"] = "utm_source={0}&utm_medium=referral&utm_campaign={1}&entrypoint={2}".format(entrypoint, campaign, entrypoint)
ctx["utm_params"] = f"utm_source={entrypoint}&utm_medium=referral&utm_campaign={campaign}&entrypoint={entrypoint}"
variant = self.request.GET.get("v", None)
@ -605,7 +603,7 @@ class DownloadThanksView(L10nTemplateView):
variations = []
def get_context_data(self, **kwargs):
ctx = super(DownloadThanksView, self).get_context_data(**kwargs)
ctx = super().get_context_data(**kwargs)
variant = self.request.GET.get("v", None)
# ensure variant matches pre-defined value
@ -662,7 +660,7 @@ class NewView(L10nTemplateView):
thanks_url = "?".join([thanks_url, force_text(query_string, errors="ignore")])
return HttpResponsePermanentRedirect(thanks_url)
return super(NewView, self).get(*args, **kwargs)
return super().get(*args, **kwargs)
def render_to_response(self, context, **response_kwargs):
# set experimental percentages per locale with this config
@ -693,7 +691,7 @@ class NewView(L10nTemplateView):
return super().render_to_response(context, **response_kwargs)
def get_context_data(self, **kwargs):
ctx = super(NewView, self).get_context_data(**kwargs)
ctx = super().get_context_data(**kwargs)
# note: v and xv params only allow a-z, A-Z, 0-9, -, and _ characters
variant = self.request.GET.get("v", None)
@ -776,7 +774,7 @@ class FirefoxHomeView(L10nTemplateView):
variations = []
def get_context_data(self, **kwargs):
ctx = super(FirefoxHomeView, self).get_context_data(**kwargs)
ctx = super().get_context_data(**kwargs)
variant = self.request.GET.get("v", None)
# ensure variant matches pre-defined value

Просмотреть файл

@ -1,5 +1,3 @@
# coding: utf-8
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -1,14 +1,13 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from io import BytesIO
from unittest.mock import Mock, patch
from django.core import mail
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test.client import RequestFactory
from mock import Mock, patch
from PIL import Image
from bedrock.base.urlresolvers import reverse

Просмотреть файл

@ -67,7 +67,7 @@ def fraud_report(request):
# send a response to avoid problem described below.
# @see https://bugzilla.mozilla.org/show_bug.cgi?id=873476 (3.2)
response = redirect(reverse("legal.fraud-report"), template_vars)
response["Location"] += "?submitted=%s" % form_submitted
response["Location"] += f"?submitted={form_submitted}"
return response
else:

Просмотреть файл

@ -27,7 +27,7 @@ def process_md_file(file_path):
extensions=["markdown.extensions.attr_list", "markdown.extensions.toc", OutlineExtension((("wrapper_cls", ""),))],
)
content = output.getvalue().decode("utf-8")
except IOError:
except OSError:
content = None
finally:
output.close()

Просмотреть файл

@ -3,12 +3,11 @@
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from pathlib import Path
from unittest.mock import patch
from django.http import Http404, HttpResponse
from django.test import RequestFactory, override_settings
from mock import patch
from bedrock.legal_docs import views
from bedrock.legal_docs.models import LegalDoc, get_data_from_file_path
from bedrock.mozorg.tests import TestCase
@ -98,7 +97,7 @@ class TestLegalDocView(TestCase):
req.locale = "de"
view = views.LegalDocView.as_view(template_name="base.html", legal_doc_name="the_dude_exists")
resp = view(req)
assert resp["cache-control"] == "max-age={0!s}".format(views.CACHE_TIMEOUT)
assert resp["cache-control"] == f"max-age={views.CACHE_TIMEOUT!s}"
assert resp.content.decode("utf-8") == doc_value
assert render_mock.call_args[0][2]["doc"] == doc_value
lld_mock.assert_called_with("the_dude_exists", "de")

Просмотреть файл

@ -72,7 +72,7 @@ class LegalDocView(TemplateView):
if legal_doc is None:
raise Http404("Legal doc not found")
context = super(LegalDocView, self).get_context_data(**kwargs)
context = super().get_context_data(**kwargs)
context[self.legal_doc_context_name] = legal_doc["content"]
context["active_locales"] = legal_doc["active_locales"]
return context
@ -80,4 +80,4 @@ class LegalDocView(TemplateView):
@classmethod
def as_view(cls, **initkwargs):
cache_timeout = initkwargs.pop("cache_timeout", cls.cache_timeout)
return cache_page(cache_timeout)(super(LegalDocView, cls).as_view(**initkwargs))
return cache_page(cache_timeout)(super().as_view(**initkwargs))

Просмотреть файл

@ -14,7 +14,7 @@ class CreditsFile(ExternalFile):
def validate_content(self, content):
rows = list(csv.reader(content.strip().split("\n")))
if len(rows) < 2200: # it's 2273 as of now
raise ValueError("Much smaller file than expected. {0} rows.".format(len(rows)))
raise ValueError(f"Much smaller file than expected. {len(rows)} rows.")
if len(rows[0]) != 2 or len(rows[-1]) != 2:
raise ValueError("CSV Content corrupted.")

Просмотреть файл

@ -1,5 +1,3 @@
# coding: utf-8
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
@ -32,13 +30,11 @@ class PrivacyWidget(widgets.CheckboxInput):
def render(self, name, value, attrs=None, renderer=None):
attrs["required"] = "required"
input_txt = super(PrivacyWidget, self).render(name, value, attrs)
input_txt = super().render(name, value, attrs)
policy_txt = ftl("newsletter-form-im-okay-with-mozilla", url=reverse("privacy.notices.websites"))
return mark_safe(
'<label for="%s" class="privacy-check-label">' "%s " '<span class="title">%s</span></label>' % (attrs["id"], input_txt, policy_txt)
)
return mark_safe(f"""<label for="{attrs['id']}" class="privacy-check-label">{input_txt}<span class="title">{policy_txt}</span></label>""")
class HoneyPotWidget(widgets.TextInput):

Просмотреть файл

@ -125,7 +125,7 @@ class PageNode:
return None
def __repr__(self):
return '{0}(display_name="{1}", path="{2}", template="{3})"'.format(self.__class__.__name__, self.display_name, self.full_path, self.template)
return f'{self.__class__.__name__}(display_name="{self.display_name}", path="{self.full_path}", template="{self.template})"'
class PageRoot(PageNode):
@ -137,7 +137,7 @@ class PageRoot(PageNode):
"""
def __init__(self, *args, **kwargs):
super(PageRoot, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
# Buid a pre-order traversal of this tree's nodes.
self.preordered_nodes = []

Просмотреть файл

@ -35,7 +35,7 @@ class Command(BaseCommand):
# fake last-modified string since the releng repo doesn't store those files
# and we rely on git commits for updates
self.last_modified = datetime.now().isoformat()
super(Command, self).__init__(stdout, stderr, no_color)
super().__init__(stdout, stderr, no_color)
def add_arguments(self, parser):
parser.add_argument("-q", "--quiet", action="store_true", dest="quiet", default=False, help="If no error occurs, swallow all output."),
@ -92,7 +92,7 @@ class Command(BaseCommand):
return
builds = len([locale for locale, build in self.file_storage.data("firefox_primary_builds.json").items() if version in build])
if builds < min_builds:
raise ValueError("Too few builds for {}".format(version_key))
raise ValueError(f"Too few builds for {version_key}")
def validate_data(self):
self.file_storage.clear_cache()

Просмотреть файл

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
@ -44,6 +43,6 @@ class Migration(migrations.Migration):
),
migrations.AlterUniqueTogether(
name="contributoractivity",
unique_together=set([("date", "source_name", "team_name")]),
unique_together={("date", "source_name", "team_name")},
),
]

Просмотреть файл

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -188,7 +188,7 @@ def platform_img(ctx, url, optional_attributes=None):
img_attrs["data-high-res"] = "true"
img_attrs.update(optional_attributes)
attrs = " ".join('%s="%s"' % (attr, val) for attr, val in img_attrs.items())
attrs = " ".join(f'{attr}="{val}"' for attr, val in img_attrs.items())
# Don't download any image until the javascript sets it based on
# data-src so we can do platform detection. If no js, show the
@ -217,15 +217,13 @@ def high_res_img(ctx, url, optional_attributes=None):
if optional_attributes:
class_name = optional_attributes.pop("class", "")
attrs = " " + " ".join('%s="%s"' % (attr, val) for attr, val in optional_attributes.items())
attrs = " " + " ".join(f'{attr}="{val}"' for attr, val in optional_attributes.items())
else:
class_name = ""
attrs = ""
# Use native srcset attribute for high res images
markup = ('<img class="{class_name}" src="{url}" ' 'srcset="{url_high_res} 1.5x"' "{attrs}>").format(
url=url, url_high_res=url_high_res, attrs=attrs, class_name=class_name
)
markup = f'<img class="{class_name}" src="{url}" srcset="{url_high_res} 1.5x"{attrs}>'
return jinja2.Markup(markup)
@ -609,7 +607,7 @@ def f(s, *args, **kwargs):
>>> {{ "{0} arguments and {x} arguments"|f('positional', x='keyword') }}
"positional arguments and keyword arguments"
"""
s = six.text_type(s)
s = str(s)
return s.format(*args, **kwargs)
@ -803,7 +801,7 @@ def _fxa_product_url(product_url, entrypoint, optional_parameters=None):
url = f"{product_url}{separator}entrypoint={entrypoint}&form_type=button&utm_source={entrypoint}&utm_medium=referral"
if optional_parameters:
params = "&".join("%s=%s" % (param, val) for param, val in optional_parameters.items())
params = "&".join(f"{param}={val}" for param, val in optional_parameters.items())
url += f"&{params}"
return url
@ -824,7 +822,7 @@ def _fxa_product_button(
attrs = ""
if optional_attributes:
attrs += " ".join('%s="%s"' % (attr, val) for attr, val in optional_attributes.items())
attrs += " ".join(f'{attr}="{val}"' for attr, val in optional_attributes.items())
if include_metrics:
css_class += " js-fxa-product-button"

Просмотреть файл

@ -17,7 +17,7 @@ cache = caches["qrcode"]
@library.global_function
def qrcode(data, box_size=20):
key = sha1(f"{data}-{box_size}".encode("utf-8")).hexdigest()
key = sha1(f"{data}-{box_size}".encode()).hexdigest()
svg = cache.get(key)
if not svg:
img = qr.make(data, image_factory=SvgPathImage, box_size=box_size)

Просмотреть файл

@ -19,7 +19,7 @@ class TestCase(DjTestCase):
old_prefix = get_url_prefix()
old_locale = translation.get_language()
rf = RequestFactory()
set_url_prefix(Prefixer(rf.get("/%s/" % (locale,))))
set_url_prefix(Prefixer(rf.get(f"/{locale}/")))
translation.activate(locale)
yield
set_url_prefix(old_prefix)

Просмотреть файл

@ -1,13 +1,11 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from pathlib import Path
from unittest.mock import DEFAULT, patch
from django.test import override_settings
from mock import DEFAULT, patch
from bedrock.mozorg.management.commands import update_product_details_files
from bedrock.mozorg.tests import TestCase

Просмотреть файл

@ -1,11 +1,9 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from collections import OrderedDict
from textwrap import dedent
from mock import Mock
from unittest.mock import Mock
from bedrock.mozorg import credits
from bedrock.mozorg.tests import TestCase

Просмотреть файл

@ -22,7 +22,7 @@ class ViewDecoratorTests(TestCase):
test_request = self.rf.get("/hi-there-dude/")
resp = view(test_request)
num_seconds = hours * 60 * 60
self.assertEqual(resp["cache-control"], "max-age=%d" % num_seconds)
self.assertEqual(resp["cache-control"], f"max-age={num_seconds}")
now_date = floor(time.time())
exp_date = parse_http_date(resp["expires"])

Просмотреть файл

@ -6,6 +6,7 @@
import os.path
from datetime import datetime
from unittest.mock import patch
from django.conf import settings
from django.test.client import RequestFactory
@ -14,7 +15,6 @@ from django.test.utils import override_settings
import pytest
from django_jinja.backend import Jinja2
from jinja2 import Markup
from mock import patch
from pyquery import PyQuery as pq
from bedrock.base.templatetags.helpers import static
@ -62,7 +62,7 @@ class TestImgL10n(TestCase):
def _render(self, locale, url):
req = self.rf.get("/")
req.locale = locale
return render("{{{{ l10n_img('{0}') }}}}".format(url), {"request": req})
return render(f"{{{{ l10n_img('{url}') }}}}", {"request": req})
def test_works_for_default_lang(self, media_exists_mock):
"""Should output correct path for default lang always."""
@ -215,12 +215,12 @@ class TestPlatformImg(TestCase):
def _render(self, url, optional_attributes=None):
req = self.rf.get("/")
req.locale = "en-US"
return render("{{{{ platform_img('{0}', {1}) }}}}".format(url, optional_attributes), {"request": req})
return render(f"{{{{ platform_img('{url}', {optional_attributes}) }}}}", {"request": req})
def _render_l10n(self, url):
req = self.rf.get("/")
req.locale = "en-US"
return render("{{{{ l10n_img('{0}') }}}}".format(url), {"request": req})
return render(f"{{{{ l10n_img('{url}') }}}}", {"request": req})
def test_platform_img_no_optional_attributes(self, find_static):
"""Should return expected markup without optional attributes"""
@ -335,7 +335,7 @@ class TestDonateUrl(TestCase):
def _render(self, locale, source=""):
req = self.rf.get("/")
req.locale = locale
return render("{{{{ donate_url('{0}') }}}}".format(source), {"request": req})
return render(f"{{{{ donate_url('{source}') }}}}", {"request": req})
def test_donate_url_no_locale(self):
"""No locale, fallback to generic link"""
@ -464,12 +464,12 @@ class TestHighResImg(TestCase):
def _render(self, url, optional_attributes=None):
req = self.rf.get("/")
req.locale = "en-US"
return render("{{{{ high_res_img('{0}', {1}) }}}}".format(url, optional_attributes), {"request": req})
return render(f"{{{{ high_res_img('{url}', {optional_attributes}) }}}}", {"request": req})
def _render_l10n(self, url):
req = self.rf.get("/")
req.locale = "en-US"
return render("{{{{ l10n_img('{0}') }}}}".format(url), {"request": req})
return render(f"{{{{ l10n_img('{url}') }}}}", {"request": req})
def test_high_res_img_no_optional_attributes(self):
"""Should return expected markup without optional attributes"""
@ -695,7 +695,7 @@ class TestStructuredDataID(TestCase):
sd_id = "firefoxbrowser"
if domain:
return render("{{{{ structured_data_id('{0}', '{1}') }}}}".format(sd_id, domain), {"request": req})
return render(f"{{{{ structured_data_id('{sd_id}', '{domain}') }}}}", {"request": req})
return render("{{ structured_data_id('%s') }}" % sd_id, {"request": req})
@ -737,9 +737,9 @@ class TestFirefoxAdjustUrl(TestCase):
req.locale = locale
if creative:
return render("{{{{ firefox_adjust_url('{0}', '{1}', '{2}') }}}}".format(redirect, adgroup, creative), {"request": req})
return render(f"{{{{ firefox_adjust_url('{redirect}', '{adgroup}', '{creative}') }}}}", {"request": req})
return render("{{{{ firefox_adjust_url('{0}', '{1}') }}}}".format(redirect, adgroup), {"request": req})
return render(f"{{{{ firefox_adjust_url('{redirect}', '{adgroup}') }}}}", {"request": req})
def test_firefox_ios_adjust_url(self):
"""Firefox for mobile with an App Store URL redirect"""
@ -778,9 +778,9 @@ class TestFocusAdjustUrl(TestCase):
req.locale = locale
if creative:
return render("{{{{ focus_adjust_url('{0}', '{1}', '{2}') }}}}".format(redirect, adgroup, creative), {"request": req})
return render(f"{{{{ focus_adjust_url('{redirect}', '{adgroup}', '{creative}') }}}}", {"request": req})
return render("{{{{ focus_adjust_url('{0}', '{1}') }}}}".format(redirect, adgroup), {"request": req})
return render(f"{{{{ focus_adjust_url('{redirect}', '{adgroup}') }}}}", {"request": req})
def test_focus_ios_adjust_url(self):
"""Firefox Focus with an App Store URL redirect"""
@ -835,9 +835,9 @@ class TestLockwiseAdjustUrl(TestCase):
req.locale = locale
if creative:
return render("{{{{ lockwise_adjust_url('{0}', '{1}', '{2}') }}}}".format(redirect, adgroup, creative), {"request": req})
return render(f"{{{{ lockwise_adjust_url('{redirect}', '{adgroup}', '{creative}') }}}}", {"request": req})
return render("{{{{ lockwise_adjust_url('{0}', '{1}') }}}}".format(redirect, adgroup), {"request": req})
return render(f"{{{{ lockwise_adjust_url('{redirect}', '{adgroup}') }}}}", {"request": req})
def test_lockwise_ios_adjust_url(self):
"""Firefox Lockwise for mobile with an App Store URL redirect"""
@ -876,9 +876,9 @@ class TestPocketAdjustUrl(TestCase):
req.locale = locale
if creative:
return render("{{{{ pocket_adjust_url('{0}', '{1}', '{2}') }}}}".format(redirect, adgroup, creative), {"request": req})
return render(f"{{{{ pocket_adjust_url('{redirect}', '{adgroup}', '{creative}') }}}}", {"request": req})
return render("{{{{ pocket_adjust_url('{0}', '{1}') }}}}".format(redirect, adgroup), {"request": req})
return render(f"{{{{ pocket_adjust_url('{redirect}', '{adgroup}') }}}}", {"request": req})
def test_pocket_ios_adjust_url(self):
"""Pocket for mobile with an App Store URL redirect"""
@ -1135,7 +1135,7 @@ class TestFxALinkFragment(TestCase):
def _render(self, entrypoint, action="signup", optional_parameters=None):
req = self.rf.get("/")
req.locale = "en-US"
return render("{{{{ fxa_link_fragment('{0}', '{1}', {2}) }}}}".format(entrypoint, action, optional_parameters), {"request": req})
return render(f"{{{{ fxa_link_fragment('{entrypoint}', '{action}', {optional_parameters}) }}}}", {"request": req})
def test_fxa_button_signup(self):
"""Should return expected markup"""

Просмотреть файл

@ -2,7 +2,8 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from mock import patch
from unittest.mock import patch
from qrcode.image.svg import SvgPathImage
from bedrock.mozorg.templatetags.qrcode import qrcode

Просмотреть файл

@ -2,7 +2,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from mock import patch
from unittest.mock import patch
from bedrock.mozorg.hierarchy import PageNode, PageRoot
from bedrock.mozorg.tests import TestCase

Просмотреть файл

@ -1,15 +1,12 @@
# coding=utf-8
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
import os
from unittest.mock import ANY, patch
from django.test import RequestFactory
from mock import ANY, patch
from bedrock.mozorg.tests import TestCase
from bedrock.mozorg.util import get_fb_like_locale, page

Просмотреть файл

@ -1,14 +1,13 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
import os
from unittest.mock import ANY, Mock, patch
from django.http.response import HttpResponse
from django.test.client import RequestFactory
import pytest
from mock import ANY, Mock, patch
from bedrock.base.urlresolvers import reverse
from bedrock.mozorg import views

Просмотреть файл

@ -14,7 +14,7 @@ def mock_view(request):
urlpatterns = [
path("", include("%s.urls" % settings.PROJECT_MODULE)),
path("", include(f"{settings.PROJECT_MODULE}.urls")),
# Used by test_helper
page("base", "base-protocol.html"),
]

Просмотреть файл

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
@ -75,7 +74,7 @@ class BooleanTabularRadioSelect(widgets.RadioSelect):
("true", ftl("newsletter-form-yes")),
("false", ftl("newsletter-form-no")),
)
super(BooleanTabularRadioSelect, self).__init__(attrs, choices)
super().__init__(attrs, choices)
def format_value(self, value):
try:
@ -98,7 +97,7 @@ class BooleanTabularRadioSelect(widgets.RadioSelect):
}.get(value)
def get_context(self, name, value, attrs):
context = super(BooleanTabularRadioSelect, self).get_context(name, value, attrs)
context = super().get_context(name, value, attrs)
context["wrap_label"] = False
return context
@ -107,7 +106,7 @@ class TableCheckboxInput(widgets.CheckboxInput):
"""Add table cell markup around the rendered checkbox"""
def render(self, *args, **kwargs):
out = super(TableCheckboxInput, self).render(*args, **kwargs)
out = super().render(*args, **kwargs)
return mark_safe("<td>" + out + "</td>")
@ -123,7 +122,7 @@ class CountrySelectForm(forms.Form):
def __init__(self, locale, *args, **kwargs):
regions = product_details.get_regions(locale)
regions = sorted(iter(regions.items()), key=itemgetter(1))
super(CountrySelectForm, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self.fields["country"].choices = regions
@ -193,7 +192,7 @@ class ManageSubscriptionsForm(forms.Form):
initial["lang"] = lang
kwargs["initial"] = initial
super(ManageSubscriptionsForm, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self.fields["country"].choices = regions
self.fields["lang"].choices = lang_choices
@ -205,7 +204,7 @@ class ManageSubscriptionsForm(forms.Form):
if newsletter not in valid_newsletters:
msg = ftl("newsletters-is-not-a-valid-newsletter", newsletter=newsletter, ftl_files=["mozorg/newsletters"])
raise ValidationError(msg)
return super(ManageSubscriptionsForm, self).clean()
return super().clean()
class NewsletterForm(forms.Form):
@ -273,7 +272,7 @@ class NewsletterFooterForm(forms.Form):
lang = ""
lang_choices.insert(0, ("", ftl_lazy("newsletter-form-available-languages")))
super(NewsletterFooterForm, self).__init__(data, *args, **kwargs)
super().__init__(data, *args, **kwargs)
required_args = {
"required": "required",

Просмотреть файл

@ -23,6 +23,6 @@ class Command(BaseCommand):
count = Newsletter.objects.refresh(newsletters)
if not options["quiet"]:
if count:
print("Updated %d newsletters" % count)
print(f"Updated {count} newsletters")
else:
print("Nothing to update")

Просмотреть файл

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -2,7 +2,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from mock import Mock
from unittest.mock import Mock
from bedrock.newsletter import utils

Просмотреть файл

@ -2,9 +2,10 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from unittest.mock import patch
from django.test.utils import override_settings
from mock import patch
from pyquery import PyQuery as pq
from bedrock.base.urlresolvers import reverse

Просмотреть файл

@ -1,7 +1,7 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
import mock
from unittest import mock
from bedrock.mozorg.tests import TestCase
from bedrock.newsletter.forms import (

Просмотреть файл

@ -2,7 +2,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
import mock
from unittest import mock
from bedrock.mozorg.tests import TestCase
from bedrock.newsletter import utils

Просмотреть файл

@ -3,13 +3,13 @@
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
import json
import uuid
from unittest.mock import ANY, DEFAULT, patch
from django.http import HttpResponse
from django.test.client import RequestFactory
from django.test.utils import override_settings
import basket
from mock import ANY, DEFAULT, patch
from pyquery import PyQuery as pq
from bedrock.base.urlresolvers import reverse
@ -85,14 +85,14 @@ class TestExistingNewsletterView(TestCase):
"form-3-subscribed_check": "false",
"submit": "Save Preferences",
}
super(TestExistingNewsletterView, self).setUp()
super().setUp()
@patch("bedrock.newsletter.utils.get_newsletters")
def test_will_show_confirm_copy(self, get_newsletters, mock_basket_request):
# After successful confirm, ensure proper context var is set to display
# confirmation-specific copy.
get_newsletters.return_value = newsletters
url = "%s?confirm=1" % reverse("newsletter.existing.token", args=(self.token,))
url = f"{reverse('newsletter.existing.token', args=(self.token,))}?confirm=1"
# noinspection PyUnresolvedReferences
with patch.multiple("basket", request=DEFAULT) as basket_patches:
with patch("lib.l10n_utils.render") as render:
@ -138,9 +138,9 @@ class TestExistingNewsletterView(TestCase):
request, template_name, context = render.call_args[0]
forms = context["formset"].initial_forms
shown = set([form.initial["newsletter"] for form in forms])
inactive = set([newsletter for newsletter, data in newsletters.items() if not data.get("active", False)])
to_show = set([newsletter for newsletter, data in newsletters.items() if data.get("show", False)]) - inactive
shown = {form.initial["newsletter"] for form in forms}
inactive = {newsletter for newsletter, data in newsletters.items() if not data.get("active", False)}
to_show = {newsletter for newsletter, data in newsletters.items() if data.get("show", False)} - inactive
subscribed = set(self.user["newsletters"])
# All subscribed newsletters except inactive ones are shown
@ -226,9 +226,9 @@ class TestExistingNewsletterView(TestCase):
# Should have called update_user with subscription list
self.assertEqual(1, basket_patches["update_user"].call_count)
kwargs = basket_patches["update_user"].call_args[1]
self.assertEqual(set(kwargs), set(["api_key", "newsletters", "lang"]))
self.assertEqual(set(kwargs), {"api_key", "newsletters", "lang"})
self.assertEqual(kwargs["lang"], "en")
self.assertEqual(set(kwargs["newsletters"].split(",")), set(["mozilla-and-you", "firefox-tips"]))
self.assertEqual(set(kwargs["newsletters"].split(",")), {"mozilla-and-you", "firefox-tips"})
# Should not have called unsubscribe
self.assertEqual(0, basket_patches["unsubscribe"].call_count)
# Should not have called subscribe
@ -278,8 +278,7 @@ class TestExistingNewsletterView(TestCase):
self.assertEqual((self.token, self.user["email"]), args)
self.assertTrue(kwargs["optout"])
# Should redirect to the 'updated' view with unsub=1 and token
url = reverse("newsletter.updated") + "?unsub=1"
url += "&token=%s" % self.token
url = f"{reverse('newsletter.updated')}?unsub=1&token={self.token}"
assert rsp["Location"] == url
@patch("bedrock.newsletter.utils.get_newsletters")
@ -365,7 +364,7 @@ class TestConfirmView(TestCase):
confirm.return_value = {"status": "ok"}
rsp = self.client.get(self.url)
self.assertEqual(302, rsp.status_code)
self.assertTrue(rsp["Location"].endswith("%s?confirm=1" % reverse("newsletter.existing.token", kwargs={"token": self.token})))
self.assertTrue(rsp["Location"].endswith(f"{reverse('newsletter.existing.token', kwargs={'token': self.token})}?confirm=1"))
def test_normal_with_query_params(self):
"""Confirm works with a valid token"""
@ -375,8 +374,8 @@ class TestConfirmView(TestCase):
self.assertEqual(302, rsp.status_code)
self.assertTrue(
rsp["Location"].endswith(
"%s?confirm=1&utm_tracking=oh+definitely+yes&"
"utm_source=malibu" % reverse("newsletter.existing.token", kwargs={"token": self.token})
f"{reverse('newsletter.existing.token', kwargs={'token': self.token})}"
"?confirm=1&utm_tracking=oh+definitely+yes&utm_source=malibu"
)
)

Просмотреть файл

@ -230,7 +230,7 @@ def confirm(request, token):
try:
result = basket.confirm(token)
except basket.BasketException as e:
log.exception("Exception confirming token %s" % token)
log.exception(f"Exception confirming token {token}")
if e.code == basket.errors.BASKET_UNKNOWN_TOKEN:
token_error = True
elif e.code == basket.errors.BASKET_USAGE_ERROR:
@ -253,7 +253,7 @@ def confirm(request, token):
qs = request.META.get("QUERY_STRING", "")
if qs:
qparams.append(qs)
return HttpResponseRedirect("%s?%s" % (reverse("newsletter.existing.token", kwargs={"token": token}), "&".join(qparams)))
return HttpResponseRedirect("{}?{}".format(reverse("newsletter.existing.token", kwargs={"token": token}), "&".join(qparams)))
else:
return l10n_utils.render(
request, "newsletter/confirm.html", {"success": success, "generic_error": generic_error, "token_error": token_error}, ftl_files=FTL_FILES
@ -400,13 +400,11 @@ def existing(request, token=None):
if formset.is_valid():
formset_is_valid = True
# What newsletters do they say they want to be subscribed to?
newsletters = set(
[
subform.cleaned_data["newsletter"]
for subform in formset
if (subform.cleaned_data["subscribed_radio"] or subform.cleaned_data["subscribed_check"])
]
)
newsletters = {
subform.cleaned_data["newsletter"]
for subform in formset
if (subform.cleaned_data["subscribed_radio"] or subform.cleaned_data["subscribed_check"])
}
form_kwargs["newsletters"] = newsletters
form = ManageSubscriptionsForm(locale, data=request.POST, initial=user, **form_kwargs)
@ -445,7 +443,7 @@ def existing(request, token=None):
messages.add_message(request, messages.ERROR, general_error)
return l10n_utils.render(request, "newsletter/existing.html", ftl_files=FTL_FILES)
# We need to pass their token to the next view
url = reverse("newsletter.updated") + "?unsub=%s&token=%s" % (UNSUB_UNSUBSCRIBED_ALL, token)
url = reverse("newsletter.updated") + f"?unsub={UNSUB_UNSUBSCRIBED_ALL}&token={token}"
return redirect(url)
# We're going to redirect, so the only way to tell the next
@ -453,7 +451,7 @@ def existing(request, token=None):
# template is to modify the URL
url = reverse("newsletter.updated")
if unsub_parm:
url += "?unsub=%s" % unsub_parm
url += f"?unsub={unsub_parm}"
return redirect(url)
# FALL THROUGH so page displays errors
@ -540,7 +538,7 @@ def updated(request):
# paste together the English versions of the reasons they submitted,
# so we can read them. (Well, except for the free-form reason.)
for i, reason in enumerate(REASONS):
if _post_or_get(request, "reason%d" % i):
if _post_or_get(request, f"reason{i}"):
reasons.append(str(reason))
if _post_or_get(request, "reason-text-p"):
reasons.append(_post_or_get(request, "reason-text", ""))
@ -617,8 +615,8 @@ def newsletter_subscribe(request):
kwargs = {"format": data["fmt"]}
# add optional data
kwargs.update(
dict(
(k, data[k])
{
k: data[k]
for k in [
"country",
"lang",
@ -627,7 +625,7 @@ def newsletter_subscribe(request):
"last_name",
]
if data[k]
)
}
)
# NOTE this is not a typo; Referrer is misspelled in the HTTP spec
@ -641,7 +639,7 @@ def newsletter_subscribe(request):
if e.code == basket.errors.BASKET_INVALID_EMAIL:
errors.append(str(invalid_email_address))
else:
log.exception("Error subscribing %s to newsletter %s" % (data["email"], data["newsletters"]))
log.exception(f"Error subscribing {data['email']} to newsletter {data['newsletters']}")
errors.append(str(general_error))
else:

Просмотреть файл

@ -23,10 +23,10 @@ class Command(BaseCommand):
if not options["quiet"]:
if updated:
print("Refreshed %s articles from Pocket" % updated)
print(f"Refreshed {updated} articles from Pocket")
if deleted:
print("Deleted %s old articles" % deleted)
print(f"Deleted {deleted} old articles")
else:
print("Pocket feed is already up to date")
else:

Просмотреть файл

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -3,12 +3,11 @@
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
import datetime
from unittest.mock import patch
from django.test import override_settings
from django.utils.timezone import make_aware, utc
from mock import patch
from bedrock.pocketfeed import api

Просмотреть файл

@ -1,5 +1,3 @@
# coding: utf-8
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
@ -44,7 +42,7 @@ class PressInquiryForm(forms.Form):
office_fax = forms.CharField(widget=HoneyPotWidget, required=False)
def clean_office_fax(self):
cleaned_data = super(PressInquiryForm, self).clean()
cleaned_data = super().clean()
honeypot = cleaned_data.pop("office_fax", None)
if honeypot:
@ -299,7 +297,7 @@ class SpeakerRequestForm(forms.Form):
office_fax = forms.CharField(widget=HoneyPotWidget, required=False)
def clean_sr_attachment(self):
cleaned_data = super(SpeakerRequestForm, self).clean()
cleaned_data = super().clean()
attachment = cleaned_data.get("sr_attachment")
if attachment:
@ -309,7 +307,7 @@ class SpeakerRequestForm(forms.Form):
return attachment
def clean_office_fax(self):
cleaned_data = super(SpeakerRequestForm, self).clean()
cleaned_data = super().clean()
honeypot = cleaned_data.pop("office_fax", None)
if honeypot:

Просмотреть файл

@ -1,15 +1,13 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
import datetime
from unittest.mock import Mock, patch
from django.core import mail
from django.test.client import RequestFactory
from mock import Mock, patch
from bedrock.base.urlresolvers import reverse
from bedrock.mozorg.tests import TestCase
from bedrock.press import forms as press_forms, views as press_views

Просмотреть файл

@ -26,10 +26,10 @@ class PressInquiryView(FormView):
@method_decorator(csrf_protect)
def dispatch(self, request, *args, **kwargs):
return super(PressInquiryView, self).dispatch(request, *args, **kwargs)
return super().dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(PressInquiryView, self).get_context_data(**kwargs)
context = super().get_context_data(**kwargs)
context["form_success"] = "success" in self.request.GET
return context
@ -38,7 +38,7 @@ class PressInquiryView(FormView):
def form_valid(self, form):
self.send_email(form)
return super(PressInquiryView, self).form_valid(form)
return super().form_valid(form)
def send_email(self, form):
subject = PRESS_INQUIRY_EMAIL_SUBJECT
@ -59,15 +59,15 @@ class SpeakerRequestView(FormView):
@method_decorator(csrf_protect)
def dispatch(self, request, *args, **kwargs):
return super(SpeakerRequestView, self).dispatch(request, *args, **kwargs)
return super().dispatch(request, *args, **kwargs)
def get_form_kwargs(self):
kwargs = super(SpeakerRequestView, self).get_form_kwargs()
kwargs = super().get_form_kwargs()
kwargs["auto_id"] = "%s"
return kwargs
def get_context_data(self, **kwargs):
context = super(SpeakerRequestView, self).get_context_data(**kwargs)
context = super().get_context_data(**kwargs)
context["form_success"] = "success" in self.request.GET
return context
@ -76,7 +76,7 @@ class SpeakerRequestView(FormView):
def form_valid(self, form):
self.send_email(form)
return super(SpeakerRequestView, self).form_valid(form)
return super().form_valid(form)
def send_email(self, form):
subject = SPEAKER_REQUEST_EMAIL_SUBJECT

Просмотреть файл

@ -34,7 +34,7 @@ def process_legal_doc(content):
class PrivacyDocView(LegalDocView):
def get_legal_doc(self):
doc = super(PrivacyDocView, self).get_legal_doc()
doc = super().get_legal_doc()
if doc is not None:
doc["content"] = process_legal_doc(doc["content"])
return doc
@ -42,7 +42,7 @@ class PrivacyDocView(LegalDocView):
class FirefoxPrivacyDocView(PrivacyDocView):
def get_legal_doc(self):
doc = super(FirefoxPrivacyDocView, self).get_legal_doc()
doc = super().get_legal_doc()
if len(doc["content"].select(".privacy-header-firefox")) > 0:
self.template_name = "privacy/notices/firefox.html"
else:

Просмотреть файл

@ -29,14 +29,14 @@ def _vpn_product_link(product_url, entrypoint, link_text, class_name=None, optio
href = f"{product_url}{separator}entrypoint={entrypoint}&form_type=button&service={client_id}&utm_source={entrypoint}&utm_medium=referral"
if optional_parameters:
params = "&".join("%s=%s" % (param, val) for param, val in optional_parameters.items())
params = "&".join(f"{param}={val}" for param, val in optional_parameters.items())
href += f"&{params}"
css_class = "js-vpn-cta-link js-fxa-product-button"
attrs = ""
if optional_attributes:
attrs += " ".join('%s="%s"' % (attr, val) for attr, val in optional_attributes.items())
attrs += " ".join(f'{attr}="{val}"' for attr, val in optional_attributes.items())
# If there's a `data-cta-position` attribute for GA, also pass that as a query param to vpn.m.o.
position = optional_attributes.get("data-cta-position", None)
@ -201,7 +201,7 @@ def vpn_product_referral_link(ctx, referral_id="", page_anchor="", link_text=Non
attrs = f'data-referral-id="{referral_id}" '
if optional_attributes:
attrs += " ".join('%s="%s"' % (attr, val) for attr, val in optional_attributes.items())
attrs += " ".join(f'{attr}="{val}"' for attr, val in optional_attributes.items())
if class_name:
css_class += f" {class_name}"

Просмотреть файл

@ -704,7 +704,7 @@ class TestVPNMonthlyPrice(TestCase):
def _render(self, plan, country_code, lang):
req = self.rf.get("/")
req.locale = "en-US"
return render("{{{{ vpn_monthly_price('{0}', '{1}', '{2}') }}}}".format(plan, country_code, lang), {"request": req})
return render(f"{{{{ vpn_monthly_price('{plan}', '{country_code}', '{lang}') }}}}", {"request": req})
def test_vpn_monthly_price_usd(self):
"""Should return expected markup"""

Просмотреть файл

@ -3,14 +3,13 @@
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
import json
from unittest.mock import Mock, patch
from django.http import HttpResponse
from django.test import override_settings
from django.test.client import RequestFactory
from django.urls import reverse
from mock import Mock, patch
from bedrock.contentful.constants import (
CONTENT_CLASSIFICATION_VPN,
CONTENT_TYPE_PAGE_RESOURCE_CENTER,

Просмотреть файл

@ -1,14 +1,13 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from unittest.mock import patch
from urllib.parse import parse_qs, urlparse
from django.test import TestCase
from django.test.client import RequestFactory
from django.urls import URLPattern
from mock import patch
from bedrock.redirects.middleware import RedirectsMiddleware
from bedrock.redirects.util import (
get_resolver,

Просмотреть файл

@ -102,7 +102,7 @@ def no_redirect(pattern, locale_prefix=True, re_flags=None):
pattern = LOCALE_RE + pattern
if re_flags:
pattern = "(?{})".format(re_flags) + pattern
pattern = f"(?{re_flags})" + pattern
def _view(request, *args, **kwargs):
return None
@ -175,7 +175,7 @@ def redirect(
pattern = LOCALE_RE + pattern
if re_flags:
pattern = "(?{})".format(re_flags) + pattern
pattern = f"(?{re_flags})" + pattern
view_decorators = []
if cache_timeout is not None:

Просмотреть файл

@ -32,7 +32,7 @@ class Command(BaseCommand):
self.output("Loading releases into database")
count = ProductRelease.objects.refresh()
self.output("%s release notes successfully loaded" % count)
self.output(f"{count} release notes successfully loaded")
repo.set_db_latest()

Просмотреть файл

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -123,7 +123,7 @@ class MarkdownField(models.TextField):
"""Field that takes Markdown text as input and saves HTML to the database"""
def pre_save(self, model_instance, add):
value = super(MarkdownField, self).pre_save(model_instance, add)
value = super().pre_save(model_instance, add)
value = process_markdown(value)
setattr(model_instance, self.attname, value)
return value
@ -271,7 +271,7 @@ class ProductRelease(models.Model):
channel and major version with the highest minor version,
or None if no such releases exist
"""
releases = ProductRelease.objects.product(product, self.channel).filter(version__startswith="%s." % self.major_version)
releases = ProductRelease.objects.product(product, self.channel).filter(version__startswith=f"{self.major_version}.")
if releases:
return sorted(releases, reverse=True, key=attrgetter("version_obj"))[0]

Просмотреть файл

@ -3,11 +3,10 @@
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
import time
from unittest.mock import Mock, patch
from django.core.cache import caches
from mock import Mock, patch
from bedrock.mozorg.tests import TestCase
from bedrock.releasenotes import utils

Просмотреть файл

@ -3,14 +3,13 @@
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from pathlib import Path
from unittest.mock import Mock, patch
from django.core.cache import caches
from django.http import Http404, HttpResponse
from django.test.client import RequestFactory
from django.test.utils import override_settings
from mock import Mock, patch
from bedrock.base.urlresolvers import reverse
from bedrock.firefox.firefox_details import FirefoxDesktop
from bedrock.mozorg.tests import TestCase

Просмотреть файл

@ -4,12 +4,11 @@
from itertools import chain
from pathlib import Path
from unittest.mock import call, patch
from django.core.cache import caches
from django.test.utils import override_settings
from mock import call, patch
from bedrock.mozorg.tests import TestCase
from bedrock.releasenotes import models

Просмотреть файл

@ -28,14 +28,14 @@ class ReleaseMemoizer(Memoizer):
def __init__(self, version_timeout=300):
self.version_timeout = version_timeout
return super(ReleaseMemoizer, self).__init__(cache=caches["release-notes"])
return super().__init__(cache=caches["release-notes"])
def _memoize_make_version_hash(self):
return get_data_version()
def _memoize_version(self, f, args=None, reset=False, delete=False, timeout=None):
"""Use a shorter timeout for the version so that we can refresh based on git hash"""
return super(ReleaseMemoizer, self)._memoize_version(f, args, reset, delete, self.version_timeout)
return super()._memoize_version(f, args, reset, delete, self.version_timeout)
memoizer = ReleaseMemoizer()

Просмотреть файл

@ -35,7 +35,7 @@ def release_notes_template(channel, product, version=None):
dir = "firefox"
return "{dir}/releases/{channel}-notes.html".format(dir=dir, channel=channel.lower())
return f"{dir}/releases/{channel.lower()}-notes.html"
def equivalent_release_url(release):
@ -130,7 +130,7 @@ def release_notes(request, version, product="Firefox"):
def system_requirements(request, version, product="Firefox"):
release = get_release_or_404(version, product)
dir = "firefox"
return l10n_utils.render(request, "{dir}/releases/system_requirements.html".format(dir=dir), {"release": release, "version": version})
return l10n_utils.render(request, f"{dir}/releases/system_requirements.html", {"release": release, "version": version})
def latest_release(product="firefox", platform=None, channel=None):
@ -184,9 +184,7 @@ def releases_index(request, product):
),
}
return l10n_utils.render(
request, "{product}/releases/index.html".format(product=product.lower()), {"releases": sorted(releases.items(), reverse=True)}
)
return l10n_utils.render(request, f"{product.lower()}/releases/index.html", {"releases": sorted(releases.items(), reverse=True)})
def nightly_feed(request):
@ -205,7 +203,7 @@ def nightly_feed(request):
continue
if note.is_public and note.tag:
note.link = "%s#note-%s" % (link, note.id)
note.link = f"{link}#note-{note.id}"
note.version = release.version
notes[note.id] = note

Просмотреть файл

@ -175,7 +175,7 @@ def update_db_from_file(filename):
elif filename.endswith(".yml"):
parser = parse_yml_file
else:
raise RuntimeError("Unknown file type %s" % filename)
raise RuntimeError(f"Unknown file type {filename}")
data, html = parser(filename)
if "advisories" in data:
@ -207,7 +207,7 @@ def get_files_to_delete_from_db(filenames):
file_ids = set(get_ids_from_files(filenames))
db_ids = set(SecurityAdvisory.objects.values_list("id", flat=True))
to_delete = db_ids - file_ids
return ["mfsa{0}.md".format(fid) for fid in to_delete]
return [f"mfsa{fid}.md" for fid in to_delete]
def delete_orphaned_products():
@ -280,7 +280,7 @@ class Command(CronCommand):
try:
update_db_from_file(mf)
except Exception as e:
errors.append("ERROR parsing %s: %s" % (mf, e))
errors.append(f"ERROR parsing {mf}: {e}")
if not quiet:
sys.stdout.write("E")
sys.stdout.flush()
@ -289,17 +289,17 @@ class Command(CronCommand):
sys.stdout.write(".")
sys.stdout.flush()
updates += 1
printout("\nUpdated {0} files.".format(updates))
printout(f"\nUpdated {updates} files.")
if not clear_db:
deleted_files = get_files_to_delete_from_db(all_files)
delete_files(deleted_files)
printout("Deleted {0} files.".format(len(deleted_files)))
printout(f"Deleted {len(deleted_files)} files.")
num_products = delete_orphaned_products()
if num_products:
printout("Deleted {0} orphaned products.".format(num_products))
printout(f"Deleted {num_products} orphaned products.")
if errors:
raise CommandError("Encountered {0} errors:\n\n".format(len(errors)) + "\n==========\n".join(errors))
raise CommandError(f"Encountered {len(errors)} errors:\n\n" + "\n==========\n".join(errors))
repo.set_db_latest()

Просмотреть файл

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше