We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Bug: mounted app path interferes with regular paths
### Description

According to ["Mounting ASGI apps"](https://docs.litestar.dev/latest/usage/routing/overview.html#mounting-asgi-apps) documentation section, Litestar can mount ASGI apps in **sub-paths**. So it is expected that if ASGI app is mounted with `path='/magic'`, every route _starting with `/magic`_ will be handled by the ASGI app, and any other route will be handled by other handlers. However, it is not true.

Imagine this setup:

```python
@asgi("/magic", is_mount=True)
async def xxx(...):
    print('Mounted')
    ...

@get("/{number:int}/magic/")
async def yyy() -> str:
    print('Parametrized')

@get("/static/magic/")
async def zzz() -> str:
    print('Static')
```

Here's "expectations VS reality" table:
| Request path  | Expected output | Real output |
| -------------------- | ------------------------ | ------------------|
| `/magic`           | `Mounted`           | `Mounted`     |
|`/123/magic/`   | `Parametrized`   | `Mounted`     |
|`/static/magic/`| `Static`                  | `Static`    |
|`/non-existent/magic/` | 404 error | `Mounted` |

## Why this happens?

`litestar/_asgi/routing_trie/traversal.py:parse_path_to_route` method has [this line](https://github.com/litestar-org/litestar/blob/main/litestar/_asgi/routing_trie/traversal.py#L139):
```
if mount_paths_regex and (match := mount_paths_regex.search(path)):
```
So instead of **matching** `/magic` to `path`, `re.search` is used which searches for occurrence of `/magic` anywhere in `path`, thus resulting in "false positives" for strings such as `/123/magic/`, `/non-existent/magic/` and `/non-existent/magic/something`.

## Possible solution

This cannot be solved by simply using regex:
```python
@asgi("^/magic", is_mount=True)
```
since `mount_paths_regex` becomes `re.compile('/^/magic')`, so it not only doesn't solve the problem, but the `/magic` endpoint itself stops working.

I believe it may be solved by replacing `mount_paths_regex.search(path)` with `mount_paths_regex.match(path)` - I did manual tests and it solved the problem completely, but ofc such a change requires tests to ensure nothing else is broken.

I am ready to create a full-fledged pull request with tests once the issue is approved :)

### URL to code causing the issue

_No response_

### MCVE

```python
from typing import Any

from litestar import Litestar, asgi, get
from litestar.response.base import ASGIResponse


@asgi("/magic", is_mount=True)
async def mounted_handler(scope: Any, receive: Any, send: Any) -> None:
    body = 'mounted!'
    response = ASGIResponse(body=body.encode("utf-8"))
    await response(scope, receive, send)


@get("/{number:int}/magic/")
async def parametrized_handler() -> str:
    return 'parametrized'


@get("/static/magic/")
async def static_handler() -> str:
    return 'static'


app = Litestar(route_handlers=[
    mounted_handler,
    parametrized_handler,
    static_handler,
])
```


### Steps to reproduce

```bash
1. Use the source code from MCVE to run Litestar app
2. Run curl to see wrong handler invoked for parametrized path:
  > curl http://127.0.0.1:8000/123/magic
  mounted!     
3. Run curl to see wrong handler invoked for non-existent path:
  > curl http://127.0.0.1:8000/whatever/magic
  mounted!
```


### Screenshots

_No response_

### Logs

_No response_

### Litestar Version

2.8.3

### Platform

- [X] Linux
- [ ] Mac
- [ ] Windows
- [ ] Other (Please specify in the description above)

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `litestar/_asgi/routing_trie/traversal.py`
Content:
```
1 from __future__ import annotations
2 
3 from functools import lru_cache
4 from typing import TYPE_CHECKING, Any, Pattern
5 
6 from litestar._asgi.routing_trie.types import PathParameterSentinel
7 from litestar.exceptions import MethodNotAllowedException, NotFoundException
8 from litestar.utils import normalize_path
9 
10 __all__ = ("parse_node_handlers", "parse_path_params", "parse_path_to_route", "traverse_route_map")
11 
12 
13 if TYPE_CHECKING:
14     from litestar._asgi.routing_trie.types import ASGIHandlerTuple, RouteTrieNode
15     from litestar.types import ASGIApp, Method, RouteHandlerType
16     from litestar.types.internal_types import PathParameterDefinition
17 
18 
19 def traverse_route_map(
20     root_node: RouteTrieNode,
21     path: str,
22 ) -> tuple[RouteTrieNode, list[str], str]:
23     """Traverses the application route mapping and retrieves the correct node for the request url.
24 
25     Args:
26         root_node: The root trie node.
27         path: The request's path.
28 
29     Raises:
30         NotFoundException: If no correlating node is found.
31 
32     Returns:
33         A tuple containing the target RouteMapNode and a list containing all path parameter values.
34     """
35     current_node = root_node
36     path_params: list[str] = []
37     path_components = [p for p in path.split("/") if p]
38 
39     for i, component in enumerate(path_components):
40         if component in current_node.child_keys:
41             current_node = current_node.children[component]
42             continue
43 
44         if current_node.is_path_param_node:
45             current_node = current_node.children[PathParameterSentinel]
46 
47             if current_node.is_path_type:
48                 path_params.append(normalize_path("/".join(path_components[i:])))
49                 break
50 
51             path_params.append(component)
52             continue
53 
54         raise NotFoundException()
55 
56     if not current_node.asgi_handlers:
57         raise NotFoundException()
58 
59     return current_node, path_params, path
60 
61 
62 def parse_node_handlers(
63     node: RouteTrieNode,
64     method: Method | None,
65 ) -> ASGIHandlerTuple:
66     """Retrieve the handler tuple from the node.
67 
68     Args:
69         node: The trie node to parse.
70         method: The scope's method.
71 
72     Raises:
73         KeyError: If no matching method is found.
74 
75     Returns:
76         An ASGI Handler tuple.
77     """
78 
79     if node.is_asgi:
80         return node.asgi_handlers["asgi"]
81     if method:
82         return node.asgi_handlers[method]
83     return node.asgi_handlers["websocket"]
84 
85 
86 @lru_cache(1024)
87 def parse_path_params(
88     parameter_definitions: tuple[PathParameterDefinition, ...], path_param_values: tuple[str, ...]
89 ) -> dict[str, Any]:
90     """Parse path parameters into a dictionary of values.
91 
92     Args:
93         parameter_definitions: The parameter definitions tuple from the route.
94         path_param_values: The string values extracted from the url
95 
96     Raises:
97         ValueError: If any of path parameters can not be parsed into a value.
98 
99     Returns:
100         A dictionary of parsed path parameters.
101     """
102     return {
103         param_definition.name: param_definition.parser(value) if param_definition.parser else value
104         for param_definition, value in zip(parameter_definitions, path_param_values)
105     }
106 
107 
108 def parse_path_to_route(
109     method: Method | None,
110     mount_paths_regex: Pattern | None,
111     mount_routes: dict[str, RouteTrieNode],
112     path: str,
113     plain_routes: set[str],
114     root_node: RouteTrieNode,
115 ) -> tuple[ASGIApp, RouteHandlerType, str, dict[str, Any]]:
116     """Given a scope object, retrieve the asgi_handlers and is_mount boolean values from correct trie node.
117 
118     Args:
119         method: The scope's method, if any.
120         root_node: The root trie node.
121         path: The path to resolve scope instance.
122         plain_routes: The set of plain routes.
123         mount_routes: Mapping of mount routes to trie nodes.
124         mount_paths_regex: A compiled regex to match the mount routes.
125 
126     Raises:
127         MethodNotAllowedException: if no matching method is found.
128         NotFoundException: If no correlating node is found or if path params can not be parsed into values according to the node definition.
129 
130     Returns:
131         A tuple containing the stack of middlewares and the route handler that is wrapped by it.
132     """
133 
134     try:
135         if path in plain_routes:
136             asgi_app, handler = parse_node_handlers(node=root_node.children[path], method=method)
137             return asgi_app, handler, path, {}
138 
139         if mount_paths_regex and (match := mount_paths_regex.search(path)):
140             mount_path = path[match.start() : match.end()]
141             mount_node = mount_routes[mount_path]
142             remaining_path = path[match.end() :]
143             # since we allow regular handlers under static paths, we must validate that the request does not match
144             # any such handler.
145             children = (
146                 normalize_path(sub_route)
147                 for sub_route in mount_node.children or []
148                 if sub_route != mount_path and isinstance(sub_route, str)
149             )
150             if not any(remaining_path.startswith(f"{sub_route}/") for sub_route in children):
151                 asgi_app, handler = parse_node_handlers(node=mount_node, method=method)
152                 remaining_path = remaining_path or "/"
153                 if not mount_node.is_static:
154                     remaining_path = remaining_path if remaining_path.endswith("/") else f"{remaining_path}/"
155                 return asgi_app, handler, remaining_path, {}
156 
157         node, path_parameters, path = traverse_route_map(
158             root_node=root_node,
159             path=path,
160         )
161         asgi_app, handler = parse_node_handlers(node=node, method=method)
162         key = method or ("asgi" if node.is_asgi else "websocket")
163         parsed_path_parameters = parse_path_params(node.path_parameters[key], tuple(path_parameters))
164 
165         return (
166             asgi_app,
167             handler,
168             path,
169             parsed_path_parameters,
170         )
171     except KeyError as e:
172         raise MethodNotAllowedException() from e
173     except ValueError as e:
174         raise NotFoundException() from e
175
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/litestar/_asgi/routing_trie/traversal.py b/litestar/_asgi/routing_trie/traversal.py
--- a/litestar/_asgi/routing_trie/traversal.py
+++ b/litestar/_asgi/routing_trie/traversal.py
@@ -136,8 +136,8 @@
             asgi_app, handler = parse_node_handlers(node=root_node.children[path], method=method)
             return asgi_app, handler, path, {}
 
-        if mount_paths_regex and (match := mount_paths_regex.search(path)):
-            mount_path = path[match.start() : match.end()]
+        if mount_paths_regex and (match := mount_paths_regex.match(path)):
+            mount_path = path[: match.end()]
             mount_node = mount_routes[mount_path]
             remaining_path = path[match.end() :]
             # since we allow regular handlers under static paths, we must validate that the request does not match

{"golden_diff": "diff --git a/litestar/_asgi/routing_trie/traversal.py b/litestar/_asgi/routing_trie/traversal.py\n--- a/litestar/_asgi/routing_trie/traversal.py\n+++ b/litestar/_asgi/routing_trie/traversal.py\n@@ -136,8 +136,8 @@\n             asgi_app, handler = parse_node_handlers(node=root_node.children[path], method=method)\n             return asgi_app, handler, path, {}\n \n-        if mount_paths_regex and (match := mount_paths_regex.search(path)):\n-            mount_path = path[match.start() : match.end()]\n+        if mount_paths_regex and (match := mount_paths_regex.match(path)):\n+            mount_path = path[: match.end()]\n             mount_node = mount_routes[mount_path]\n             remaining_path = path[match.end() :]\n             # since we allow regular handlers under static paths, we must validate that the request does not match\n", "issue": "Bug: mounted app path interferes with regular paths\n### Description\r\n\r\nAccording to [\"Mounting ASGI apps\"](https://docs.litestar.dev/latest/usage/routing/overview.html#mounting-asgi-apps) documentation section, Litestar can mount ASGI apps in **sub-paths**. So it is expected that if ASGI app is mounted with `path='/magic'`, every route _starting with `/magic`_ will be handled by the ASGI app, and any other route will be handled by other handlers. However, it is not true.\r\n\r\nImagine this setup:\r\n\r\n```python\r\n@asgi(\"/magic\", is_mount=True)\r\nasync def xxx(...):\r\n    print('Mounted')\r\n    ...\r\n\r\n@get(\"/{number:int}/magic/\")\r\nasync def yyy() -> str:\r\n    print('Parametrized')\r\n\r\n@get(\"/static/magic/\")\r\nasync def zzz() -> str:\r\n    print('Static')\r\n```\r\n\r\nHere's \"expectations VS reality\" table:\r\n| Request path  | Expected output | Real output |\r\n| -------------------- | ------------------------ | ------------------|\r\n| `/magic`           | `Mounted`           | `Mounted`     |\r\n|`/123/magic/`   | `Parametrized`   | `Mounted`     |\r\n|`/static/magic/`| `Static`                  | `Static`    |\r\n|`/non-existent/magic/` | 404 error | `Mounted` |\r\n\r\n## Why this happens?\r\n\r\n`litestar/_asgi/routing_trie/traversal.py:parse_path_to_route` method has [this line](https://github.com/litestar-org/litestar/blob/main/litestar/_asgi/routing_trie/traversal.py#L139):\r\n```\r\nif mount_paths_regex and (match := mount_paths_regex.search(path)):\r\n```\r\nSo instead of **matching** `/magic` to `path`, `re.search` is used which searches for occurrence of `/magic` anywhere in `path`, thus resulting in \"false positives\" for strings such as `/123/magic/`, `/non-existent/magic/` and `/non-existent/magic/something`.\r\n\r\n## Possible solution\r\n\r\nThis cannot be solved by simply using regex:\r\n```python\r\n@asgi(\"^/magic\", is_mount=True)\r\n```\r\nsince `mount_paths_regex` becomes `re.compile('/^/magic')`, so it not only doesn't solve the problem, but the `/magic` endpoint itself stops working.\r\n\r\nI believe it may be solved by replacing `mount_paths_regex.search(path)` with `mount_paths_regex.match(path)` - I did manual tests and it solved the problem completely, but ofc such a change requires tests to ensure nothing else is broken.\r\n\r\nI am ready to create a full-fledged pull request with tests once the issue is approved :)\r\n\r\n### URL to code causing the issue\r\n\r\n_No response_\r\n\r\n### MCVE\r\n\r\n```python\r\nfrom typing import Any\r\n\r\nfrom litestar import Litestar, asgi, get\r\nfrom litestar.response.base import ASGIResponse\r\n\r\n\r\n@asgi(\"/magic\", is_mount=True)\r\nasync def mounted_handler(scope: Any, receive: Any, send: Any) -> None:\r\n    body = 'mounted!'\r\n    response = ASGIResponse(body=body.encode(\"utf-8\"))\r\n    await response(scope, receive, send)\r\n\r\n\r\n@get(\"/{number:int}/magic/\")\r\nasync def parametrized_handler() -> str:\r\n    return 'parametrized'\r\n\r\n\r\n@get(\"/static/magic/\")\r\nasync def static_handler() -> str:\r\n    return 'static'\r\n\r\n\r\napp = Litestar(route_handlers=[\r\n    mounted_handler,\r\n    parametrized_handler,\r\n    static_handler,\r\n])\r\n```\r\n\r\n\r\n### Steps to reproduce\r\n\r\n```bash\r\n1. Use the source code from MCVE to run Litestar app\r\n2. Run curl to see wrong handler invoked for parametrized path:\r\n  > curl http://127.0.0.1:8000/123/magic\r\n  mounted!     \r\n3. Run curl to see wrong handler invoked for non-existent path:\r\n  > curl http://127.0.0.1:8000/whatever/magic\r\n  mounted!\r\n```\r\n\r\n\r\n### Screenshots\r\n\r\n_No response_\r\n\r\n### Logs\r\n\r\n_No response_\r\n\r\n### Litestar Version\r\n\r\n2.8.3\r\n\r\n### Platform\r\n\r\n- [X] Linux\r\n- [ ] Mac\r\n- [ ] Windows\r\n- [ ] Other (Please specify in the description above)\n", "before_files": [{"content": "from __future__ import annotations\n\nfrom functools import lru_cache\nfrom typing import TYPE_CHECKING, Any, Pattern\n\nfrom litestar._asgi.routing_trie.types import PathParameterSentinel\nfrom litestar.exceptions import MethodNotAllowedException, NotFoundException\nfrom litestar.utils import normalize_path\n\n__all__ = (\"parse_node_handlers\", \"parse_path_params\", \"parse_path_to_route\", \"traverse_route_map\")\n\n\nif TYPE_CHECKING:\n    from litestar._asgi.routing_trie.types import ASGIHandlerTuple, RouteTrieNode\n    from litestar.types import ASGIApp, Method, RouteHandlerType\n    from litestar.types.internal_types import PathParameterDefinition\n\n\ndef traverse_route_map(\n    root_node: RouteTrieNode,\n    path: str,\n) -> tuple[RouteTrieNode, list[str], str]:\n    \"\"\"Traverses the application route mapping and retrieves the correct node for the request url.\n\n    Args:\n        root_node: The root trie node.\n        path: The request's path.\n\n    Raises:\n        NotFoundException: If no correlating node is found.\n\n    Returns:\n        A tuple containing the target RouteMapNode and a list containing all path parameter values.\n    \"\"\"\n    current_node = root_node\n    path_params: list[str] = []\n    path_components = [p for p in path.split(\"/\") if p]\n\n    for i, component in enumerate(path_components):\n        if component in current_node.child_keys:\n            current_node = current_node.children[component]\n            continue\n\n        if current_node.is_path_param_node:\n            current_node = current_node.children[PathParameterSentinel]\n\n            if current_node.is_path_type:\n                path_params.append(normalize_path(\"/\".join(path_components[i:])))\n                break\n\n            path_params.append(component)\n            continue\n\n        raise NotFoundException()\n\n    if not current_node.asgi_handlers:\n        raise NotFoundException()\n\n    return current_node, path_params, path\n\n\ndef parse_node_handlers(\n    node: RouteTrieNode,\n    method: Method | None,\n) -> ASGIHandlerTuple:\n    \"\"\"Retrieve the handler tuple from the node.\n\n    Args:\n        node: The trie node to parse.\n        method: The scope's method.\n\n    Raises:\n        KeyError: If no matching method is found.\n\n    Returns:\n        An ASGI Handler tuple.\n    \"\"\"\n\n    if node.is_asgi:\n        return node.asgi_handlers[\"asgi\"]\n    if method:\n        return node.asgi_handlers[method]\n    return node.asgi_handlers[\"websocket\"]\n\n\n@lru_cache(1024)\ndef parse_path_params(\n    parameter_definitions: tuple[PathParameterDefinition, ...], path_param_values: tuple[str, ...]\n) -> dict[str, Any]:\n    \"\"\"Parse path parameters into a dictionary of values.\n\n    Args:\n        parameter_definitions: The parameter definitions tuple from the route.\n        path_param_values: The string values extracted from the url\n\n    Raises:\n        ValueError: If any of path parameters can not be parsed into a value.\n\n    Returns:\n        A dictionary of parsed path parameters.\n    \"\"\"\n    return {\n        param_definition.name: param_definition.parser(value) if param_definition.parser else value\n        for param_definition, value in zip(parameter_definitions, path_param_values)\n    }\n\n\ndef parse_path_to_route(\n    method: Method | None,\n    mount_paths_regex: Pattern | None,\n    mount_routes: dict[str, RouteTrieNode],\n    path: str,\n    plain_routes: set[str],\n    root_node: RouteTrieNode,\n) -> tuple[ASGIApp, RouteHandlerType, str, dict[str, Any]]:\n    \"\"\"Given a scope object, retrieve the asgi_handlers and is_mount boolean values from correct trie node.\n\n    Args:\n        method: The scope's method, if any.\n        root_node: The root trie node.\n        path: The path to resolve scope instance.\n        plain_routes: The set of plain routes.\n        mount_routes: Mapping of mount routes to trie nodes.\n        mount_paths_regex: A compiled regex to match the mount routes.\n\n    Raises:\n        MethodNotAllowedException: if no matching method is found.\n        NotFoundException: If no correlating node is found or if path params can not be parsed into values according to the node definition.\n\n    Returns:\n        A tuple containing the stack of middlewares and the route handler that is wrapped by it.\n    \"\"\"\n\n    try:\n        if path in plain_routes:\n            asgi_app, handler = parse_node_handlers(node=root_node.children[path], method=method)\n            return asgi_app, handler, path, {}\n\n        if mount_paths_regex and (match := mount_paths_regex.search(path)):\n            mount_path = path[match.start() : match.end()]\n            mount_node = mount_routes[mount_path]\n            remaining_path = path[match.end() :]\n            # since we allow regular handlers under static paths, we must validate that the request does not match\n            # any such handler.\n            children = (\n                normalize_path(sub_route)\n                for sub_route in mount_node.children or []\n                if sub_route != mount_path and isinstance(sub_route, str)\n            )\n            if not any(remaining_path.startswith(f\"{sub_route}/\") for sub_route in children):\n                asgi_app, handler = parse_node_handlers(node=mount_node, method=method)\n                remaining_path = remaining_path or \"/\"\n                if not mount_node.is_static:\n                    remaining_path = remaining_path if remaining_path.endswith(\"/\") else f\"{remaining_path}/\"\n                return asgi_app, handler, remaining_path, {}\n\n        node, path_parameters, path = traverse_route_map(\n            root_node=root_node,\n            path=path,\n        )\n        asgi_app, handler = parse_node_handlers(node=node, method=method)\n        key = method or (\"asgi\" if node.is_asgi else \"websocket\")\n        parsed_path_parameters = parse_path_params(node.path_parameters[key], tuple(path_parameters))\n\n        return (\n            asgi_app,\n            handler,\n            path,\n            parsed_path_parameters,\n        )\n    except KeyError as e:\n        raise MethodNotAllowedException() from e\n    except ValueError as e:\n        raise NotFoundException() from e\n", "path": "litestar/_asgi/routing_trie/traversal.py"}], "after_files": [{"content": "from __future__ import annotations\n\nfrom functools import lru_cache\nfrom typing import TYPE_CHECKING, Any, Pattern\n\nfrom litestar._asgi.routing_trie.types import PathParameterSentinel\nfrom litestar.exceptions import MethodNotAllowedException, NotFoundException\nfrom litestar.utils import normalize_path\n\n__all__ = (\"parse_node_handlers\", \"parse_path_params\", \"parse_path_to_route\", \"traverse_route_map\")\n\n\nif TYPE_CHECKING:\n    from litestar._asgi.routing_trie.types import ASGIHandlerTuple, RouteTrieNode\n    from litestar.types import ASGIApp, Method, RouteHandlerType\n    from litestar.types.internal_types import PathParameterDefinition\n\n\ndef traverse_route_map(\n    root_node: RouteTrieNode,\n    path: str,\n) -> tuple[RouteTrieNode, list[str], str]:\n    \"\"\"Traverses the application route mapping and retrieves the correct node for the request url.\n\n    Args:\n        root_node: The root trie node.\n        path: The request's path.\n\n    Raises:\n        NotFoundException: If no correlating node is found.\n\n    Returns:\n        A tuple containing the target RouteMapNode and a list containing all path parameter values.\n    \"\"\"\n    current_node = root_node\n    path_params: list[str] = []\n    path_components = [p for p in path.split(\"/\") if p]\n\n    for i, component in enumerate(path_components):\n        if component in current_node.child_keys:\n            current_node = current_node.children[component]\n            continue\n\n        if current_node.is_path_param_node:\n            current_node = current_node.children[PathParameterSentinel]\n\n            if current_node.is_path_type:\n                path_params.append(normalize_path(\"/\".join(path_components[i:])))\n                break\n\n            path_params.append(component)\n            continue\n\n        raise NotFoundException()\n\n    if not current_node.asgi_handlers:\n        raise NotFoundException()\n\n    return current_node, path_params, path\n\n\ndef parse_node_handlers(\n    node: RouteTrieNode,\n    method: Method | None,\n) -> ASGIHandlerTuple:\n    \"\"\"Retrieve the handler tuple from the node.\n\n    Args:\n        node: The trie node to parse.\n        method: The scope's method.\n\n    Raises:\n        KeyError: If no matching method is found.\n\n    Returns:\n        An ASGI Handler tuple.\n    \"\"\"\n\n    if node.is_asgi:\n        return node.asgi_handlers[\"asgi\"]\n    if method:\n        return node.asgi_handlers[method]\n    return node.asgi_handlers[\"websocket\"]\n\n\n@lru_cache(1024)\ndef parse_path_params(\n    parameter_definitions: tuple[PathParameterDefinition, ...], path_param_values: tuple[str, ...]\n) -> dict[str, Any]:\n    \"\"\"Parse path parameters into a dictionary of values.\n\n    Args:\n        parameter_definitions: The parameter definitions tuple from the route.\n        path_param_values: The string values extracted from the url\n\n    Raises:\n        ValueError: If any of path parameters can not be parsed into a value.\n\n    Returns:\n        A dictionary of parsed path parameters.\n    \"\"\"\n    return {\n        param_definition.name: param_definition.parser(value) if param_definition.parser else value\n        for param_definition, value in zip(parameter_definitions, path_param_values)\n    }\n\n\ndef parse_path_to_route(\n    method: Method | None,\n    mount_paths_regex: Pattern | None,\n    mount_routes: dict[str, RouteTrieNode],\n    path: str,\n    plain_routes: set[str],\n    root_node: RouteTrieNode,\n) -> tuple[ASGIApp, RouteHandlerType, str, dict[str, Any]]:\n    \"\"\"Given a scope object, retrieve the asgi_handlers and is_mount boolean values from correct trie node.\n\n    Args:\n        method: The scope's method, if any.\n        root_node: The root trie node.\n        path: The path to resolve scope instance.\n        plain_routes: The set of plain routes.\n        mount_routes: Mapping of mount routes to trie nodes.\n        mount_paths_regex: A compiled regex to match the mount routes.\n\n    Raises:\n        MethodNotAllowedException: if no matching method is found.\n        NotFoundException: If no correlating node is found or if path params can not be parsed into values according to the node definition.\n\n    Returns:\n        A tuple containing the stack of middlewares and the route handler that is wrapped by it.\n    \"\"\"\n\n    try:\n        if path in plain_routes:\n            asgi_app, handler = parse_node_handlers(node=root_node.children[path], method=method)\n            return asgi_app, handler, path, {}\n\n        if mount_paths_regex and (match := mount_paths_regex.match(path)):\n            mount_path = path[: match.end()]\n            mount_node = mount_routes[mount_path]\n            remaining_path = path[match.end() :]\n            # since we allow regular handlers under static paths, we must validate that the request does not match\n            # any such handler.\n            children = (\n                normalize_path(sub_route)\n                for sub_route in mount_node.children or []\n                if sub_route != mount_path and isinstance(sub_route, str)\n            )\n            if not any(remaining_path.startswith(f\"{sub_route}/\") for sub_route in children):\n                asgi_app, handler = parse_node_handlers(node=mount_node, method=method)\n                remaining_path = remaining_path or \"/\"\n                if not mount_node.is_static:\n                    remaining_path = remaining_path if remaining_path.endswith(\"/\") else f\"{remaining_path}/\"\n                return asgi_app, handler, remaining_path, {}\n\n        node, path_parameters, path = traverse_route_map(\n            root_node=root_node,\n            path=path,\n        )\n        asgi_app, handler = parse_node_handlers(node=node, method=method)\n        key = method or (\"asgi\" if node.is_asgi else \"websocket\")\n        parsed_path_parameters = parse_path_params(node.path_parameters[key], tuple(path_parameters))\n\n        return (\n            asgi_app,\n            handler,\n            path,\n            parsed_path_parameters,\n        )\n    except KeyError as e:\n        raise MethodNotAllowedException() from e\n    except ValueError as e:\n        raise NotFoundException() from e\n", "path": "litestar/_asgi/routing_trie/traversal.py"}]}