python: Convert more "".format to Python 3.6 f-strings.

Generated by pyupgrade --py36-plus --keep-percent-format, with more
restrictions patched out.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg 2020-06-09 21:40:53 -07:00 committed by Tim Abbott
parent 7b2255597c
commit 6480deaf27
27 changed files with 60 additions and 156 deletions

View File

@ -1096,9 +1096,7 @@ def support(request: HttpRequest) -> HttpResponse:
new_plan_type = int(new_plan_type) new_plan_type = int(new_plan_type)
current_plan_type = realm.plan_type current_plan_type = realm.plan_type
do_change_plan_type(realm, new_plan_type) do_change_plan_type(realm, new_plan_type)
msg = "Plan type of {} changed from {} to {} ".format(realm.name, msg = f"Plan type of {realm.name} changed from {get_plan_name(current_plan_type)} to {get_plan_name(new_plan_type)} "
get_plan_name(current_plan_type),
get_plan_name(new_plan_type))
context["message"] = msg context["message"] = msg
new_discount = request.POST.get("discount", None) new_discount = request.POST.get("discount", None)

View File

@ -64,8 +64,7 @@ def stripe_fixture_path(decorated_function_name: str, mocked_function_name: str,
# use test_* for the python test files # use test_* for the python test files
if decorated_function_name[:5] == 'test_': if decorated_function_name[:5] == 'test_':
decorated_function_name = decorated_function_name[5:] decorated_function_name = decorated_function_name[5:]
return "{}/{}--{}.{}.json".format( return f"{STRIPE_FIXTURES_DIR}/{decorated_function_name}--{mocked_function_name[7:]}.{call_count}.json"
STRIPE_FIXTURES_DIR, decorated_function_name, mocked_function_name[7:], call_count)
def fixture_files_for_function(decorated_function: CallableT) -> List[str]: # nocoverage def fixture_files_for_function(decorated_function: CallableT) -> List[str]: # nocoverage
decorated_function_name = decorated_function.__name__ decorated_function_name = decorated_function.__name__

View File

@ -257,13 +257,11 @@ python_rules = RuleList(
# This next check could have false positives, but it seems pretty # This next check could have false positives, but it seems pretty
# rare; if we find any, they can be added to the exclude list for # rare; if we find any, they can be added to the exclude list for
# this rule. # this rule.
{'pattern': r"""^(?:[^'"#\\]|{}|{})*(?:{}|{})\s*%\s*(?![\s({{\\]|dict\(|tuple\()(?:[^,{}]|{})+(?:$|[,#\\]|{})""".format( {'pattern': fr"""^(?:[^'"#\\]|{PYSQ}|{PYDQ})*(?:{PYSQ}|{PYDQ})\s*%\s*(?![\s({{\\]|dict\(|tuple\()(?:[^,{PYDELIMS}]|{PYGROUP})+(?:$|[,#\\]|{PYRIGHT})""",
PYSQ, PYDQ, PYSQ, PYDQ, PYDELIMS, PYGROUP, PYRIGHT),
'description': 'Used % formatting without a tuple', 'description': 'Used % formatting without a tuple',
'good_lines': ['"foo %s bar" % ("baz",)'], 'good_lines': ['"foo %s bar" % ("baz",)'],
'bad_lines': ['"foo %s bar" % "baz"']}, 'bad_lines': ['"foo %s bar" % "baz"']},
{'pattern': r"""^(?:[^'"#\\]|{}|{})*(?:{}|{})\s*%\s*\((?:[^,{}]|{})*\)""".format( {'pattern': fr"""^(?:[^'"#\\]|{PYSQ}|{PYDQ})*(?:{PYSQ}|{PYDQ})\s*%\s*\((?:[^,{PYDELIMS}]|{PYGROUP})*\)""",
PYSQ, PYDQ, PYSQ, PYDQ, PYDELIMS, PYGROUP),
'description': 'Used % formatting with parentheses that do not form a tuple', 'description': 'Used % formatting with parentheses that do not form a tuple',
'good_lines': ['"foo %s bar" % ("baz",)"'], 'good_lines': ['"foo %s bar" % ("baz",)"'],
'bad_lines': ['"foo %s bar" % ("baz")']}, 'bad_lines': ['"foo %s bar" % ("baz")']},

View File

@ -57,10 +57,7 @@ class AttachmentHandler:
size = os.path.getsize(local_fn) size = os.path.getsize(local_fn)
mtime = os.path.getmtime(local_fn) mtime = os.path.getmtime(local_fn)
content = '[{name}](/user_uploads/{path})'.format( content = f'[{name}](/user_uploads/{target_path})'
name=name,
path=target_path,
)
info = dict( info = dict(
message_ids={message_id}, message_ids={message_id},

View File

@ -300,8 +300,7 @@ def get_user_email(user: ZerverFieldsT, domain_name: str) -> str:
raise AssertionError("Could not find email address for Slack user %s" % (user,)) raise AssertionError("Could not find email address for Slack user %s" % (user,))
def build_avatar_url(slack_user_id: str, team_id: str, avatar_hash: str) -> str: def build_avatar_url(slack_user_id: str, team_id: str, avatar_hash: str) -> str:
avatar_url = "https://ca.slack-edge.com/{}-{}-{}".format(team_id, slack_user_id, avatar_url = f"https://ca.slack-edge.com/{team_id}-{slack_user_id}-{avatar_hash}"
avatar_hash)
return avatar_url return avatar_url
def get_owner(user: ZerverFieldsT) -> bool: def get_owner(user: ZerverFieldsT) -> bool:

View File

@ -1718,8 +1718,7 @@ class StreamTopicPattern(CompiledPattern):
el.set('data-stream-id', str(stream['id'])) el.set('data-stream-id', str(stream['id']))
stream_url = encode_stream(stream['id'], stream_name) stream_url = encode_stream(stream['id'], stream_name)
topic_url = hash_util_encode(topic_name) topic_url = hash_util_encode(topic_name)
link = '/#narrow/stream/{stream_url}/topic/{topic_url}'.format(stream_url=stream_url, link = f'/#narrow/stream/{stream_url}/topic/{topic_url}'
topic_url=topic_url)
el.set('href', link) el.set('href', link)
text = f'#{stream_name} > {topic_name}' text = f'#{stream_name} > {topic_name}'
el.text = markdown.util.AtomicString(text) el.text = markdown.util.AtomicString(text)

View File

@ -134,9 +134,7 @@ def get_fixture_http_headers(integration_name: str,
function from the target integration module to determine what set function from the target integration module to determine what set
of HTTP headers goes with the given test fixture. of HTTP headers goes with the given test fixture.
""" """
view_module_name = "zerver.webhooks.{integration_name}.view".format( view_module_name = f"zerver.webhooks.{integration_name}.view"
integration_name=integration_name
)
try: try:
# TODO: We may want to migrate to a more explicit registration # TODO: We may want to migrate to a more explicit registration
# strategy for this behavior rather than a try/except import. # strategy for this behavior rather than a try/except import.

View File

@ -178,14 +178,12 @@ def get_pull_request_event_message(user_name: str, action: str, url: str, number
punctuation = ':' if message else '.' punctuation = ':' if message else '.'
if (assignees or assignee or (target_branch and base_branch) or (title is None)): if (assignees or assignee or (target_branch and base_branch) or (title is None)):
main_message = '{message}{punctuation}'.format( main_message = f'{main_message}{punctuation}'
message=main_message, punctuation=punctuation)
elif title is not None: elif title is not None:
# Once we get here, we know that the message ends with a title # Once we get here, we know that the message ends with a title
# which could already have punctuation at the end # which could already have punctuation at the end
if title[-1] not in string.punctuation: if title[-1] not in string.punctuation:
main_message = '{message}{punctuation}'.format( main_message = f'{main_message}{punctuation}'
message=main_message, punctuation=punctuation)
if message: if message:
main_message += '\n' + CONTENT_MESSAGE_TEMPLATE.format(message=message) main_message += '\n' + CONTENT_MESSAGE_TEMPLATE.format(message=message)

View File

@ -177,8 +177,7 @@ def curl_method_arguments(endpoint: str, method: str,
elif method in valid_methods: elif method in valid_methods:
return ["-sSX", method, url] return ["-sSX", method, url]
else: else:
msg = "The request method {} is not one of {}".format(method, msg = f"The request method {method} is not one of {valid_methods}"
valid_methods)
raise ValueError(msg) raise ValueError(msg)
def get_openapi_param_example_value_as_string(endpoint: str, method: str, param: Dict[str, Any], def get_openapi_param_example_value_as_string(endpoint: str, method: str, param: Dict[str, Any],

View File

@ -863,8 +863,7 @@ class SocialAuthBase(DesktopFlowTestingLib, ZulipTestCase):
self.assertEqual(data['redirect_to'], '/user_uploads/image') self.assertEqual(data['redirect_to'], '/user_uploads/image')
self.assertEqual(result.status_code, 302) self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result.url) parsed_url = urllib.parse.urlparse(result.url)
uri = "{}://{}{}".format(parsed_url.scheme, parsed_url.netloc, uri = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
parsed_url.path)
self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/')) self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/'))
@override_settings(SOCIAL_AUTH_SUBDOMAIN=None) @override_settings(SOCIAL_AUTH_SUBDOMAIN=None)
@ -881,8 +880,7 @@ class SocialAuthBase(DesktopFlowTestingLib, ZulipTestCase):
self.assertEqual(data['redirect_to'], '/user_uploads/image') self.assertEqual(data['redirect_to'], '/user_uploads/image')
self.assertEqual(result.status_code, 302) self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result.url) parsed_url = urllib.parse.urlparse(result.url)
uri = "{}://{}{}".format(parsed_url.scheme, parsed_url.netloc, uri = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
parsed_url.path)
self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/')) self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/'))
def test_social_auth_deactivated_user(self) -> None: def test_social_auth_deactivated_user(self) -> None:
@ -1043,8 +1041,7 @@ class SocialAuthBase(DesktopFlowTestingLib, ZulipTestCase):
self.assertEqual(data['subdomain'], 'zulip') self.assertEqual(data['subdomain'], 'zulip')
self.assertEqual(result.status_code, 302) self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result.url) parsed_url = urllib.parse.urlparse(result.url)
uri = "{}://{}{}".format(parsed_url.scheme, parsed_url.netloc, uri = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
parsed_url.path)
self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/')) self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/'))
hamlet = self.example_user("hamlet") hamlet = self.example_user("hamlet")
# Name wasn't changed at all # Name wasn't changed at all
@ -1063,8 +1060,7 @@ class SocialAuthBase(DesktopFlowTestingLib, ZulipTestCase):
self.assertEqual(data['subdomain'], 'zulip') self.assertEqual(data['subdomain'], 'zulip')
self.assertEqual(result.status_code, 302) self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result.url) parsed_url = urllib.parse.urlparse(result.url)
uri = "{}://{}{}".format(parsed_url.scheme, parsed_url.netloc, uri = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
parsed_url.path)
self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/')) self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/'))
result = self.client_get(result.url) result = self.client_get(result.url)
@ -1251,8 +1247,7 @@ class SocialAuthBase(DesktopFlowTestingLib, ZulipTestCase):
self.assertEqual(data['subdomain'], 'zulip') self.assertEqual(data['subdomain'], 'zulip')
self.assertEqual(result.status_code, 302) self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result.url) parsed_url = urllib.parse.urlparse(result.url)
uri = "{}://{}{}".format(parsed_url.scheme, parsed_url.netloc, uri = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
parsed_url.path)
self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/')) self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/'))
result = self.client_get(result.url) result = self.client_get(result.url)
@ -1276,8 +1271,7 @@ class SocialAuthBase(DesktopFlowTestingLib, ZulipTestCase):
self.assertEqual(data['subdomain'], 'zulip') self.assertEqual(data['subdomain'], 'zulip')
self.assertEqual(result.status_code, 302) self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result.url) parsed_url = urllib.parse.urlparse(result.url)
uri = "{}://{}{}".format(parsed_url.scheme, parsed_url.netloc, uri = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
parsed_url.path)
self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/')) self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/'))
result = self.client_get(result.url) result = self.client_get(result.url)
@ -1793,8 +1787,7 @@ class SAMLAuthBackendTest(SocialAuthBase):
self.assertEqual(data['subdomain'], 'zulip') self.assertEqual(data['subdomain'], 'zulip')
self.assertEqual(result.status_code, 302) self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result.url) parsed_url = urllib.parse.urlparse(result.url)
uri = "{}://{}{}".format(parsed_url.scheme, parsed_url.netloc, uri = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
parsed_url.path)
self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/')) self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/'))
self.client_get(uri) self.client_get(uri)
@ -1829,8 +1822,7 @@ class SAMLAuthBackendTest(SocialAuthBase):
self.assertEqual(data['subdomain'], 'zulip') self.assertEqual(data['subdomain'], 'zulip')
self.assertEqual(result.status_code, 302) self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result.url) parsed_url = urllib.parse.urlparse(result.url)
uri = "{}://{}{}".format(parsed_url.scheme, parsed_url.netloc, uri = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
parsed_url.path)
self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/')) self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/'))
self.client_get(uri) self.client_get(uri)
@ -1851,8 +1843,7 @@ class SAMLAuthBackendTest(SocialAuthBase):
self.assertEqual(data['subdomain'], 'zulip') self.assertEqual(data['subdomain'], 'zulip')
self.assertEqual(result.status_code, 302) self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result.url) parsed_url = urllib.parse.urlparse(result.url)
uri = "{}://{}{}".format(parsed_url.scheme, parsed_url.netloc, uri = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
parsed_url.path)
self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/')) self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/'))
self.client_get(uri) self.client_get(uri)
@ -2220,8 +2211,7 @@ class GitHubAuthBackendTest(SocialAuthBase):
self.assertEqual(data['redirect_to'], '/user_uploads/image') self.assertEqual(data['redirect_to'], '/user_uploads/image')
self.assertEqual(result.status_code, 302) self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result.url) parsed_url = urllib.parse.urlparse(result.url)
uri = "{}://{}{}".format(parsed_url.scheme, parsed_url.netloc, uri = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
parsed_url.path)
self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/')) self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/'))
def test_github_oauth2_success_single_email(self) -> None: def test_github_oauth2_success_single_email(self) -> None:
@ -2246,8 +2236,7 @@ class GitHubAuthBackendTest(SocialAuthBase):
self.assertEqual(data['redirect_to'], '/user_uploads/image') self.assertEqual(data['redirect_to'], '/user_uploads/image')
self.assertEqual(result.status_code, 302) self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result.url) parsed_url = urllib.parse.urlparse(result.url)
uri = "{}://{}{}".format(parsed_url.scheme, parsed_url.netloc, uri = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
parsed_url.path)
self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/')) self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/'))
def test_github_oauth2_login_only_one_account_exists(self) -> None: def test_github_oauth2_login_only_one_account_exists(self) -> None:
@ -2277,8 +2266,7 @@ class GitHubAuthBackendTest(SocialAuthBase):
self.assertEqual(data['redirect_to'], '/user_uploads/image') self.assertEqual(data['redirect_to'], '/user_uploads/image')
self.assertEqual(result.status_code, 302) self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result.url) parsed_url = urllib.parse.urlparse(result.url)
uri = "{}://{}{}".format(parsed_url.scheme, parsed_url.netloc, uri = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
parsed_url.path)
self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/')) self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/'))
def test_github_oauth2_login_multiple_accounts_exist(self) -> None: def test_github_oauth2_login_multiple_accounts_exist(self) -> None:
@ -2309,8 +2297,7 @@ class GitHubAuthBackendTest(SocialAuthBase):
self.assertEqual(data['redirect_to'], '/user_uploads/image') self.assertEqual(data['redirect_to'], '/user_uploads/image')
self.assertEqual(result.status_code, 302) self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result.url) parsed_url = urllib.parse.urlparse(result.url)
uri = "{}://{}{}".format(parsed_url.scheme, parsed_url.netloc, uri = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
parsed_url.path)
self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/')) self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/'))
def test_github_oauth2_login_no_account_exists(self) -> None: def test_github_oauth2_login_no_account_exists(self) -> None:
@ -2363,8 +2350,7 @@ class GitHubAuthBackendTest(SocialAuthBase):
self.assertEqual(data['redirect_to'], '/user_uploads/image') self.assertEqual(data['redirect_to'], '/user_uploads/image')
self.assertEqual(result.status_code, 302) self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result.url) parsed_url = urllib.parse.urlparse(result.url)
uri = "{}://{}{}".format(parsed_url.scheme, parsed_url.netloc, uri = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
parsed_url.path)
self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/')) self.assertTrue(uri.startswith('http://zulip.testserver/accounts/login/subdomain/'))
def test_github_oauth2_signup_choose_new_email_to_register(self) -> None: def test_github_oauth2_signup_choose_new_email_to_register(self) -> None:

