python: Consistently use from…import for urllib.parse.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg 2023-12-05 12:14:17 -08:00 committed by Tim Abbott
parent e5d71fe5ac
commit 3853fa875a
27 changed files with 154 additions and 210 deletions

View File

@ -1,9 +1,8 @@
import urllib
from contextlib import suppress
from datetime import timedelta
from decimal import Decimal
from typing import Any, Dict, Iterable, List, Optional, Union
from urllib.parse import urlencode
from urllib.parse import urlencode, urlparse
from django.conf import settings
from django.core.exceptions import ValidationError
@ -273,7 +272,7 @@ def support(
for key_word in key_words:
try:
URLValidator()(key_word)
parse_result = urllib.parse.urlparse(key_word)
parse_result = urlparse(key_word)
hostname = parse_result.hostname
assert hostname is not None
if parse_result.port:

View File

@ -5,12 +5,12 @@ import http.client
import json
import logging
import time
import urllib.parse
from urllib.parse import urlencode
def fetch_metric(metric_id: str, query: str) -> float:
logging.info("Fetching %s", metric_id)
params = urllib.parse.urlencode({"query": query})
params = urlencode({"query": query})
conn = http.client.HTTPConnection("localhost:9090")
conn.request("GET", "/api/v1/query?" + params)
response = conn.getresponse()

View File

@ -1,6 +1,5 @@
import base64
import logging
import urllib
from datetime import datetime
from functools import wraps
from io import BytesIO
@ -16,6 +15,7 @@ from typing import (
cast,
overload,
)
from urllib.parse import urlparse
import django_otp
from django.conf import settings
@ -393,8 +393,8 @@ def zulip_redirect_to_login(
resolved_login_url = resolve_url(login_url or settings.LOGIN_URL)
# If the login URL is the same scheme and net location then just
# use the path as the "next" url.
login_scheme, login_netloc = urllib.parse.urlparse(resolved_login_url)[:2]
current_scheme, current_netloc = urllib.parse.urlparse(path)[:2]
login_scheme, login_netloc = urlparse(resolved_login_url)[:2]
current_scheme, current_netloc = urlparse(path)[:2]
if (not login_scheme or login_scheme == current_scheme) and (
not login_netloc or login_netloc == current_netloc
):

View File

@ -1,5 +1,5 @@
import urllib
from typing import Any, Dict, Optional
from urllib.parse import urljoin
from django.conf import settings
from django.contrib.staticfiles.storage import staticfiles_storage
@ -135,7 +135,7 @@ def absolute_avatar_url(user_profile: UserProfile) -> str:
avatar = avatar_url(user_profile)
# avatar_url can return None if client_gravatar=True, however here we use the default value of False
assert avatar is not None
return urllib.parse.urljoin(user_profile.realm.uri, avatar)
return urljoin(user_profile.realm.uri, avatar)
def is_avatar_new(ldap_avatar: bytes, user_profile: UserProfile) -> bool:

View File

@ -6,8 +6,6 @@ import logging
import mimetypes
import re
import time
import urllib
import urllib.parse
from collections import deque
from dataclasses import dataclass
from datetime import datetime, timezone
@ -28,7 +26,7 @@ from typing import (
Union,
cast,
)
from urllib.parse import parse_qs, urlencode, urljoin, urlsplit
from urllib.parse import parse_qs, quote, urlencode, urljoin, urlparse, urlsplit, urlunparse
from xml.etree.ElementTree import Element, SubElement
import ahocorasick
@ -488,7 +486,7 @@ def fetch_open_graph_image(url: str) -> Optional[Dict[str, Any]]:
def get_tweet_id(url: str) -> Optional[str]:
parsed_url = urllib.parse.urlparse(url)
parsed_url = urlparse(url)
if not (parsed_url.netloc == "twitter.com" or parsed_url.netloc.endswith(".twitter.com")):
return None
to_match = parsed_url.path
@ -717,13 +715,13 @@ class InlineInterestingLinkProcessor(markdown.treeprocessors.Treeprocessor):
def get_actual_image_url(self, url: str) -> str:
# Add specific per-site cases to convert image-preview URLs to image URLs.
# See https://github.com/zulip/zulip/issues/4658 for more information
parsed_url = urllib.parse.urlparse(url)
parsed_url = urlparse(url)
if parsed_url.netloc == "github.com" or parsed_url.netloc.endswith(".github.com"):
# https://github.com/zulip/zulip/blob/main/static/images/logo/zulip-icon-128x128.png ->
# https://raw.githubusercontent.com/zulip/zulip/main/static/images/logo/zulip-icon-128x128.png
split_path = parsed_url.path.split("/")
if len(split_path) > 3 and split_path[3] == "blob":
return urllib.parse.urljoin(
return urljoin(
"https://raw.githubusercontent.com", "/".join(split_path[0:3] + split_path[4:])
)
@ -732,7 +730,7 @@ class InlineInterestingLinkProcessor(markdown.treeprocessors.Treeprocessor):
def is_image(self, url: str) -> bool:
if not self.zmd.image_preview_enabled:
return False
parsed_url = urllib.parse.urlparse(url)
parsed_url = urlparse(url)
# remove HTML URLs which end with image extensions that cannot be shorted
if parsed_url.netloc == "pasteboard.co":
return False
@ -744,7 +742,7 @@ class InlineInterestingLinkProcessor(markdown.treeprocessors.Treeprocessor):
# wikipedia.org to point to the actual image URL. It's
# structurally very similar to dropbox_image, and possibly
# should be rewritten to use open graph, but has some value.
parsed_url = urllib.parse.urlparse(url)
parsed_url = urlparse(url)
if parsed_url.netloc.lower().endswith(".wikipedia.org") and parsed_url.path.startswith(
"/wiki/File:"
):
@ -759,7 +757,7 @@ class InlineInterestingLinkProcessor(markdown.treeprocessors.Treeprocessor):
def dropbox_image(self, url: str) -> Optional[Dict[str, Any]]:
# TODO: The returned Dict could possibly be a TypedDict in future.
parsed_url = urllib.parse.urlparse(url)
parsed_url = urlparse(url)
if parsed_url.netloc == "dropbox.com" or parsed_url.netloc.endswith(".dropbox.com"):
is_album = parsed_url.path.startswith("/sc/") or parsed_url.path.startswith("/photos/")
# Only allow preview Dropbox shared links
@ -911,7 +909,7 @@ class InlineInterestingLinkProcessor(markdown.treeprocessors.Treeprocessor):
"type": "mention",
"start": match.start(),
"end": match.end(),
"url": "https://twitter.com/" + urllib.parse.quote(screen_name),
"url": "https://twitter.com/" + quote(screen_name),
"text": mention_string,
}
for match in re.finditer(re.escape(mention_string), text, re.IGNORECASE)
@ -1260,7 +1258,7 @@ class InlineInterestingLinkProcessor(markdown.treeprocessors.Treeprocessor):
# `/user_uploads` and beginning with `user_uploads`.
# This urllib construction converts the latter into
# the former.
parsed_url = urllib.parse.urlsplit(urllib.parse.urljoin("/", url))
parsed_url = urlsplit(urljoin("/", url))
host = parsed_url.netloc
if host != "" and (
@ -1568,7 +1566,7 @@ def sanitize_url(url: str) -> Optional[str]:
See the docstring on markdown.inlinepatterns.LinkPattern.sanitize_url.
"""
try:
parts = urllib.parse.urlparse(url.replace(" ", "%20"))
parts = urlparse(url.replace(" ", "%20"))
scheme, netloc, path, params, query, fragment = parts
except ValueError:
# Bad URL - so bad it couldn't be parsed.
@ -1580,10 +1578,10 @@ def sanitize_url(url: str) -> Optional[str]:
scheme = "mailto"
elif scheme == "" and netloc == "" and len(path) > 0 and path[0] == "/":
# Allow domain-relative links
return urllib.parse.urlunparse(("", "", path, params, query, fragment))
return urlunparse(("", "", path, params, query, fragment))
elif (scheme, netloc, path, params, query) == ("", "", "", "", "") and len(fragment) > 0:
# Allow fragment links
return urllib.parse.urlunparse(("", "", "", "", "", fragment))
return urlunparse(("", "", "", "", "", fragment))
# Zulip modification: If scheme is not specified, assume http://
# We re-enter sanitize_url because netloc etc. need to be re-parsed.
@ -1608,7 +1606,7 @@ def sanitize_url(url: str) -> Optional[str]:
# the colon check, which would also forbid a lot of legitimate URLs.
# URL passes all tests. Return URL as-is.
return urllib.parse.urlunparse((scheme, netloc, path, params, query, fragment))
return urlunparse((scheme, netloc, path, params, query, fragment))
def url_to_a(

View File

@ -1,6 +1,6 @@
import logging
import urllib
from typing import Any, Dict, List, Mapping, Optional, Tuple, Union
from urllib.parse import urljoin
import orjson
import requests
@ -88,9 +88,7 @@ def send_to_push_bouncer(
assert settings.PUSH_NOTIFICATION_BOUNCER_URL is not None
assert settings.ZULIP_ORG_ID is not None
assert settings.ZULIP_ORG_KEY is not None
url = urllib.parse.urljoin(
settings.PUSH_NOTIFICATION_BOUNCER_URL, "/api/v1/remotes/" + endpoint
)
url = urljoin(settings.PUSH_NOTIFICATION_BOUNCER_URL, "/api/v1/remotes/" + endpoint)
api_auth = requests.auth.HTTPBasicAuth(settings.ZULIP_ORG_ID, settings.ZULIP_ORG_KEY)
headers = {"User-agent": f"ZulipServer/{ZULIP_VERSION}"}

View File

@ -1,6 +1,6 @@
import re
import urllib
from typing import Optional
from urllib.parse import urlsplit
from django.conf import settings
from django.http import HttpRequest
@ -57,8 +57,8 @@ def is_root_domain_available() -> bool:
def is_static_or_current_realm_url(url: str, realm: Optional[Realm]) -> bool:
assert settings.STATIC_URL is not None
split_url = urllib.parse.urlsplit(url)
split_static_url = urllib.parse.urlsplit(settings.STATIC_URL)
split_url = urlsplit(url)
split_static_url = urlsplit(settings.STATIC_URL)
# The netloc check here is important to correctness if STATIC_URL
# does not contain a `/`; see the tests for why.

View File

@ -4,7 +4,6 @@ import re
import shutil
import subprocess
import tempfile
import urllib
from contextlib import contextmanager
from datetime import timedelta
from typing import (
@ -25,6 +24,7 @@ from typing import (
cast,
)
from unittest import TestResult, mock, skipUnless
from urllib.parse import parse_qs, quote, urlencode
import lxml.html
import orjson
@ -278,7 +278,7 @@ Output:
url_split = url.split("?")
data = {}
if len(url_split) == 2:
data = urllib.parse.parse_qs(url_split[1])
data = parse_qs(url_split[1])
url = url_split[0]
url = url.replace("/json/", "/").replace("/api/v1/", "/")
return (url, data)
@ -342,7 +342,7 @@ Output:
"""
We need to urlencode, since Django's function won't do it for us.
"""
encoded = urllib.parse.urlencode(info)
encoded = urlencode(info)
extra["content_type"] = "application/x-www-form-urlencoded"
django_client = self.client # see WRAPPER_COMMENT
self.set_http_headers(extra, skip_user_agent)
@ -434,7 +434,7 @@ Output:
headers: Optional[Mapping[str, Any]] = None,
**extra: str,
) -> "TestHttpResponse":
encoded = urllib.parse.urlencode(info)
encoded = urlencode(info)
extra["content_type"] = "application/x-www-form-urlencoded"
django_client = self.client # see WRAPPER_COMMENT
self.set_http_headers(extra, skip_user_agent)
@ -477,7 +477,7 @@ Output:
intentionally_undocumented: bool = False,
**extra: str,
) -> "TestHttpResponse":
encoded = urllib.parse.urlencode(info)
encoded = urlencode(info)
extra["content_type"] = "application/x-www-form-urlencoded"
django_client = self.client # see WRAPPER_COMMENT
self.set_http_headers(extra, skip_user_agent)
@ -807,9 +807,7 @@ Output:
def register(self, email: str, password: str, subdomain: str = DEFAULT_SUBDOMAIN) -> None:
response = self.client_post("/accounts/home/", {"email": email}, subdomain=subdomain)
self.assertEqual(response.status_code, 302)
self.assertEqual(
response["Location"], f"/accounts/send_confirm/?email={urllib.parse.quote(email)}"
)
self.assertEqual(response["Location"], f"/accounts/send_confirm/?email={quote(email)}")
response = self.submit_reg_form_for_user(email, password, subdomain=subdomain)
self.assertEqual(response.status_code, 302)
self.assertEqual(response["Location"], f"http://{Realm.host_for_subdomain(subdomain)}/")
@ -2408,7 +2406,7 @@ class BouncerTestCase(ZulipTestCase):
kwargs = dict(content_type="application/json")
else:
assert isinstance(request.body, str) or request.body is None
params: Dict[str, List[str]] = urllib.parse.parse_qs(request.body)
params: Dict[str, List[str]] = parse_qs(request.body)
# In Python 3, the values of the dict from `parse_qs` are
# in a list, because there might be multiple values.
# But since we are sending values with no same keys, hence

View File

@ -1,10 +1,9 @@
import io
import logging
import urllib
from datetime import datetime
from mimetypes import guess_type
from typing import IO, Any, BinaryIO, Callable, Iterator, List, Optional, Tuple, Union
from urllib.parse import urljoin
from urllib.parse import unquote, urljoin
from django.conf import settings
from django.core.files.uploadedfile import UploadedFile
@ -47,7 +46,7 @@ def get_file_info(user_file: UploadedFile) -> Tuple[str, str]:
# different content-type from the filename.
content_type = "application/octet-stream"
uploaded_file_name = urllib.parse.unquote(uploaded_file_name)
uploaded_file_name = unquote(uploaded_file_name)
return uploaded_file_name, content_type

View File

@ -1,10 +1,10 @@
import logging
import os
import secrets
import urllib
from datetime import datetime
from mimetypes import guess_type
from typing import IO, Any, BinaryIO, Callable, Iterator, List, Literal, Optional, Tuple
from urllib.parse import urljoin, urlsplit, urlunsplit
import boto3
import botocore
@ -188,10 +188,10 @@ class S3UploadBackend(ZulipUploadBackend):
},
ExpiresIn=0,
)
split_url = urllib.parse.urlsplit(foo_url)
split_url = urlsplit(foo_url)
assert split_url.path.endswith(f"/{DUMMY_KEY}")
return urllib.parse.urlunsplit(
return urlunsplit(
(split_url.scheme, split_url.netloc, split_url.path[: -len(DUMMY_KEY)], "", "")
)
@ -204,7 +204,7 @@ class S3UploadBackend(ZulipUploadBackend):
key: str,
) -> str:
assert not key.startswith("/")
return urllib.parse.urljoin(self.public_upload_url_base, key)
return urljoin(self.public_upload_url_base, key)
@override
def generate_message_upload_path(self, realm_id: str, uploaded_file_name: str) -> str:

View File

@ -5,7 +5,6 @@ import os
import re
import secrets
import time
import urllib
from abc import ABC, abstractmethod
from contextlib import contextmanager
from datetime import timedelta
@ -25,7 +24,7 @@ from typing import (
Type,
)
from unittest import mock
from urllib.parse import urlencode
from urllib.parse import parse_qs, urlencode, urlparse
import jwt
import ldap
@ -978,8 +977,8 @@ class SocialAuthBase(DesktopFlowTestingLib, ZulipTestCase, ABC):
headers: Any,
**extra_data: Any,
) -> "TestHttpResponse":
parsed_url = urllib.parse.urlparse(result["Location"])
csrf_state = urllib.parse.parse_qs(parsed_url.query)["state"]
parsed_url = urlparse(result["Location"])
csrf_state = parse_qs(parsed_url.query)["state"]
result = self.client_get(self.AUTH_FINISH_URL, dict(state=csrf_state), **headers)
return result
@ -1158,7 +1157,7 @@ class SocialAuthBase(DesktopFlowTestingLib, ZulipTestCase, ABC):
self.assertEqual(data["subdomain"], "zulip")
self.assertEqual(data["redirect_to"], "/user_uploads/image")
self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result["Location"])
parsed_url = urlparse(result["Location"])
url = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
self.assertTrue(url.startswith("http://zulip.testserver/accounts/login/subdomain/"))
@ -1182,7 +1181,7 @@ class SocialAuthBase(DesktopFlowTestingLib, ZulipTestCase, ABC):
self.assertEqual(data["subdomain"], "zulip")
self.assertEqual(data["redirect_to"], "/user_uploads/image")
self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result["Location"])
parsed_url = urlparse(result["Location"])
url = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
self.assertTrue(url.startswith("http://zulip.testserver/accounts/login/subdomain/"))
@ -1308,8 +1307,8 @@ class SocialAuthBase(DesktopFlowTestingLib, ZulipTestCase, ABC):
)
self.assertEqual(result.status_code, 302)
redirect_url = result["Location"]
parsed_url = urllib.parse.urlparse(redirect_url)
query_params = urllib.parse.parse_qs(parsed_url.query)
parsed_url = urlparse(redirect_url)
query_params = parse_qs(parsed_url.query)
self.assertEqual(parsed_url.scheme, "zulip")
self.assertEqual(query_params["realm"], ["http://zulip.testserver"])
self.assertEqual(query_params["email"], [hamlet.delivery_email])
@ -1404,7 +1403,7 @@ class SocialAuthBase(DesktopFlowTestingLib, ZulipTestCase, ABC):
self.assertEqual(data["full_name"], self.example_user("hamlet").full_name)
self.assertEqual(data["subdomain"], "zulip")
self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result["Location"])
parsed_url = urlparse(result["Location"])
url = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
self.assertTrue(url.startswith("http://zulip.testserver/accounts/login/subdomain/"))
hamlet = self.example_user("hamlet")
@ -1430,7 +1429,7 @@ class SocialAuthBase(DesktopFlowTestingLib, ZulipTestCase, ABC):
self.assertEqual(data["full_name"], name)
self.assertEqual(data["subdomain"], "zulip")
self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result["Location"])
parsed_url = urlparse(result["Location"])
url = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
self.assertTrue(url.startswith("http://zulip.testserver/accounts/login/subdomain/"))
@ -1473,8 +1472,8 @@ class SocialAuthBase(DesktopFlowTestingLib, ZulipTestCase, ABC):
if mobile_flow_otp:
self.assertEqual(result.status_code, 302)
redirect_url = result["Location"]
parsed_url = urllib.parse.urlparse(redirect_url)
query_params = urllib.parse.parse_qs(parsed_url.query)
parsed_url = urlparse(redirect_url)
query_params = parse_qs(parsed_url.query)
self.assertEqual(parsed_url.scheme, "zulip")
self.assertEqual(query_params["realm"], ["http://zulip.testserver"])
self.assertEqual(query_params["email"], [email])
@ -1716,7 +1715,7 @@ class SocialAuthBase(DesktopFlowTestingLib, ZulipTestCase, ABC):
self.assertEqual(data["full_name"], name)
self.assertEqual(data["subdomain"], "zulip")
self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result["Location"])
parsed_url = urlparse(result["Location"])
url = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
self.assertTrue(url.startswith("http://zulip.testserver/accounts/login/subdomain/"))
@ -1740,7 +1739,7 @@ class SocialAuthBase(DesktopFlowTestingLib, ZulipTestCase, ABC):
self.assertEqual(data["full_name"], name)
self.assertEqual(data["subdomain"], "zulip")
self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result["Location"])
parsed_url = urlparse(result["Location"])
url = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
self.assertTrue(url.startswith("http://zulip.testserver/accounts/login/subdomain/"))
@ -1996,8 +1995,8 @@ class SAMLAuthBackendTest(SocialAuthBase):
assert "samlrequest" in result["Location"].lower()
self.client.cookies = result.cookies
parsed_url = urllib.parse.urlparse(result["Location"])
relay_state = urllib.parse.parse_qs(parsed_url.query)["RelayState"][0]
parsed_url = urlparse(result["Location"])
relay_state = parse_qs(parsed_url.query)["RelayState"][0]
# Make sure params are getting encoded into RelayState:
data = SAMLAuthBackend.get_data_from_redis(orjson.loads(relay_state)["state_token"])
assert data is not None
@ -2149,7 +2148,7 @@ class SAMLAuthBackendTest(SocialAuthBase):
# Verify the redirect has the correct form - a LogoutRequest for hamlet
# is delivered to the IdP in the SAMLRequest param.
query_dict = urllib.parse.parse_qs(urllib.parse.urlparse(result["Location"]).query)
query_dict = parse_qs(urlparse(result["Location"]).query)
saml_request_encoded = query_dict["SAMLRequest"][0]
saml_request = OneLogin_Saml2_Utils.decode_base64_and_inflate(saml_request_encoded).decode()
self.assertIn("<samlp:LogoutRequest", saml_request)
@ -2331,8 +2330,8 @@ class SAMLAuthBackendTest(SocialAuthBase):
redirect_to = result["Location"]
self.assertIn(settings.SOCIAL_AUTH_SAML_ENABLED_IDPS["test_idp"]["slo_url"], redirect_to)
parsed = urllib.parse.urlparse(redirect_to)
query_dict = urllib.parse.parse_qs(parsed.query)
parsed = urlparse(redirect_to)
query_dict = parse_qs(parsed.query)
self.assertIn("SAMLResponse", query_dict)
# Do some very basic parsing of the SAMLResponse to verify it's a success response.
@ -3015,7 +3014,7 @@ class SAMLAuthBackendTest(SocialAuthBase):
self.assertEqual(data["full_name"], self.name)
self.assertEqual(data["subdomain"], "zulip")
self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result["Location"])
parsed_url = urlparse(result["Location"])
url = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
self.assertTrue(url.startswith("http://zulip.testserver/accounts/login/subdomain/"))
@ -3050,7 +3049,7 @@ class SAMLAuthBackendTest(SocialAuthBase):
self.assertEqual(data["full_name"], self.name)
self.assertEqual(data["subdomain"], "zulip")
self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result["Location"])
parsed_url = urlparse(result["Location"])
url = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
self.assertTrue(url.startswith("http://zulip.testserver/accounts/login/subdomain/"))
@ -3071,7 +3070,7 @@ class SAMLAuthBackendTest(SocialAuthBase):
self.assertEqual(data["full_name"], self.name)
self.assertEqual(data["subdomain"], "zulip")
self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result["Location"])
parsed_url = urlparse(result["Location"])
url = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
self.assertTrue(url.startswith("http://zulip.testserver/accounts/login/subdomain/"))
@ -3345,8 +3344,8 @@ class AppleIdAuthBackendTest(AppleAuthMixin, SocialAuthBase):
headers: Any,
**extra_data: Any,
) -> "TestHttpResponse":
parsed_url = urllib.parse.urlparse(result["Location"])
state = urllib.parse.parse_qs(parsed_url.query)["state"]
parsed_url = urlparse(result["Location"])
state = parse_qs(parsed_url.query)["state"]
user_param = json.dumps(account_data_dict)
self.client.session.flush()
result = self.client_post(
@ -3924,8 +3923,8 @@ class GitHubAuthBackendTest(SocialAuthBase):
expect_noreply_email_allowed: bool = False,
**extra_data: Any,
) -> "TestHttpResponse":
parsed_url = urllib.parse.urlparse(result["Location"])
csrf_state = urllib.parse.parse_qs(parsed_url.query)["state"]
parsed_url = urlparse(result["Location"])
csrf_state = parse_qs(parsed_url.query)["state"]
result = self.client_get(self.AUTH_FINISH_URL, dict(state=csrf_state), **headers)
if expect_choose_email_screen:
@ -4121,7 +4120,7 @@ class GitHubAuthBackendTest(SocialAuthBase):
self.assertEqual(data["subdomain"], "zulip")
self.assertEqual(data["redirect_to"], "/user_uploads/image")
self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result["Location"])
parsed_url = urlparse(result["Location"])
url = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
self.assertTrue(url.startswith("http://zulip.testserver/accounts/login/subdomain/"))
@ -4146,7 +4145,7 @@ class GitHubAuthBackendTest(SocialAuthBase):
self.assertEqual(data["subdomain"], "zulip")
self.assertEqual(data["redirect_to"], "/user_uploads/image")
self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result["Location"])
parsed_url = urlparse(result["Location"])
url = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
self.assertTrue(url.startswith("http://zulip.testserver/accounts/login/subdomain/"))
@ -4175,7 +4174,7 @@ class GitHubAuthBackendTest(SocialAuthBase):
self.assertEqual(data["subdomain"], "zulip")
self.assertEqual(data["redirect_to"], "/user_uploads/image")
self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result["Location"])
parsed_url = urlparse(result["Location"])
url = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
self.assertTrue(url.startswith("http://zulip.testserver/accounts/login/subdomain/"))
@ -4204,7 +4203,7 @@ class GitHubAuthBackendTest(SocialAuthBase):
self.assertEqual(data["subdomain"], "zulip")
self.assertEqual(data["redirect_to"], "/user_uploads/image")
self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result["Location"])
parsed_url = urlparse(result["Location"])
url = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
self.assertTrue(url.startswith("http://zulip.testserver/accounts/login/subdomain/"))
@ -4265,7 +4264,7 @@ class GitHubAuthBackendTest(SocialAuthBase):
self.assertEqual(data["subdomain"], "zulip")
self.assertEqual(data["redirect_to"], "/user_uploads/image")
self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result["Location"])
parsed_url = urlparse(result["Location"])
url = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
self.assertTrue(url.startswith("http://zulip.testserver/accounts/login/subdomain/"))
@ -4348,7 +4347,7 @@ class GitHubAuthBackendTest(SocialAuthBase):
self.assertEqual(data["full_name"], account_data_dict["name"])
self.assertEqual(data["subdomain"], "zulip")
self.assertEqual(result.status_code, 302)
parsed_url = urllib.parse.urlparse(result["Location"])
parsed_url = urlparse(result["Location"])
url = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
self.assertTrue(url.startswith("http://zulip.testserver/accounts/login/subdomain/"))
@ -4487,8 +4486,8 @@ class GoogleAuthBackendTest(SocialAuthBase):
self.assertEqual(result.status_code, 302)
redirect_url = result["Location"]
parsed_url = urllib.parse.urlparse(redirect_url)
query_params = urllib.parse.parse_qs(parsed_url.query)
parsed_url = urlparse(redirect_url)
query_params = parse_qs(parsed_url.query)
self.assertEqual(parsed_url.scheme, "zulip")
self.assertEqual(query_params["realm"], ["http://zulip-mobile.testserver"])
self.assertEqual(query_params["email"], [self.example_email("hamlet")])
@ -4532,8 +4531,8 @@ class GoogleAuthBackendTest(SocialAuthBase):
)
self.assertEqual(result.status_code, 302)
redirect_url = result["Location"]
parsed_url = urllib.parse.urlparse(redirect_url)
query_params = urllib.parse.parse_qs(parsed_url.query)
parsed_url = urlparse(redirect_url)
query_params = parse_qs(parsed_url.query)
self.assertEqual(parsed_url.scheme, "zulip")
self.assertEqual(query_params["realm"], ["http://zulip.testserver"])
self.assertEqual(query_params["email"], [self.example_email("hamlet")])
@ -5530,7 +5529,7 @@ class TestZulipRemoteUserBackend(DesktopFlowTestingLib, ZulipTestCase):
self.assertEqual(result.status_code, 302)
url = result["Location"]
parsed_url = urllib.parse.urlparse(url)
parsed_url = urlparse(url)
self.assertEqual(parsed_url.path, "/accounts/login/sso/")
self.assertEqual(parsed_url.query, "param1=value1&params=value2")
@ -5674,8 +5673,8 @@ class TestZulipRemoteUserBackend(DesktopFlowTestingLib, ZulipTestCase):
)
self.assertEqual(result.status_code, 302)
redirect_url = result["Location"]
parsed_url = urllib.parse.urlparse(redirect_url)
query_params = urllib.parse.parse_qs(parsed_url.query)
parsed_url = urlparse(redirect_url)
query_params = parse_qs(parsed_url.query)
self.assertEqual(parsed_url.scheme, "zulip")
self.assertEqual(query_params["realm"], ["http://zulip.testserver"])
self.assertEqual(query_params["email"], [self.example_email("hamlet")])
@ -5723,8 +5722,8 @@ class TestZulipRemoteUserBackend(DesktopFlowTestingLib, ZulipTestCase):
)
self.assertEqual(result.status_code, 302)
redirect_url = result["Location"]
parsed_url = urllib.parse.urlparse(redirect_url)
query_params = urllib.parse.parse_qs(parsed_url.query)
parsed_url = urlparse(redirect_url)
query_params = parse_qs(parsed_url.query)
self.assertEqual(parsed_url.scheme, "zulip")
self.assertEqual(query_params["realm"], ["http://zulip.testserver"])
self.assertEqual(query_params["email"], [self.example_email("hamlet")])

View File

@ -1,8 +1,8 @@
import calendar
import urllib
from datetime import timedelta, timezone
from typing import TYPE_CHECKING, Any, Dict
from unittest.mock import patch
from urllib.parse import urlparse
import orjson
import time_machine
@ -1011,7 +1011,7 @@ class HomeTest(ZulipTestCase):
self.assertTrue(result["Location"].endswith("/desktop_home/"))
result = self.client_get("/desktop_home/")
self.assertEqual(result.status_code, 302)
path = urllib.parse.urlparse(result["Location"]).path
path = urlparse(result["Location"]).path
self.assertEqual(path, "/")
@override_settings(SERVER_UPGRADE_NAG_DEADLINE_DAYS=365)

View File

@ -1,9 +1,8 @@
import re
import urllib
from datetime import datetime, timedelta
from typing import TYPE_CHECKING, List, Optional, Sequence, Union
from unittest.mock import patch
from urllib.parse import urlencode
from urllib.parse import quote, urlencode
import orjson
import time_machine
@ -2294,9 +2293,7 @@ class MultiuseInviteTest(ZulipTestCase):
result = self.client_post(invite_link, {"email": email})
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/send_confirm/?email={urllib.parse.quote(email)}"
)
result["Location"].endswith(f"/accounts/send_confirm/?email={quote(email)}")
)
result = self.client_get(result["Location"])
self.assert_in_response("check your email", result)

View File

@ -1,10 +1,10 @@
import os
import re
import urllib
from datetime import timedelta
from typing import Any, Dict, List, Optional
from unittest import mock, skipUnless
from unittest.mock import MagicMock, call, patch
from urllib.parse import quote, quote_plus
from django.apps import apps
from django.conf import settings
@ -344,7 +344,7 @@ class TestGenerateRealmCreationLink(ZulipTestCase):
)
self.assertEqual(result.status_code, 302)
self.assertEqual(
f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}&realm_name={urllib.parse.quote_plus(realm_name)}&realm_type=10&realm_default_language=en&realm_subdomain={string_id}",
f"/accounts/new/send_confirm/?email={quote(email)}&realm_name={quote_plus(realm_name)}&realm_type=10&realm_default_language=en&realm_subdomain={string_id}",
result["Location"],
)
result = self.client_get(result["Location"])

View File

@ -1,10 +1,9 @@
import re
import time
import urllib
from datetime import timedelta
from typing import TYPE_CHECKING, Any, Dict, Optional, Sequence, Union
from unittest.mock import MagicMock, patch
from urllib.parse import urlencode
from urllib.parse import quote, quote_plus, urlencode, urlparse
import orjson
from django.conf import settings
@ -1096,7 +1095,7 @@ class EmailUnsubscribeTests(ZulipTestCase):
# An unknown message type "fake" produces an error.
user_profile = self.example_user("hamlet")
unsubscribe_link = one_click_unsubscribe_link(user_profile, "fake")
result = self.client_get(urllib.parse.urlparse(unsubscribe_link).path)
result = self.client_get(urlparse(unsubscribe_link).path)
self.assert_in_response("Unknown email unsubscribe request", result)
def test_message_notification_emails_unsubscribe(self) -> None:
@ -1110,7 +1109,7 @@ class EmailUnsubscribeTests(ZulipTestCase):
user_profile.save()
unsubscribe_link = one_click_unsubscribe_link(user_profile, "missed_messages")
result = self.client_get(urllib.parse.urlparse(unsubscribe_link).path)
result = self.client_get(urlparse(unsubscribe_link).path)
self.assertEqual(result.status_code, 200)
@ -1129,7 +1128,7 @@ class EmailUnsubscribeTests(ZulipTestCase):
# Simulate unsubscribing from the welcome e-mails.
unsubscribe_link = one_click_unsubscribe_link(user_profile, "welcome")
result = self.client_get(urllib.parse.urlparse(unsubscribe_link).path)
result = self.client_get(urlparse(unsubscribe_link).path)
# The welcome email jobs are no longer scheduled.
self.assertEqual(result.status_code, 200)
@ -1167,7 +1166,7 @@ class EmailUnsubscribeTests(ZulipTestCase):
# Simulate unsubscribing from digest e-mails.
unsubscribe_link = one_click_unsubscribe_link(user_profile, "digest")
result = self.client_get(urllib.parse.urlparse(unsubscribe_link).path)
result = self.client_get(urlparse(unsubscribe_link).path)
# The setting is toggled off, and scheduled jobs have been removed.
self.assertEqual(result.status_code, 200)
@ -1188,7 +1187,7 @@ class EmailUnsubscribeTests(ZulipTestCase):
user_profile.save()
unsubscribe_link = one_click_unsubscribe_link(user_profile, "login")
result = self.client_get(urllib.parse.urlparse(unsubscribe_link).path)
result = self.client_get(urlparse(unsubscribe_link).path)
self.assertEqual(result.status_code, 200)
@ -1205,7 +1204,7 @@ class EmailUnsubscribeTests(ZulipTestCase):
# Simulate unsubscribing from marketing e-mails.
unsubscribe_link = one_click_unsubscribe_link(user_profile, "marketing")
result = self.client_get(urllib.parse.urlparse(unsubscribe_link).path)
result = self.client_get(urlparse(unsubscribe_link).path)
self.assertEqual(result.status_code, 200)
# Circumvent user_profile caching.
@ -1224,9 +1223,7 @@ class EmailUnsubscribeTests(ZulipTestCase):
# Simulate unsubscribing from marketing e-mails.
unsubscribe_link = one_click_unsubscribe_link(user_profile, "marketing")
client = Client(enforce_csrf_checks=True)
result = client.post(
urllib.parse.urlparse(unsubscribe_link).path, {"List-Unsubscribe": "One-Click"}
)
result = client.post(urlparse(unsubscribe_link).path, {"List-Unsubscribe": "One-Click"})
self.assertEqual(result.status_code, 200)
# Circumvent user_profile caching.
@ -1255,7 +1252,7 @@ class RealmCreationTest(ZulipTestCase):
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}&realm_name={urllib.parse.quote_plus(org_name)}&realm_type=10&realm_default_language=en&realm_subdomain={string_id}"
f"/accounts/new/send_confirm/?email={quote(email)}&realm_name={quote_plus(org_name)}&realm_type=10&realm_default_language=en&realm_subdomain={string_id}"
)
)
result = self.client_get(result["Location"])
@ -1398,7 +1395,7 @@ class RealmCreationTest(ZulipTestCase):
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}&realm_name={urllib.parse.quote_plus(realm_name)}&realm_type=10&realm_default_language=en&realm_subdomain={string_id}"
f"/accounts/new/send_confirm/?email={quote(email)}&realm_name={quote_plus(realm_name)}&realm_type=10&realm_default_language=en&realm_subdomain={string_id}"
)
)
result = self.client_get(result["Location"])
@ -1446,7 +1443,7 @@ class RealmCreationTest(ZulipTestCase):
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}&realm_name={urllib.parse.quote_plus(realm_name)}&realm_type=10&realm_default_language=en&realm_subdomain={string_id}"
f"/accounts/new/send_confirm/?email={quote(email)}&realm_name={quote_plus(realm_name)}&realm_type=10&realm_default_language=en&realm_subdomain={string_id}"
)
)
result = self.client_get(result["Location"])
@ -1495,7 +1492,7 @@ class RealmCreationTest(ZulipTestCase):
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}&realm_name={urllib.parse.quote_plus(realm_name)}&realm_type=10&realm_default_language=en&realm_subdomain={string_id}"
f"/accounts/new/send_confirm/?email={quote(email)}&realm_name={quote_plus(realm_name)}&realm_type=10&realm_default_language=en&realm_subdomain={string_id}"
)
)
result = self.client_get(result["Location"])
@ -1555,7 +1552,7 @@ class RealmCreationTest(ZulipTestCase):
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}&realm_name={urllib.parse.quote_plus(realm_name)}&realm_type=10&realm_default_language=en&realm_subdomain={string_id}"
f"/accounts/new/send_confirm/?email={quote(email)}&realm_name={quote_plus(realm_name)}&realm_type=10&realm_default_language=en&realm_subdomain={string_id}"
)
)
result = self.client_get(result["Location"])
@ -1600,7 +1597,7 @@ class RealmCreationTest(ZulipTestCase):
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}&realm_name={urllib.parse.quote_plus(realm_name)}&realm_type=10&realm_default_language=en&realm_subdomain={string_id}"
f"/accounts/new/send_confirm/?email={quote(email)}&realm_name={quote_plus(realm_name)}&realm_type=10&realm_default_language=en&realm_subdomain={string_id}"
)
)
result = self.client_get(result["Location"])
@ -1651,7 +1648,7 @@ class RealmCreationTest(ZulipTestCase):
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}&realm_name={urllib.parse.quote_plus(realm_name)}&realm_type=35&realm_default_language=en&realm_subdomain={string_id}"
f"/accounts/new/send_confirm/?email={quote(email)}&realm_name={quote_plus(realm_name)}&realm_type=35&realm_default_language=en&realm_subdomain={string_id}"
)
)
result = self.client_get(result["Location"])
@ -1708,7 +1705,7 @@ class RealmCreationTest(ZulipTestCase):
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}&realm_name={urllib.parse.quote_plus(realm_name)}&realm_type=10&realm_default_language={realm_language}&realm_subdomain={string_id}"
f"/accounts/new/send_confirm/?email={quote(email)}&realm_name={quote_plus(realm_name)}&realm_type=10&realm_default_language={realm_language}&realm_subdomain={string_id}"
)
)
result = self.client_get(result["Location"])
@ -1774,7 +1771,7 @@ class RealmCreationTest(ZulipTestCase):
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}&realm_name={urllib.parse.quote_plus(realm_name)}&realm_type=10&realm_default_language=en&realm_subdomain={string_id}"
f"/accounts/new/send_confirm/?email={quote(email)}&realm_name={quote_plus(realm_name)}&realm_type=10&realm_default_language=en&realm_subdomain={string_id}"
)
)
result = self.client_get(result["Location"])
@ -1830,7 +1827,7 @@ class RealmCreationTest(ZulipTestCase):
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}&realm_name={urllib.parse.quote_plus(first_realm_name)}&realm_type=10&realm_default_language=en&realm_subdomain={first_string_id}"
f"/accounts/new/send_confirm/?email={quote(email)}&realm_name={quote_plus(first_realm_name)}&realm_type=10&realm_default_language=en&realm_subdomain={first_string_id}"
)
)
result = self.client_get(result["Location"])
@ -1846,7 +1843,7 @@ class RealmCreationTest(ZulipTestCase):
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}&realm_name={urllib.parse.quote_plus(second_realm_name)}&realm_type=10&realm_default_language=en&realm_subdomain={second_string_id}"
f"/accounts/new/send_confirm/?email={quote(email)}&realm_name={quote_plus(second_realm_name)}&realm_type=10&realm_default_language=en&realm_subdomain={second_string_id}"
)
)
result = self.client_get(result["Location"])
@ -2118,9 +2115,7 @@ class UserSignUpTest(ZulipTestCase):
result = self.client_post("/accounts/home/", {"email": email}, **client_kwargs)
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/send_confirm/?email={urllib.parse.quote(email)}"
)
result["Location"].endswith(f"/accounts/send_confirm/?email={quote(email)}")
)
result = self.client_get(result["Location"], **client_kwargs)
self.assert_in_response("check your email", result)
@ -2261,9 +2256,7 @@ class UserSignUpTest(ZulipTestCase):
result = self.client_post("/accounts/home/", {"email": email})
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/send_confirm/?email={urllib.parse.quote(email)}"
)
result["Location"].endswith(f"/accounts/send_confirm/?email={quote(email)}")
)
result = self.client_get(result["Location"])
self.assert_in_response("check your email", result)
@ -2296,9 +2289,7 @@ class UserSignUpTest(ZulipTestCase):
result = self.client_post("/accounts/home/", {"email": email})
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/send_confirm/?email={urllib.parse.quote(email)}"
)
result["Location"].endswith(f"/accounts/send_confirm/?email={quote(email)}")
)
result = self.client_get(result["Location"])
self.assert_in_response("check your email", result)
@ -2334,9 +2325,7 @@ class UserSignUpTest(ZulipTestCase):
result = self.client_post("/accounts/home/", {"email": email})
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/send_confirm/?email={urllib.parse.quote(email)}"
)
result["Location"].endswith(f"/accounts/send_confirm/?email={quote(email)}")
)
result = self.client_get(result["Location"])
self.assert_in_response("check your email", result)
@ -2367,9 +2356,7 @@ class UserSignUpTest(ZulipTestCase):
result = self.client_post("/accounts/home/", {"email": email})
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/send_confirm/?email={urllib.parse.quote(email)}"
)
result["Location"].endswith(f"/accounts/send_confirm/?email={quote(email)}")
)
result = self.client_get(result["Location"])
self.assert_in_response("check your email", result)
@ -2472,9 +2459,7 @@ class UserSignUpTest(ZulipTestCase):
result = self.client_post("/accounts/home/", {"email": email})
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/send_confirm/?email={urllib.parse.quote(email)}"
)
result["Location"].endswith(f"/accounts/send_confirm/?email={quote(email)}")
)
result = self.client_get(result["Location"])
self.assert_in_response("check your email", result)
@ -2521,7 +2506,7 @@ class UserSignUpTest(ZulipTestCase):
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/login/?email={urllib.parse.quote(email)}&already_registered=1"
f"/accounts/login/?email={quote(email)}&already_registered=1"
)
)
@ -2790,9 +2775,7 @@ class UserSignUpTest(ZulipTestCase):
result = self.client_post("/accounts/home/", {"email": email})
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/send_confirm/?email={urllib.parse.quote(email)}"
)
result["Location"].endswith(f"/accounts/send_confirm/?email={quote(email)}")
)
result = self.client_get(result["Location"])
self.assert_in_response("check your email", result)
@ -2974,9 +2957,7 @@ class UserSignUpTest(ZulipTestCase):
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/send_confirm/?email={urllib.parse.quote(email)}"
)
result["Location"].endswith(f"/accounts/send_confirm/?email={quote(email)}")
)
result = self.client_get(result["Location"])
self.assert_in_response("check your email", result)
@ -3062,9 +3043,7 @@ class UserSignUpTest(ZulipTestCase):
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/send_confirm/?email={urllib.parse.quote(email)}"
)
result["Location"].endswith(f"/accounts/send_confirm/?email={quote(email)}")
)
result = self.client_get(result["Location"])
self.assert_in_response("check your email", result)
@ -3146,9 +3125,7 @@ class UserSignUpTest(ZulipTestCase):
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/send_confirm/?email={urllib.parse.quote(email)}"
)
result["Location"].endswith(f"/accounts/send_confirm/?email={quote(email)}")
)
result = self.client_get(result["Location"])
self.assert_in_response("check your email", result)
@ -3223,9 +3200,7 @@ class UserSignUpTest(ZulipTestCase):
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/send_confirm/?email={urllib.parse.quote(email)}"
)
result["Location"].endswith(f"/accounts/send_confirm/?email={quote(email)}")
)
result = self.client_get(result["Location"])
self.assert_in_response("check your email", result)
@ -3299,9 +3274,7 @@ class UserSignUpTest(ZulipTestCase):
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/send_confirm/?email={urllib.parse.quote(email)}"
)
result["Location"].endswith(f"/accounts/send_confirm/?email={quote(email)}")
)
result = self.client_get(result["Location"])
self.assert_in_response("check your email", result)
@ -3449,9 +3422,7 @@ class UserSignUpTest(ZulipTestCase):
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/send_confirm/?email={urllib.parse.quote(email)}"
)
result["Location"].endswith(f"/accounts/send_confirm/?email={quote(email)}")
)
result = self.client_get(result["Location"])
self.assert_in_response("check your email", result)
@ -3504,9 +3475,7 @@ class UserSignUpTest(ZulipTestCase):
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/send_confirm/?email={urllib.parse.quote(email)}"
)
result["Location"].endswith(f"/accounts/send_confirm/?email={quote(email)}")
)
result = self.client_get(result["Location"])
self.assert_in_response("check your email", result)
@ -3630,9 +3599,7 @@ class UserSignUpTest(ZulipTestCase):
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/send_confirm/?email={urllib.parse.quote(email)}"
)
result["Location"].endswith(f"/accounts/send_confirm/?email={quote(email)}")
)
result = self.client_get(result["Location"])
self.assert_in_response("check your email", result)
@ -3675,9 +3642,7 @@ class UserSignUpTest(ZulipTestCase):
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/send_confirm/?email={urllib.parse.quote(email)}"
)
result["Location"].endswith(f"/accounts/send_confirm/?email={quote(email)}")
)
result = self.client_get(result["Location"])
self.assert_in_response("check your email", result)
@ -3837,9 +3802,7 @@ class UserSignUpTest(ZulipTestCase):
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/send_confirm/?email={urllib.parse.quote(email)}"
)
result["Location"].endswith(f"/accounts/send_confirm/?email={quote(email)}")
)
result = self.client_get(result["Location"])
self.assert_in_response("check your email", result)
@ -3870,9 +3833,7 @@ class UserSignUpTest(ZulipTestCase):
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/send_confirm/?email={urllib.parse.quote(email)}"
)
result["Location"].endswith(f"/accounts/send_confirm/?email={quote(email)}")
)
result = self.client_get(result["Location"])
self.assert_in_response("check your email", result)
@ -3936,9 +3897,7 @@ class UserSignUpTest(ZulipTestCase):
self.assertEqual(result.status_code, 302)
self.assertTrue(
result["Location"].endswith(
f"/accounts/send_confirm/?email={urllib.parse.quote(email)}"
)
result["Location"].endswith(f"/accounts/send_confirm/?email={quote(email)}")
)
result = self.client_get(result["Location"], subdomain="zephyr")
self.assert_in_response("check your email", result)

View File

@ -1,9 +1,9 @@
import asyncio
import socket
import urllib.parse
from functools import wraps
from typing import Any, Awaitable, Callable, Dict, Optional, TypeVar
from unittest import TestResult, mock
from urllib.parse import urlencode
import orjson
from asgiref.sync import async_to_sync, sync_to_async
@ -120,7 +120,7 @@ class EventsTestCase(TornadoWebTestCase):
"last_event_id": -1,
}
path = f"/json/events?{urllib.parse.urlencode(data)}"
path = f"/json/events?{urlencode(data)}"
def process_events() -> None:
users = [user_profile.id]

View File

@ -2,10 +2,10 @@ import io
import os
import re
import time
import urllib
from io import StringIO
from unittest import mock
from unittest.mock import patch
from urllib.parse import quote
import orjson
from django.conf import settings
@ -572,7 +572,7 @@ class FileUploadTest(UploadSerializeMixin, ZulipTestCase):
self.login("hamlet")
for expected in ["Здравейте.txt", "test"]:
fp = StringIO("bah!")
fp.name = urllib.parse.quote(expected)
fp.name = quote(expected)
result = self.client_post("/json/user_uploads", {"f1": fp})
response_dict = self.assert_json_success(result)
@ -590,7 +590,7 @@ class FileUploadTest(UploadSerializeMixin, ZulipTestCase):
("**", "uploaded-file"),
]:
fp = StringIO("bah!")
fp.name = urllib.parse.quote(uploaded_filename)
fp.name = quote(uploaded_filename)
result = self.client_post("/json/user_uploads", {"f1": fp})
response_dict = self.assert_json_success(result)

View File

@ -1,6 +1,5 @@
import os
import re
import urllib
from io import BytesIO, StringIO
from urllib.parse import urlparse
@ -258,5 +257,5 @@ class LocalStorageTest(UploadSerializeMixin, ZulipTestCase):
warn_log.output,
["WARNING:root:not_a_file does not exist. Its entry in the database will be removed."],
)
path_id = urllib.parse.urlparse(url).path
path_id = urlparse(url).path
self.assertEqual(delete_export_tarball(path_id), path_id)

View File

@ -1,9 +1,9 @@
import io
import os
import re
import urllib
from io import BytesIO, StringIO
from unittest.mock import patch
from urllib.parse import urlparse
import botocore.exceptions
from django.conf import settings
@ -191,7 +191,7 @@ class S3Test(ZulipTestCase):
# In development, this is just a redirect
response = self.client_get(url)
redirect_url = response["Location"]
path = urllib.parse.urlparse(redirect_url).path
path = urlparse(redirect_url).path
assert path.startswith("/")
key = path[len("/") :]
self.assertEqual(b"zulip!", bucket.Object(key).get()["Body"].read())
@ -200,7 +200,7 @@ class S3Test(ZulipTestCase):
with self.settings(DEVELOPMENT=False):
response = self.client_get(url)
redirect_url = response["X-Accel-Redirect"]
path = urllib.parse.urlparse(redirect_url).path
path = urlparse(redirect_url).path
assert path.startswith(prefix)
key = path[len(prefix) :]
self.assertEqual(b"zulip!", bucket.Object(key).get()["Body"].read())
@ -210,7 +210,7 @@ class S3Test(ZulipTestCase):
with self.settings(DEVELOPMENT=False):
response = self.client_get(download_url)
redirect_url = response["X-Accel-Redirect"]
path = urllib.parse.urlparse(redirect_url).path
path = urlparse(redirect_url).path
assert path.startswith(prefix)
key = path[len(prefix) :]
self.assertEqual(b"zulip!", bucket.Object(key).get()["Body"].read())
@ -230,7 +230,7 @@ class S3Test(ZulipTestCase):
with self.settings(DEVELOPMENT=False):
self.client_get(url_only_url)
redirect_url = response["X-Accel-Redirect"]
path = urllib.parse.urlparse(redirect_url).path
path = urlparse(redirect_url).path
assert path.startswith(prefix)
key = path[len(prefix) :]
self.assertEqual(b"zulip!", bucket.Object(key).get()["Body"].read())
@ -532,5 +532,5 @@ class S3Test(ZulipTestCase):
warn_log.output,
["WARNING:root:not_a_file does not exist. Its entry in the database will be removed."],
)
path_id = urllib.parse.urlparse(url).path
path_id = urlparse(url).path
self.assertEqual(delete_export_tarball(path_id), path_id)

View File

@ -1,7 +1,7 @@
import logging
import urllib
from contextlib import suppress
from typing import Any, Dict, List, Optional
from urllib.parse import unquote
import tornado.web
from asgiref.sync import sync_to_async
@ -108,7 +108,7 @@ class AsyncDjangoHandler(tornado.web.RequestHandler):
# HttpRequest object with the original Tornado request's HTTP
# headers, parameters, etc.
environ = fake_wsgi_container.environ(self.request)
environ["PATH_INFO"] = urllib.parse.unquote(environ["PATH_INFO"])
environ["PATH_INFO"] = unquote(environ["PATH_INFO"])
# Django WSGIRequest setup code that should match logic from
# Django's WSGIHandler.__call__ before the call to

View File

@ -1,9 +1,8 @@
import logging
import secrets
import urllib
from functools import wraps
from typing import TYPE_CHECKING, Any, Callable, Dict, List, Mapping, Optional, Tuple, cast
from urllib.parse import urlencode
from urllib.parse import urlencode, urljoin
import jwt
import orjson
@ -115,7 +114,7 @@ def get_safe_redirect_to(url: str, redirect_host: str) -> str:
# Mark as safe to prevent Pysa from surfacing false positives for
# open redirects. In this branch, we have already checked that the URL
# points to the specified 'redirect_host', or is relative.
return urllib.parse.urljoin(redirect_host, mark_sanitized(url))
return urljoin(redirect_host, mark_sanitized(url))
else:
return redirect_host
@ -478,7 +477,7 @@ def create_response_for_otp_flow(
}
# We can't use HttpResponseRedirect, since it only allows HTTP(S) URLs
response = HttpResponse(status=302)
response["Location"] = append_url_query_string("zulip://login", urllib.parse.urlencode(params))
response["Location"] = append_url_query_string("zulip://login", urlencode(params))
return response
@ -628,7 +627,7 @@ def oauth_redirect_to_root(
params = {**params, **extra_url_params}
return redirect(append_url_query_string(main_site_url, urllib.parse.urlencode(params)))
return redirect(append_url_query_string(main_site_url, urlencode(params)))
def handle_desktop_flow(

View File

@ -1,7 +1,7 @@
import os
import urllib
from contextlib import suppress
from typing import Optional
from urllib.parse import urlencode
import orjson
from django.conf import settings
@ -121,7 +121,7 @@ def generate_all_emails(request: HttpRequest) -> HttpResponse:
# Verification for new email
result = client.patch(
"/json/settings",
urllib.parse.urlencode({"email": "hamlets-new@zulip.com"}),
urlencode({"email": "hamlets-new@zulip.com"}),
content_type="application/x-www-form-urlencoded",
HTTP_HOST=realm.host,
)

View File

@ -1,5 +1,4 @@
import logging
import urllib
from contextlib import suppress
from typing import Any, Dict, Iterable, List, Optional, Tuple, Union
from urllib.parse import urlencode, urljoin
@ -1109,7 +1108,7 @@ def find_account(
# Note: Show all the emails in the result otherwise this
# feature can be used to ascertain which email addresses
# are associated with Zulip.
data = urllib.parse.urlencode({"emails": ",".join(emails)})
data = urlencode({"emails": ",".join(emails)})
return redirect(append_url_query_string(url, data))
else:
form = FindMyTeamForm()

View File

@ -1,7 +1,7 @@
import logging
import urllib
from contextlib import suppress
from typing import Type
from urllib.parse import urlparse
import orjson
from circuitbreaker import CircuitBreakerError, circuit
@ -34,7 +34,7 @@ def sentry_tunnel(
try:
envelope_header_line, envelope_items = request.body.split(b"\n", 1)
envelope_header = to_wild_value("envelope_header", envelope_header_line.decode("utf-8"))
dsn = urllib.parse.urlparse(envelope_header["dsn"].tame(check_url))
dsn = urlparse(envelope_header["dsn"].tame(check_url))
except Exception:
raise JsonableError(_("Invalid request format"))

View File

@ -1,4 +1,4 @@
import urllib
from urllib.parse import urlencode
from typing_extensions import override
@ -15,7 +15,7 @@ class LibratoHookTests(WebhookTestCase):
def get_body(self, fixture_name: str) -> str:
if self.IS_ATTACHMENT:
return self.webhook_fixture_data("librato", fixture_name, file_type="json")
return urllib.parse.urlencode(
return urlencode(
{"payload": self.webhook_fixture_data("librato", fixture_name, file_type="json")}
)

View File

@ -1,4 +1,4 @@
import urllib
from urllib.parse import urlencode
from typing_extensions import override
@ -131,6 +131,6 @@ one or more new messages.
@override
def get_body(self, fixture_name: str) -> str:
return urllib.parse.urlencode(
return urlencode(
{"payload": self.webhook_fixture_data("travis", fixture_name, file_type="json")}
)

View File

@ -10,7 +10,6 @@ import socket
import tempfile
import threading
import time
import urllib
from abc import ABC, abstractmethod
from collections import defaultdict, deque
from datetime import timedelta
@ -31,6 +30,7 @@ from typing import (
Type,
TypeVar,
)
from urllib.parse import urlparse
import orjson
import sentry_sdk
@ -1132,7 +1132,7 @@ class DeferredWorker(QueueProcessingWorker):
assert public_url is not None
# Update the extra_data field now that the export is complete.
extra_data["export_path"] = urllib.parse.urlparse(public_url).path
extra_data["export_path"] = urlparse(public_url).path
export_event.extra_data = extra_data
export_event.save(update_fields=["extra_data"])