switch from black to ruff format (#21384)

* switch from black to ruff format

* Update Makefile-docker
This commit is contained in:
Andrew Williamson 2023-11-02 14:35:10 +00:00 коммит произвёл GitHub
Родитель f852abe6a6
Коммит 9ffd8c12a7
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
31 изменённых файлов: 110 добавлений и 128 удалений

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

@ -165,8 +165,8 @@ perf-tests: setup-ui-tests
.PHONY: lint
lint: ## lint the code
black --check src/ tests/
ruff check .
ruff format --check .
NODE_PATH=$(NODE_MODULES) npm exec $(NPM_ARGS) -- prettier --check '**'
curlylint src/
@ -233,7 +233,7 @@ watch_js_tests: ## Run+watch the JavaScript test suite (requires compiled/compre
format: ## Autoformat our codebase.
NODE_PATH=$(NODE_MODULES) npm exec $(NPM_ARGS) -- prettier --write '**'
ruff check --fix-only .
black src/ tests/
ruff format .
.PHONY: help_submake
help_submake:

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

@ -66,23 +66,27 @@ def mock_basket(settings):
Tests that do need basket to work should disable `responses`
and add a passthrough.
"""
USER_TOKEN = u'13f64f64-1de7-42f6-8c7f-a19e2fae5021'
USER_TOKEN = '13f64f64-1de7-42f6-8c7f-a19e2fae5021'
responses.add(
responses.GET,
settings.BASKET_URL + '/news/lookup-user/',
json={'status': 'ok', 'newsletters': [], 'token': USER_TOKEN})
json={'status': 'ok', 'newsletters': [], 'token': USER_TOKEN},
)
responses.add(
responses.POST,
settings.BASKET_URL + '/news/subscribe/',
json={'status': 'ok', 'token': USER_TOKEN})
json={'status': 'ok', 'token': USER_TOKEN},
)
responses.add(
responses.POST,
settings.BASKET_URL + '/news/unsubscribe/{}/'.format(USER_TOKEN),
json={'status': 'ok', 'token': USER_TOKEN})
json={'status': 'ok', 'token': USER_TOKEN},
)
def pytest_configure(config):
import django
# Forcefully call `django.setup`, pytest-django tries to be very lazy
# and doesn't call it if it has already been setup.
# That is problematic for us since we overwrite our logging config
@ -93,6 +97,7 @@ def pytest_configure(config):
django.setup()
from olympia.amo.tests import prefix_indexes
prefix_indexes(config)
@ -108,8 +113,7 @@ def instrument_jinja():
def instrumented_render(self, *args, **kwargs):
context = dict(*args, **kwargs)
test.signals.template_rendered.send(
sender=self, template=self, context=context)
test.signals.template_rendered.send(sender=self, template=self, context=context)
return old_render(self, *args, **kwargs)
jinja2.Template.render = instrumented_render
@ -177,8 +181,7 @@ def test_pre_setup(request, tmpdir, settings):
return path
settings.STORAGE_ROOT = storage_root = _path(str(tmpdir.mkdir('storage')))
settings.SHARED_STORAGE = shared_storage = _path(
storage_root, 'shared_storage')
settings.SHARED_STORAGE = shared_storage = _path(storage_root, 'shared_storage')
settings.ADDONS_PATH = _path(storage_root, 'files')
settings.GUARDED_ADDONS_PATH = _path(storage_root, 'guarded-addons')
@ -214,6 +217,7 @@ def test_pre_setup(request, tmpdir, settings):
def admin_group(db):
"""Create the Admins group."""
from olympia.access.models import Group
return Group.objects.create(name='Admins', rules='*:*')
@ -223,9 +227,9 @@ def mozilla_user(admin_group, settings):
from olympia.access.models import GroupUser
from olympia.users.models import UserProfile
user = UserProfile.objects.create(pk=settings.TASK_USER_ID,
email='admin@mozilla.com',
username='admin')
user = UserProfile.objects.create(
pk=settings.TASK_USER_ID, email='admin@mozilla.com', username='admin'
)
user.save()
GroupUser.objects.create(user=user, group=admin_group)
return user

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

@ -19,10 +19,14 @@ def to_locale(language):
p = language.find('-')
if p >= 0:
# Get correct locale for sr-latn
if len(language[p + 1:]) > 2:
return (language[:p].lower() + '_' + language[p + 1].upper() +
language[p + 2:].lower())
return language[:p].lower() + '_' + language[p + 1:].upper()
if len(language[p + 1 :]) > 2:
return (
language[:p].lower()
+ '_'
+ language[p + 1].upper()
+ language[p + 2 :].lower()
)
return language[:p].lower() + '_' + language[p + 1 :].upper()
else:
return language.lower()
@ -52,8 +56,10 @@ def extract_translations_for_given_locale(all_translations, locale):
def main():
if not os.path.isdir('locale'):
print('Sorry, please run from the root of the project, '
'eg. ./locale/generate_category_po_files.py')
print(
'Sorry, please run from the root of the project, '
'eg. ./locale/generate_category_po_files.py'
)
return
print('Loading translations JSON dump...')
@ -71,14 +77,16 @@ def main():
continue
translations_for_this_locale = extract_translations_for_given_locale(
all_translations, locale)
all_translations, locale
)
if not translations_for_this_locale:
print('Skipping locale %s, it has no translations :(' % locale)
continue
print('Writing %d translations to %s' % (
len(translations_for_this_locale), fname))
print(
'Writing %d translations to %s' % (len(translations_for_this_locale), fname)
)
write_po(fname, translations_for_this_locale)

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

@ -1,19 +1,3 @@
[tool.black]
line-length = 88
target-version = ['py310']
skip-string-normalization = true
extend-exclude = '''
(
/(
docs
| static
| \.git
)/
| src/.*/migrations/.*\.py
| src/olympia/translations/tests/testapp/migrations/.*\.py
)
'''
[tool.ruff]
exclude = [
"docs",
@ -37,6 +21,10 @@ select = [
[tool.ruff.flake8-quotes]
inline-quotes = "single"
[tool.ruff.format]
quote-style = "single"
line-ending = "lf"
[tool.ruff.isort]
combine-as-imports = true
lines-after-imports = 2

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

@ -18,36 +18,9 @@ curlylint==0.13.1 \
toml==0.10.2 \
--hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \
--hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f
black==23.9.1 \
--hash=sha256:031e8c69f3d3b09e1aa471a926a1eeb0b9071f80b17689a655f7885ac9325a6f \
--hash=sha256:13a2e4a93bb8ca74a749b6974925c27219bb3df4d42fc45e948a5d9feb5122b7 \
--hash=sha256:13ef033794029b85dfea8032c9d3b92b42b526f1ff4bf13b2182ce4e917f5100 \
--hash=sha256:14f04c990259576acd093871e7e9b14918eb28f1866f91968ff5524293f9c573 \
--hash=sha256:24b6b3ff5c6d9ea08a8888f6977eae858e1f340d7260cf56d70a49823236b62d \
--hash=sha256:403397c033adbc45c2bd41747da1f7fc7eaa44efbee256b53842470d4ac5a70f \
--hash=sha256:50254ebfa56aa46a9fdd5d651f9637485068a1adf42270148cd101cdf56e0ad9 \
--hash=sha256:538efb451cd50f43aba394e9ec7ad55a37598faae3348d723b59ea8e91616300 \
--hash=sha256:638619a559280de0c2aa4d76f504891c9860bb8fa214267358f0a20f27c12948 \
--hash=sha256:6a3b50e4b93f43b34a9d3ef00d9b6728b4a722c997c99ab09102fd5efdb88325 \
--hash=sha256:6ccd59584cc834b6d127628713e4b6b968e5f79572da66284532525a042549f9 \
--hash=sha256:75a2dc41b183d4872d3a500d2b9c9016e67ed95738a3624f4751a0cb4818fe71 \
--hash=sha256:7d30ec46de88091e4316b17ae58bbbfc12b2de05e069030f6b747dfc649ad186 \
--hash=sha256:8431445bf62d2a914b541da7ab3e2b4f3bc052d2ccbf157ebad18ea126efb91f \
--hash=sha256:8fc1ddcf83f996247505db6b715294eba56ea9372e107fd54963c7553f2b6dfe \
--hash=sha256:a732b82747235e0542c03bf352c126052c0fbc458d8a239a94701175b17d4855 \
--hash=sha256:adc3e4442eef57f99b5590b245a328aad19c99552e0bdc7f0b04db6656debd80 \
--hash=sha256:c46767e8df1b7beefb0899c4a95fb43058fa8500b6db144f4ff3ca38eb2f6393 \
--hash=sha256:c619f063c2d68f19b2d7270f4cf3192cb81c9ec5bc5ba02df91471d0b88c4c5c \
--hash=sha256:cf3a4d00e4cdb6734b64bf23cd4341421e8953615cba6b3670453737a72ec204 \
--hash=sha256:cf99f3de8b3273a8317681d8194ea222f10e0133a24a7548c73ce44ea1679377 \
--hash=sha256:d6bc09188020c9ac2555a498949401ab35bb6bf76d4e0f8ee251694664df6301
mypy-extensions==1.0.0 \
--hash=sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d \
--hash=sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782
# platformdirs is required by black
platformdirs==3.11.0 \
--hash=sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3 \
--hash=sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e
tomli==2.0.1 \
--hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
--hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f

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

@ -23,7 +23,10 @@ if __name__ == '__main__':
parser.add_argument('--keep-runtime-typing', action='store_true')
parser.add_argument(
'--py38-plus',
action='store_const', dest='min_version', default=(3, 8), const=(3, 8),
action='store_const',
dest='min_version',
default=(3, 8),
const=(3, 8),
)
args = parser.parse_args()

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

@ -294,8 +294,9 @@ class TestCheckAndUpdateFxaAccessToken(TestCase):
self.get_fxa_token_mock.assert_called_with(
refresh_token='refreshing!', config=settings.FXA_CONFIG['default']
)
assert request.session['fxa_access_token_expiry'] == (
self.get_fxa_token_mock.return_value['access_token_expiry']
assert (
request.session['fxa_access_token_expiry']
== (self.get_fxa_token_mock.return_value['access_token_expiry'])
)
@freeze_time()

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

@ -1033,7 +1033,9 @@ class TestAuthenticateView(TestCase, InitializeSessionMixin):
},
)
self.assertRedirects(
response, self.user_edit_url, target_status_code=200 # No '?to=...'
response,
self.user_edit_url, # No '?to=...'
target_status_code=200,
)
assert (
response['Cache-Control']

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

@ -114,8 +114,7 @@ class AddonIndexer:
db_field = '%s_id' % field
extend_with_me = {
'%s_translations'
% field: [
'%s_translations' % field: [
{'lang': to_language(lang), 'string': str(string)}
for lang, string in obj.translations[getattr(obj, db_field)]
if string

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

@ -272,9 +272,8 @@ class AddonManager(ManagerBase):
# select_related('_current_version__autoapprovalsummary') from
# working, because it overrides the _current_version with the one
# it fetches. We want translations though, but only for the name.
.only_translations().defer(
*[x.name for x in Addon._meta.translated_fields if x.name != 'name']
)
.only_translations()
.defer(*[x.name for x in Addon._meta.translated_fields if x.name != 'name'])
)
# Useful joins to avoid extra queries.
select_related_fields = [

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

@ -204,7 +204,7 @@ class ConstantlyRecalculateWeightTestCase(TestCase):
rating=2,
body='Apocalypse',
user=user_factory(),
),
)
# *not considered* - current version is auto-approved but
# has a recent rating with rating > 3
@ -219,7 +219,7 @@ class ConstantlyRecalculateWeightTestCase(TestCase):
rating=4,
body='Apocalypse',
user=user_factory(),
),
)
# *not considered* - current version is auto-approved but
# has a recent rating with rating > 3
@ -234,7 +234,7 @@ class ConstantlyRecalculateWeightTestCase(TestCase):
rating=4,
body='Apocalypse',
user=user_factory(),
),
)
# *not considered* - current version is auto-approved but
# has a low rating that isn't recent enough
@ -249,7 +249,7 @@ class ConstantlyRecalculateWeightTestCase(TestCase):
rating=1,
body='Apocalypse',
user=user_factory(),
),
)
# *considered* - current version is auto-approved and
# has a recent abuse report
@ -311,7 +311,7 @@ class ConstantlyRecalculateWeightTestCase(TestCase):
rating=2,
body='Apocalypse',
user=user_factory(),
),
)
# *considered* - current version is auto-approved and
# has an abuse report through it's author that is recent enough

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

@ -101,8 +101,7 @@ def process_failure_signal(
def start_task_timer(task_id, task, **kw):
timer = TaskTimer()
log.info(
'starting task timer; id={id}; name={name}; '
'current_dt={current_dt}'.format(
'starting task timer; id={id}; name={name}; current_dt={current_dt}'.format(
id=task_id, name=task.name, current_dt=timer.current_datetime
)
)

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

@ -290,8 +290,9 @@ def handle_upload_validation_result(results, upload_pk, is_mozilla_signed):
# TODO: actually fix this so we can get stats. It seems that
# the file maybe gets moved but it needs more investigation.
log.warning(
'Scaled upload stats were not tracked. File is '
'missing: {}'.format(upload.file_path)
'Scaled upload stats were not tracked. File is missing: {}'.format(
upload.file_path
)
)
return

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

@ -173,8 +173,9 @@ class TestAddManifestVersionMessages(TestCase):
# for an unlisted submission.
assert len(results['messages']) == 1
# It should be inserted at the top.
assert 'https://blog.mozilla.org/addons/2021/05/27/manifest-v3-update/' in (
results['messages'][0]['message']
assert (
'https://blog.mozilla.org/addons/2021/05/27/manifest-v3-update/'
in (results['messages'][0]['message'])
)
def test_add_manifest_version_message_not_mv3(self):
@ -207,9 +208,12 @@ class TestAddManifestVersionMessages(TestCase):
assert (
results['messages'][0]['message'] == 'Manifest V3 compatibility warning'
)
assert 'https://mzl.la/3hIwQXX' in (
# description is a list of strings, the link is in the second one.
results['messages'][0]['description'][1]
assert (
'https://mzl.la/3hIwQXX'
in (
# description is a list of strings, the link is in the second one.
results['messages'][0]['description'][1]
)
)
def test_add_manifest_version_message(self):
@ -226,8 +230,9 @@ class TestAddManifestVersionMessages(TestCase):
)
assert len(results['messages']) == 2 # we added it
# It should be inserted at the top.
assert 'https://blog.mozilla.org/addons/2021/05/27/manifest-v3-update/' in (
results['messages'][0]['message']
assert (
'https://blog.mozilla.org/addons/2021/05/27/manifest-v3-update/'
in (results['messages'][0]['message'])
)
def test_add_manifest_version_message_replace(self):
@ -248,6 +253,7 @@ class TestAddManifestVersionMessages(TestCase):
results=results, parsed_data=data, channel=amo.CHANNEL_LISTED
)
assert len(results['messages']) == 1 # we replaced it and not added it.
assert 'https://blog.mozilla.org/addons/2021/05/27/manifest-v3-update/' in (
results['messages'][0]['message']
assert (
'https://blog.mozilla.org/addons/2021/05/27/manifest-v3-update/'
in (results['messages'][0]['message'])
)

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

@ -141,7 +141,7 @@ class TestNewUploadForm(TestCase):
assert (
'There was an error with your upload. Please try again.'
in form.errors.get('__all__')
), (form.errors)
), form.errors
# Admin override makes the form ignore the brokenness
with mock.patch('olympia.access.acl.action_allowed_for') as acl:
@ -184,7 +184,7 @@ class TestNewUploadForm(TestCase):
assert (
'There was an error with your upload. Please try again.'
in form.errors.get('__all__')
), (form.errors)
), form.errors
# Admin override can bypass
with mock.patch('olympia.access.acl.action_allowed_for') as acl:

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

@ -1790,8 +1790,8 @@ class TestRequestReview(TestCase):
response = self.client.post(self.public_url)
self.assert3xx(response, self.redirect_url)
assert self.get_addon().status == amo.STATUS_NOMINATED
assert self.get_version().due_date.timetuple()[0:5] != (
orig_date.timetuple()[0:5]
assert (
self.get_version().due_date.timetuple()[0:5] != (orig_date.timetuple()[0:5])
)

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

@ -1251,8 +1251,8 @@ class DetailsPageMixin:
self.get_version().update(due_date=duedate, _signal=False)
# Update something else in the addon:
self.get_addon().update(slug='foobar')
assert self.get_version().due_date.timetuple()[0:5] == (
duedate.timetuple()[0:5]
assert (
self.get_version().due_date.timetuple()[0:5] == (duedate.timetuple()[0:5])
)
def test_submit_details_unlisted_should_redirect(self):

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

@ -543,7 +543,7 @@ class TestUploadURLs(TestCase):
self.upload('devhub.standalone_upload')
self.expect_validation(channel=amo.CHANNEL_LISTED)
self.upload('devhub.standalone_upload_unlisted'),
self.upload('devhub.standalone_upload_unlisted')
self.expect_validation(channel=amo.CHANNEL_UNLISTED)
def test_upload_submit(self):
@ -552,7 +552,7 @@ class TestUploadURLs(TestCase):
self.upload('devhub.upload')
self.expect_validation(channel=amo.CHANNEL_LISTED)
self.upload('devhub.upload_unlisted'),
self.upload('devhub.upload_unlisted')
self.expect_validation(channel=amo.CHANNEL_UNLISTED)
def test_upload_addon_version(self):

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

@ -341,8 +341,9 @@ def create_version_for_upload(addon, upload, channel, parsed_data=None):
return None
else:
log.info(
'Creating version for {upload_uuid} that passed '
'validation'.format(upload_uuid=upload.uuid)
'Creating version for {upload_uuid} that passed validation'.format(
upload_uuid=upload.uuid
)
)
# Note: if we somehow managed to get here with an invalid add-on,
# parse_addon() will raise ValidationError and the task will fail

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

@ -834,8 +834,9 @@ class TestSecondaryHeroShelfAdmin(TestCase):
follow=True,
)
assert response.status_code == 200
assert 'There must be exactly 3 modules in this shelf.' in (
response.context_data['errors']
assert (
'There must be exactly 3 modules in this shelf.'
in (response.context_data['errors'])
)
assert SecondaryHero.objects.count() == 0

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

@ -698,8 +698,7 @@ class AddonGitRepository:
or (
# See:
# https://github.com/mozilla/addons-server/issues/15966
patch.delta.status == pygit2.GIT_DELTA_MODIFIED
and len(hunks) == 0
patch.delta.status == pygit2.GIT_DELTA_MODIFIED and len(hunks) == 0
)
)
)

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

@ -187,8 +187,9 @@ def sign_file(file_obj):
# though we didn't sign, it's not an error - we just don't need to do
# anything in this case.
log.info(
'Not signing file {}: mozilla signed extension is already '
'signed'.format(file_obj.pk)
'Not signing file {}: mozilla signed extension is already signed'.format(
file_obj.pk
)
)
return file_obj

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

@ -109,7 +109,7 @@ DRF_API_REGEX = r'^/?api/(?:auth|v3|v4|v5)/'
CORS_ALLOW_ALL_ORIGINS = True
# Exclude the `accounts/session` endpoint, see:
# https://github.com/mozilla/addons-server/issues/11100
CORS_URLS_REGEX = fr'{DRF_API_REGEX}(?!accounts/session/)'
CORS_URLS_REGEX = rf'{DRF_API_REGEX}(?!accounts/session/)'
# https://github.com/mozilla/addons-server/issues/17364
CORS_ALLOW_HEADERS = list(default_headers) + [
'x-country-code',

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

@ -35,9 +35,7 @@ from ..views import RatingViewSet
locmem_cache = settings.CACHES.copy()
locmem_cache['default'][
'BACKEND'
] = 'django.core.cache.backends.locmem.LocMemCache' # noqa
locmem_cache['default']['BACKEND'] = 'django.core.cache.backends.locmem.LocMemCache' # noqa
class TestRatingViewSetGet(TestCase):

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

@ -800,8 +800,9 @@ class TestScannerResultAdmin(TestCase):
assert (
urlencode(
{
'title': 'False positive report for '
'ScannerResult {}'.format(result.pk)
'title': 'False positive report for ScannerResult {}'.format(
result.pk
)
}
)
in response['Location']

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

@ -64,7 +64,5 @@ def test_format_scanners_data_complex():
<li><dl>
<dt>extensionId:</dt><dd><a href="{expected_url}">@welp</a></dd>
</dl></li>
</ul>""".format(
expected_url=expected_url
)
</ul>""".format(expected_url=expected_url)
assert format_scanners_data(data) == expected

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

@ -612,7 +612,8 @@ class TestRankingScenarios(ESTestCase):
'This addon contains Amazon 1-Click Lock in its description '
' but not in its name.'
),
),
)
amo.tests.addon_factory(
name='Amazon 1-Click Lock',
type=amo.ADDON_EXTENSION,

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

@ -453,8 +453,9 @@ class TestUploadVersion(BaseUploadVersionTestMixin, TestCase):
response = self.request('PUT', self.url(self.guid, '3.0'), version='3.0')
assert response.status_code == 400
error_msg = 'cannot add versions to an add-on that has status: %s.' % (
amo.STATUS_CHOICES_ADDON[amo.STATUS_DISABLED]
error_msg = (
'cannot add versions to an add-on that has status: %s.'
% (amo.STATUS_CHOICES_ADDON[amo.STATUS_DISABLED])
)
assert error_msg in response.data['error']

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

@ -255,9 +255,9 @@ class TestCacheControl(StatsTestCase):
response = self.get_view_response(
'stats.downloads_series', head=True, group='month', format='json'
)
assert response.get('cache-control', '').startswith(
'max-age='
), 'Bad or no cache-control: %r' % response.get('cache-control', '')
assert response.get('cache-control', '').startswith('max-age='), (
'Bad or no cache-control: %r' % response.get('cache-control', '')
)
class TestLayout(StatsTestCase):

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

@ -7,8 +7,8 @@ group_re = r'(?P<group>' + '|'.join(views.SERIES_GROUPS) + ')'
group_date_re = r'(?P<group>' + '|'.join(views.SERIES_GROUPS_DATE) + ')'
range_re = r'(?P<start>\d{8})-(?P<end>\d{8})'
format_re = r'(?P<format>' + '|'.join(views.SERIES_FORMATS) + ')'
series_re = fr'{group_re}-{range_re}\.{format_re}$'
series = {type: fr'^{type}-{series_re}' for type in views.SERIES}
series_re = rf'{group_re}-{range_re}\.{format_re}$'
series = {type: rf'^{type}-{series_re}' for type in views.SERIES}
# Addon specific stats.
stats_patterns = [

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

@ -36,9 +36,7 @@ def update_user_ratings():
AND addons.status IN (%s)
AND addons.inactive = 0
GROUP BY addons_users.user_id
""" % (
','.join(map(str, VALID_ADDON_STATUSES))
)
""" % (','.join(map(str, VALID_ADDON_STATUSES)))
cursor.execute(q)
d = cursor.fetchall()