View File

@ -1891,9 +1891,7 @@ class BugdownTest(ZulipTestCase):
msg = Message(sender=sender_user_profile, sending_client=get_client("test")) msg = Message(sender=sender_user_profile, sending_client=get_client("test"))
content = "#**привет**" content = "#**привет**"
quoted_name = '.D0.BF.D1.80.D0.B8.D0.B2.D0.B5.D1.82' quoted_name = '.D0.BF.D1.80.D0.B8.D0.B2.D0.B5.D1.82'
href = '/#narrow/stream/{stream_id}-{quoted_name}'.format( href = f'/#narrow/stream/{uni.id}-{quoted_name}'
stream_id=uni.id,
quoted_name=quoted_name)
self.assertEqual( self.assertEqual(
render_markdown(msg, content), render_markdown(msg, content),
'<p><a class="stream" data-stream-id="{s.id}" href="{href}">#{s.name}</a></p>'.format( '<p><a class="stream" data-stream-id="{s.id}" href="{href}">#{s.name}</a></p>'.format(

View File

@ -4299,8 +4299,7 @@ class MessageHasKeywordsTest(ZulipTestCase):
with mock.patch("zerver.lib.actions.do_claim_attachments", with mock.patch("zerver.lib.actions.do_claim_attachments",
wraps=do_claim_attachments) as m: wraps=do_claim_attachments) as m:
self.update_message(msg, '[link](http://{}/user_uploads/{})'.format( self.update_message(msg, f'[link](http://{hamlet.realm.host}/user_uploads/{dummy_path_ids[0]})')
hamlet.realm.host, dummy_path_ids[0]))
self.assertTrue(m.called) self.assertTrue(m.called)
m.reset_mock() m.reset_mock()
@ -4317,8 +4316,7 @@ class MessageHasKeywordsTest(ZulipTestCase):
self.assertFalse(m.called) self.assertFalse(m.called)
m.reset_mock() m.reset_mock()
self.update_message(msg, '[link](https://github.com/user_uploads/{})'.format( self.update_message(msg, f'[link](https://github.com/user_uploads/{dummy_path_ids[0]})')
dummy_path_ids[0]))
self.assertFalse(m.called) self.assertFalse(m.called)
m.reset_mock() m.reset_mock()

View File

@ -1550,10 +1550,7 @@ class LocalStorageTest(UploadSerializeMixin, ZulipTestCase):
result = re.search(re.compile(r"([A-Za-z0-9\-_]{24})"), uri) result = re.search(re.compile(r"([A-Za-z0-9\-_]{24})"), uri)
if result is not None: if result is not None:
random_name = result.group(1) random_name = result.group(1)
expected_url = "http://zulip.testserver/user_avatars/exports/{realm_id}/{random_name}/tarball.tar.gz".format( expected_url = f"http://zulip.testserver/user_avatars/exports/{user_profile.realm_id}/{random_name}/tarball.tar.gz"
realm_id=user_profile.realm_id,
random_name=random_name,
)
self.assertEqual(expected_url, uri) self.assertEqual(expected_url, uri)
# Delete the tarball. # Delete the tarball.
@ -1863,10 +1860,7 @@ class S3Test(ZulipTestCase):
result = re.search(re.compile(r"([0-9a-fA-F]{32})"), uri) result = re.search(re.compile(r"([0-9a-fA-F]{32})"), uri)
if result is not None: if result is not None:
hex_value = result.group(1) hex_value = result.group(1)
expected_url = "https://{bucket}.s3.amazonaws.com/exports/{hex_value}/{path}".format( expected_url = f"https://{bucket.name}.s3.amazonaws.com/exports/{hex_value}/{os.path.basename(tarball_path)}"
bucket=bucket.name,
hex_value=hex_value,
path=os.path.basename(tarball_path))
self.assertEqual(uri, expected_url) self.assertEqual(uri, expected_url)
# Delete the tarball. # Delete the tarball.

View File

@ -53,12 +53,10 @@ def get_fixtures(request: HttpResponse,
integration_name: str=REQ()) -> HttpResponse: integration_name: str=REQ()) -> HttpResponse:
valid_integration_name = get_valid_integration_name(integration_name) valid_integration_name = get_valid_integration_name(integration_name)
if not valid_integration_name: if not valid_integration_name:
return json_error("\"{integration_name}\" is not a valid webhook integration.".format( return json_error(f"\"{integration_name}\" is not a valid webhook integration.", status=404)
integration_name=integration_name), status=404)
fixtures = {} fixtures = {}
fixtures_dir = os.path.join(ZULIP_PATH, "zerver/webhooks/{valid_integration_name}/fixtures".format( fixtures_dir = os.path.join(ZULIP_PATH, f"zerver/webhooks/{valid_integration_name}/fixtures")
valid_integration_name=valid_integration_name))
if not os.path.exists(fixtures_dir): if not os.path.exists(fixtures_dir):
msg = ("The integration \"{valid_integration_name}\" does not have fixtures.").format( msg = ("The integration \"{valid_integration_name}\" does not have fixtures.").format(
valid_integration_name=valid_integration_name) valid_integration_name=valid_integration_name)
@ -114,11 +112,9 @@ def send_all_webhook_fixture_messages(request: HttpRequest,
integration_name: str=REQ()) -> HttpResponse: integration_name: str=REQ()) -> HttpResponse:
valid_integration_name = get_valid_integration_name(integration_name) valid_integration_name = get_valid_integration_name(integration_name)
if not valid_integration_name: if not valid_integration_name:
return json_error("\"{integration_name}\" is not a valid webhook integration.".format( return json_error(f"\"{integration_name}\" is not a valid webhook integration.", status=404)
integration_name=integration_name), status=404)
fixtures_dir = os.path.join(ZULIP_PATH, "zerver/webhooks/{valid_integration_name}/fixtures".format( fixtures_dir = os.path.join(ZULIP_PATH, f"zerver/webhooks/{valid_integration_name}/fixtures")
valid_integration_name=valid_integration_name))
if not os.path.exists(fixtures_dir): if not os.path.exists(fixtures_dir):
msg = ("The integration \"{valid_integration_name}\" does not have fixtures.").format( msg = ("The integration \"{valid_integration_name}\" does not have fixtures.").format(
valid_integration_name=valid_integration_name) valid_integration_name=valid_integration_name)

View File

@ -46,16 +46,10 @@ def api_alertmanager_webhook(request: HttpRequest, user_profile: UserProfile,
icon = ":squared_ok:" icon = ":squared_ok:"
if len(messages) == 1: if len(messages) == 1:
body = "{icon} **{title}** {message}".format( body = f"{icon} **{title}** {messages[0]}"
icon=icon,
title=title,
message=messages[0])
else: else:
message_list = "\n".join([f"* {m}" for m in messages]) message_list = "\n".join([f"* {m}" for m in messages])
body = "{icon} **{title}**\n{messages}".format( body = f"{icon} **{title}**\n{message_list}"
icon=icon,
title=title,
messages=message_list)
check_send_webhook_message(request, user_profile, topic, body) check_send_webhook_message(request, user_profile, topic, body)

View File

@ -47,17 +47,13 @@ class Bitbucket2HookTests(WebhookTestCase):
def test_bitbucket2_on_push_commits_above_limit_event(self) -> None: def test_bitbucket2_on_push_commits_above_limit_event(self) -> None:
commit_info = '* a ([6f161a7](https://bitbucket.org/kolaszek/repository-name/commits/6f161a7bced94430ac8947d87dbf45c6deee3fb0))\n' commit_info = '* a ([6f161a7](https://bitbucket.org/kolaszek/repository-name/commits/6f161a7bced94430ac8947d87dbf45c6deee3fb0))\n'
expected_message = "kolaszek [pushed](https://bitbucket.org/kolaszek/repository-name/branches/compare/6f161a7bced94430ac8947d87dbf45c6deee3fb0..1221f2fda6f1e3654b09f1f3a08390e4cb25bb48) 5 commits to branch master. Commits by Tomasz (5).\n\n{}[and more commit(s)]".format( expected_message = f"kolaszek [pushed](https://bitbucket.org/kolaszek/repository-name/branches/compare/6f161a7bced94430ac8947d87dbf45c6deee3fb0..1221f2fda6f1e3654b09f1f3a08390e4cb25bb48) 5 commits to branch master. Commits by Tomasz (5).\n\n{(commit_info * 5)}[and more commit(s)]"
(commit_info * 5),
)
self.send_and_test_stream_message('push_commits_above_limit', self.EXPECTED_TOPIC_BRANCH_EVENTS, expected_message) self.send_and_test_stream_message('push_commits_above_limit', self.EXPECTED_TOPIC_BRANCH_EVENTS, expected_message)
def test_bitbucket2_on_push_commits_above_limit_filtered_by_branches(self) -> None: def test_bitbucket2_on_push_commits_above_limit_filtered_by_branches(self) -> None:
self.url = self.build_webhook_url(branches='master,development') self.url = self.build_webhook_url(branches='master,development')
commit_info = '* a ([6f161a7](https://bitbucket.org/kolaszek/repository-name/commits/6f161a7bced94430ac8947d87dbf45c6deee3fb0))\n' commit_info = '* a ([6f161a7](https://bitbucket.org/kolaszek/repository-name/commits/6f161a7bced94430ac8947d87dbf45c6deee3fb0))\n'
expected_message = "kolaszek [pushed](https://bitbucket.org/kolaszek/repository-name/branches/compare/6f161a7bced94430ac8947d87dbf45c6deee3fb0..1221f2fda6f1e3654b09f1f3a08390e4cb25bb48) 5 commits to branch master. Commits by Tomasz (5).\n\n{}[and more commit(s)]".format( expected_message = f"kolaszek [pushed](https://bitbucket.org/kolaszek/repository-name/branches/compare/6f161a7bced94430ac8947d87dbf45c6deee3fb0..1221f2fda6f1e3654b09f1f3a08390e4cb25bb48) 5 commits to branch master. Commits by Tomasz (5).\n\n{(commit_info * 5)}[and more commit(s)]"
(commit_info * 5),
)
self.send_and_test_stream_message('push_commits_above_limit', self.EXPECTED_TOPIC_BRANCH_EVENTS, expected_message) self.send_and_test_stream_message('push_commits_above_limit', self.EXPECTED_TOPIC_BRANCH_EVENTS, expected_message)

View File

@ -150,10 +150,7 @@ def api_freshdesk_webhook(request: HttpRequest, user_profile: UserProfile,
ticket = TicketDict(ticket_data) ticket = TicketDict(ticket_data)
subject = "#{ticket_id}: {ticket_subject}".format( subject = f"#{ticket.id}: {ticket.subject}"
ticket_id=ticket.id,
ticket_subject=ticket.subject
)
event_info = parse_freshdesk_event(ticket.triggered_event) event_info = parse_freshdesk_event(ticket.triggered_event)
if event_info[1] == "created": if event_info[1] == "created":

View File

@ -78,17 +78,13 @@ class GithubWebhookTest(WebhookTestCase):
def test_push_50_commits(self) -> None: def test_push_50_commits(self) -> None:
commit_info = "* Update README.md ([0d1a26e](https://github.com/baxterthehacker/public-repo/commit/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c))\n" commit_info = "* Update README.md ([0d1a26e](https://github.com/baxterthehacker/public-repo/commit/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c))\n"
expected_message = "baxterthehacker [pushed](https://github.com/baxterthehacker/public-repo/compare/9049f1265b7d...0d1a26e67d8f) 50 commits to branch changes.\n\n{}[and 30 more commit(s)]".format( expected_message = f"baxterthehacker [pushed](https://github.com/baxterthehacker/public-repo/compare/9049f1265b7d...0d1a26e67d8f) 50 commits to branch changes.\n\n{commit_info * COMMITS_LIMIT}[and 30 more commit(s)]"
commit_info * COMMITS_LIMIT
)
self.send_and_test_stream_message('push__50_commits', self.EXPECTED_TOPIC_BRANCH_EVENTS, expected_message) self.send_and_test_stream_message('push__50_commits', self.EXPECTED_TOPIC_BRANCH_EVENTS, expected_message)
def test_push_50_commits_filtered_by_branches(self) -> None: def test_push_50_commits_filtered_by_branches(self) -> None:
self.url = self.build_webhook_url(branches='master,changes') self.url = self.build_webhook_url(branches='master,changes')
commit_info = "* Update README.md ([0d1a26e](https://github.com/baxterthehacker/public-repo/commit/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c))\n" commit_info = "* Update README.md ([0d1a26e](https://github.com/baxterthehacker/public-repo/commit/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c))\n"
expected_message = "baxterthehacker [pushed](https://github.com/baxterthehacker/public-repo/compare/9049f1265b7d...0d1a26e67d8f) 50 commits to branch changes.\n\n{}[and 30 more commit(s)]".format( expected_message = f"baxterthehacker [pushed](https://github.com/baxterthehacker/public-repo/compare/9049f1265b7d...0d1a26e67d8f) 50 commits to branch changes.\n\n{commit_info * COMMITS_LIMIT}[and 30 more commit(s)]"
commit_info * COMMITS_LIMIT
)
self.send_and_test_stream_message('push__50_commits', self.EXPECTED_TOPIC_BRANCH_EVENTS, expected_message) self.send_and_test_stream_message('push__50_commits', self.EXPECTED_TOPIC_BRANCH_EVENTS, expected_message)
def test_commit_comment_msg(self) -> None: def test_commit_comment_msg(self) -> None:

View File

@ -145,9 +145,7 @@ def get_fork_body(payload: Dict[str, Any]) -> str:
) )
def get_deployment_body(payload: Dict[str, Any]) -> str: def get_deployment_body(payload: Dict[str, Any]) -> str:
return '{} created new deployment.'.format( return f'{get_sender_name(payload)} created new deployment.'
get_sender_name(payload),
)
def get_change_deployment_status_body(payload: Dict[str, Any]) -> str: def get_change_deployment_status_body(payload: Dict[str, Any]) -> str:
return 'Deployment changed status to {}.'.format( return 'Deployment changed status to {}.'.format(

View File

@ -45,20 +45,14 @@ class GitlabHookTests(WebhookTestCase):
def test_push_commits_more_than_limit_event_message(self) -> None: def test_push_commits_more_than_limit_event_message(self) -> None:
expected_topic = "my-awesome-project / tomek" expected_topic = "my-awesome-project / tomek"
commits_info = '* b ([66abd2d](https://gitlab.com/tomaszkolek0/my-awesome-project/commit/66abd2da28809ffa128ed0447965cf11d7f863a7))\n' commits_info = '* b ([66abd2d](https://gitlab.com/tomaszkolek0/my-awesome-project/commit/66abd2da28809ffa128ed0447965cf11d7f863a7))\n'
expected_message = "Tomasz Kolek [pushed](https://gitlab.com/tomaszkolek0/my-awesome-project/compare/5fcdd5551fc3085df79bece2c32b1400802ac407...eb6ae1e591e0819dc5bf187c6bfe18ec065a80e9) 50 commits to branch tomek.\n\n{}[and {} more commit(s)]".format( expected_message = f"Tomasz Kolek [pushed](https://gitlab.com/tomaszkolek0/my-awesome-project/compare/5fcdd5551fc3085df79bece2c32b1400802ac407...eb6ae1e591e0819dc5bf187c6bfe18ec065a80e9) 50 commits to branch tomek.\n\n{commits_info * COMMITS_LIMIT}[and {50 - COMMITS_LIMIT} more commit(s)]"
commits_info * COMMITS_LIMIT,
50 - COMMITS_LIMIT,
)
self.send_and_test_stream_message('push_hook__push_commits_more_than_limit', expected_topic, expected_message) self.send_and_test_stream_message('push_hook__push_commits_more_than_limit', expected_topic, expected_message)
def test_push_commits_more_than_limit_message_filtered_by_branches(self) -> None: def test_push_commits_more_than_limit_message_filtered_by_branches(self) -> None:
self.url = self.build_webhook_url(branches='master,tomek') self.url = self.build_webhook_url(branches='master,tomek')
expected_topic = "my-awesome-project / tomek" expected_topic = "my-awesome-project / tomek"
commits_info = '* b ([66abd2d](https://gitlab.com/tomaszkolek0/my-awesome-project/commit/66abd2da28809ffa128ed0447965cf11d7f863a7))\n' commits_info = '* b ([66abd2d](https://gitlab.com/tomaszkolek0/my-awesome-project/commit/66abd2da28809ffa128ed0447965cf11d7f863a7))\n'
expected_message = "Tomasz Kolek [pushed](https://gitlab.com/tomaszkolek0/my-awesome-project/compare/5fcdd5551fc3085df79bece2c32b1400802ac407...eb6ae1e591e0819dc5bf187c6bfe18ec065a80e9) 50 commits to branch tomek.\n\n{}[and {} more commit(s)]".format( expected_message = f"Tomasz Kolek [pushed](https://gitlab.com/tomaszkolek0/my-awesome-project/compare/5fcdd5551fc3085df79bece2c32b1400802ac407...eb6ae1e591e0819dc5bf187c6bfe18ec065a80e9) 50 commits to branch tomek.\n\n{commits_info * COMMITS_LIMIT}[and {50 - COMMITS_LIMIT} more commit(s)]"
commits_info * COMMITS_LIMIT,
50 - COMMITS_LIMIT,
)
self.send_and_test_stream_message('push_hook__push_commits_more_than_limit', expected_topic, expected_message) self.send_and_test_stream_message('push_hook__push_commits_more_than_limit', expected_topic, expected_message)
def test_remove_branch_event_message(self) -> None: def test_remove_branch_event_message(self) -> None:

View File

@ -241,8 +241,7 @@ def get_build_hook_event_body(payload: Dict[str, Any]) -> str:
) )
def get_test_event_body(payload: Dict[str, Any]) -> str: def get_test_event_body(payload: Dict[str, Any]) -> str:
return "Webhook for **{repo}** has been configured successfully! :tada:".format( return f"Webhook for **{get_repo_name(payload)}** has been configured successfully! :tada:"
repo=get_repo_name(payload))
def get_pipeline_event_body(payload: Dict[str, Any]) -> str: def get_pipeline_event_body(payload: Dict[str, Any]) -> str:
pipeline_status = payload['object_attributes'].get('status') pipeline_status = payload['object_attributes'].get('status')
@ -269,11 +268,7 @@ def get_pipeline_event_body(payload: Dict[str, Any]) -> str:
if artifact_filename: if artifact_filename:
artifact_download_url = f'{build_url}/artifacts/download' artifact_download_url = f'{build_url}/artifacts/download'
artifact_browse_url = f'{build_url}/artifacts/browse' artifact_browse_url = f'{build_url}/artifacts/browse'
artifact_string = ' * built artifact: *{}* [[Browse]({})|[Download]({})]\n'.format( artifact_string = f' * built artifact: *{artifact_filename}* [[Browse]({artifact_browse_url})|[Download]({artifact_download_url})]\n'
artifact_filename,
artifact_browse_url,
artifact_download_url
)
else: else:
artifact_string = '' artifact_string = ''
builds_status += "* [{}]({}) - {}\n{}".format( builds_status += "* [{}]({}) - {}\n{}".format(

View File

@ -40,20 +40,14 @@ class GogsHookTests(WebhookTestCase):
def test_push_commits_more_than_limits(self) -> None: def test_push_commits_more_than_limits(self) -> None:
expected_topic = "try-git / master" expected_topic = "try-git / master"
commits_info = "* Webhook Test ([d8fce16](http://localhost:3000/john/try-git/commit/d8fce16c72a2ff56a5afc8a08645a6ce45491794))\n" commits_info = "* Webhook Test ([d8fce16](http://localhost:3000/john/try-git/commit/d8fce16c72a2ff56a5afc8a08645a6ce45491794))\n"
expected_message = "john [pushed](http://localhost:3000/john/try-git/compare/479e6b772b7fba19412457483f50b201286d0103...d8fce16c72a2ff56a5afc8a08645a6ce45491794) 30 commits to branch master. Commits by John (30).\n\n{}[and {} more commit(s)]".format( expected_message = f"john [pushed](http://localhost:3000/john/try-git/compare/479e6b772b7fba19412457483f50b201286d0103...d8fce16c72a2ff56a5afc8a08645a6ce45491794) 30 commits to branch master. Commits by John (30).\n\n{commits_info * COMMITS_LIMIT}[and {30 - COMMITS_LIMIT} more commit(s)]"
commits_info * COMMITS_LIMIT,
30 - COMMITS_LIMIT
)
self.send_and_test_stream_message('push__commits_more_than_limits', expected_topic, expected_message) self.send_and_test_stream_message('push__commits_more_than_limits', expected_topic, expected_message)
def test_push_commits_more_than_limits_filtered_by_branches(self) -> None: def test_push_commits_more_than_limits_filtered_by_branches(self) -> None:
self.url = self.build_webhook_url(branches='master,development') self.url = self.build_webhook_url(branches='master,development')
expected_topic = "try-git / master" expected_topic = "try-git / master"
commits_info = "* Webhook Test ([d8fce16](http://localhost:3000/john/try-git/commit/d8fce16c72a2ff56a5afc8a08645a6ce45491794))\n" commits_info = "* Webhook Test ([d8fce16](http://localhost:3000/john/try-git/commit/d8fce16c72a2ff56a5afc8a08645a6ce45491794))\n"
expected_message = "john [pushed](http://localhost:3000/john/try-git/compare/479e6b772b7fba19412457483f50b201286d0103...d8fce16c72a2ff56a5afc8a08645a6ce45491794) 30 commits to branch master. Commits by John (30).\n\n{}[and {} more commit(s)]".format( expected_message = f"john [pushed](http://localhost:3000/john/try-git/compare/479e6b772b7fba19412457483f50b201286d0103...d8fce16c72a2ff56a5afc8a08645a6ce45491794) 30 commits to branch master. Commits by John (30).\n\n{commits_info * COMMITS_LIMIT}[and {30 - COMMITS_LIMIT} more commit(s)]"
commits_info * COMMITS_LIMIT,
30 - COMMITS_LIMIT
)
self.send_and_test_stream_message('push__commits_more_than_limits', expected_topic, expected_message) self.send_and_test_stream_message('push__commits_more_than_limits', expected_topic, expected_message)
def test_new_branch(self) -> None: def test_new_branch(self) -> None:

View File

@ -43,11 +43,7 @@ def handle_push_image_event(payload: Dict[str, Any],
image_name = payload["event_data"]["repository"]["repo_full_name"] image_name = payload["event_data"]["repository"]["repo_full_name"]
image_tag = payload["event_data"]["resources"][0]["tag"] image_tag = payload["event_data"]["resources"][0]["tag"]
return "{author} pushed image `{image_name}:{image_tag}`".format( return f"{operator_username} pushed image `{image_name}:{image_tag}`"
author=operator_username,
image_name=image_name,
image_tag=image_tag
)
VULNERABILITY_SEVERITY_NAME_MAP = { VULNERABILITY_SEVERITY_NAME_MAP = {

View File

@ -55,8 +55,7 @@ def make_user_stats_chunk(error_dict: Dict[str, Any]) -> str:
total_occurrences = error_dict['totalOccurrences'] total_occurrences = error_dict['totalOccurrences']
# One line is subjectively better than two lines for this. # One line is subjectively better than two lines for this.
return "* {} users affected with {} total occurrences\n".format( return f"* {users_affected} users affected with {total_occurrences} total occurrences\n"
users_affected, total_occurrences)
def make_time_chunk(error_dict: Dict[str, Any]) -> str: def make_time_chunk(error_dict: Dict[str, Any]) -> str:
@ -76,8 +75,7 @@ def make_time_chunk(error_dict: Dict[str, Any]) -> str:
time_last = parse_time(error_dict['lastOccurredOn']) time_last = parse_time(error_dict['lastOccurredOn'])
# Provide time information about this error, # Provide time information about this error,
return "* **First occurred**: {}\n* **Last occurred**: {}\n".format( return f"* **First occurred**: {time_first}\n* **Last occurred**: {time_last}\n"
time_first, time_last)
def make_message_chunk(message: str) -> str: def make_message_chunk(message: str) -> str:
@ -185,8 +183,7 @@ def notification_message_error_occurred(payload: Dict[str, Any]) -> str:
if affected_user is not None: if affected_user is not None:
user_uuid = affected_user['UUID'] user_uuid = affected_user['UUID']
message += "* **Affected user**: {}...{}\n".format( message += f"* **Affected user**: {user_uuid[:6]}...{user_uuid[-5:]}\n"
user_uuid[:6], user_uuid[-5:])
if custom_data is not None: if custom_data is not None:
# We don't know what the keys and values beforehand, so we are forced # We don't know what the keys and values beforehand, so we are forced
@ -241,16 +238,13 @@ def activity_message(payload: Dict[str, Any]) -> str:
user = payload['error']['user'] user = payload['error']['user']
if event_type == "StatusChanged": if event_type == "StatusChanged":
error_status = payload['error']['status'] error_status = payload['error']['status']
message += "{} status changed to **{}** by {}:\n".format( message += f"{error_link_md} status changed to **{error_status}** by {user}:\n"
error_link_md, error_status, user)
elif event_type == "CommentAdded": elif event_type == "CommentAdded":
comment = payload['error']['comment'] comment = payload['error']['comment']
message += "{} commented on {}:\n\n``` quote\n{}\n```\n".format( message += f"{user} commented on {error_link_md}:\n\n``` quote\n{comment}\n```\n"
user, error_link_md, comment)
elif event_type == "AssignedToUser": elif event_type == "AssignedToUser":
assigned_to = payload['error']['assignedTo'] assigned_to = payload['error']['assignedTo']
message += "{} assigned {} to {}:\n".format( message += f"{user} assigned {error_link_md} to {assigned_to}:\n"
user, error_link_md, assigned_to)
message += "* **Timestamp**: {}\n".format( message += "* **Timestamp**: {}\n".format(
parse_time(payload['error']['activityDate'])) parse_time(payload['error']['activityDate']))

View File

@ -147,8 +147,7 @@ def semaphore_classic(payload: Dict[str, Any]) -> Tuple[str, str, str]:
) )
else: # should never get here else: # should never get here
content = "{event}: {result}".format( content = f"{event}: {result}"
event=event, result=result)
return content, project_name, branch_name return content, project_name, branch_name
@ -163,8 +162,7 @@ def semaphore_2(payload: Dict[str, Any]) -> Tuple[str, str, Optional[str]]:
author_url=GITHUB_URL_TEMPLATES['user'].format(repo_url=repo_url, username=author_name), author_url=GITHUB_URL_TEMPLATES['user'].format(repo_url=repo_url, username=author_name),
pipeline_name=payload["pipeline"]["name"], pipeline_name=payload["pipeline"]["name"],
pipeline_result=payload["pipeline"]["result"], pipeline_result=payload["pipeline"]["result"],
workflow_url='https://{org}.semaphoreci.com/workflows/{id}'.format( workflow_url=f'https://{organization_name}.semaphoreci.com/workflows/{workflow_id}'
org=organization_name, id=workflow_id)
) )
if payload["revision"]["reference_type"] == "branch": # push event if payload["revision"]["reference_type"] == "branch": # push event

View File

@ -76,11 +76,9 @@ def api_teamcity_webhook(request: HttpRequest, user_profile: UserProfile,
status = 'was successful! :thumbs_up:' status = 'was successful! :thumbs_up:'
elif build_result == 'failure': elif build_result == 'failure':
if build_result_delta == 'broken': if build_result_delta == 'broken':
status = 'is broken with status {status}! :thumbs_down:'.format( status = f'is broken with status {build_status}! :thumbs_down:'
status=build_status)
else: else:
status = 'is still broken with status {status}! :thumbs_down:'.format( status = f'is still broken with status {build_status}! :thumbs_down:'
status=build_status)
elif build_result == 'running': elif build_result == 'running':
status = 'has started.' status = 'has started.'

View File

@ -1198,10 +1198,7 @@ def social_associate_user_helper(backend: BaseAuth, return_data: Dict[str, Any],
# In SAML authentication, the IdP may support only sending # In SAML authentication, the IdP may support only sending
# the first and last name as separate attributes - in that case # the first and last name as separate attributes - in that case
# we construct the full name from them. # we construct the full name from them.
return_data["full_name"] = "{} {}".format( return_data["full_name"] = f"{first_name} {last_name}".strip() # strip removes the unnecessary ' '
first_name,
last_name
).strip() # strip removes the unnecessary ' '
return user_profile return user_profile