replace `werkzeug.urls` with `urllib.parse`
diff --git a/CHANGES.rst b/CHANGES.rst
index cd1a04c489..a8762477eb 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1,3 +1,11 @@
+Version 2.2.4
+-------------
+
+Unreleased
+
+-   Update for compatibility with Werkzeug 2.3.
+
+
 Version 2.2.3
 -------------
 
diff --git a/src/flask/app.py b/src/flask/app.py
index ff6b097382..d904d6ba38 100644
--- a/src/flask/app.py
+++ b/src/flask/app.py
@@ -11,6 +11,7 @@
 from itertools import chain
 from threading import Lock
 from types import TracebackType
+from urllib.parse import quote as _url_quote
 
 import click
 from werkzeug.datastructures import Headers
@@ -27,7 +28,6 @@
 from werkzeug.routing import RoutingException
 from werkzeug.routing import Rule
 from werkzeug.serving import is_running_from_reloader
-from werkzeug.urls import url_quote
 from werkzeug.utils import redirect as _wz_redirect
 from werkzeug.wrappers import Response as BaseResponse
 
@@ -2034,7 +2034,8 @@ def url_for(
             return self.handle_url_build_error(error, endpoint, values)
 
         if _anchor is not None:
-            rv = f"{rv}#{url_quote(_anchor)}"
+            _anchor = _url_quote(_anchor, safe="%!#$&'()*+,/:;=?@")
+            rv = f"{rv}#{_anchor}"
 
         return rv
 
diff --git a/src/flask/testing.py b/src/flask/testing.py
index 3b21b093fb..8cb2d1bd94 100644
--- a/src/flask/testing.py
+++ b/src/flask/testing.py
@@ -3,11 +3,11 @@
 from contextlib import ExitStack
 from copy import copy
 from types import TracebackType
+from urllib.parse import urlsplit
 
 import werkzeug.test
 from click.testing import CliRunner
 from werkzeug.test import Client
-from werkzeug.urls import url_parse
 from werkzeug.wrappers import Request as BaseRequest
 
 from .cli import ScriptInfo
@@ -68,7 +68,7 @@ def __init__(
             if url_scheme is None:
                 url_scheme = app.config["PREFERRED_URL_SCHEME"]
 
-            url = url_parse(path)
+            url = urlsplit(path)
             base_url = (
                 f"{url.scheme or url_scheme}://{url.netloc or http_host}"
                 f"/{app_root.lstrip('/')}"

For compatibility with Werkzeug 2.3, which deprecates `werkzeug.urls`.