codecov-io: ## [Current coverage](https://codecov.io/gh/falconry/falcon/pull/889?src=pr) is 99.89% (diff: 100%)
> Merging [#889](https://codecov.io/gh/falconry/falcon/pull/889?src=pr) into [master](https://codecov.io/gh/falconry/falcon/branch/master?src=pr) will decrease coverage by **0.10%**

```diff
@@           master       #889   diff @@
========================================
  Files          30         30          
  Lines        1897       1905     +8   
  Methods         0          0          
  Messages        0          0          
  Branches      314        314          
========================================
+ Hits         1897       1903     +6   
- Misses          0          2     +2   
  Partials        0          0          
```

> Powered by [Codecov](https://codecov.io?src=pr). Last update [d9d1aed...c8c3ac0](https://codecov.io/gh/falconry/falcon/compare/d9d1aed01ef5e85d3164bd0e6b83f52293647c58...c8c3ac08eac979f469330a6b0baf593526c24106?src=pr)
jmvrbanac: :+1: 
fxfitz: LGTM2!!! 
diff --git a/docs/api/routing.rst b/docs/api/routing.rst
index c0ce2d2..f579920 100644
--- a/docs/api/routing.rst
+++ b/docs/api/routing.rst
@@ -24,14 +24,15 @@ A custom router is any class that implements the following interface:
             """
 
         def find(self, uri):
-            """Search for a route that matches the given URI.
+            """Search for a route that matches the given partial URI.
 
             Args:
-                uri (str): Request URI to match to a route.
+                uri(str): The requested path to route
 
             Returns:
-                tuple: A 3-member tuple composed of (resource, method_map, params)
-                    or ``None`` if no route is found.
+                tuple: A 4-member tuple composed of (resource, method_map,
+                    params, uri_template), or ``None`` if no route matches
+                    the requested path
             """
 
 A custom routing engine may be specified when instantiating
diff --git a/falcon/api.py b/falcon/api.py
index e1e985a..8d62173 100644
--- a/falcon/api.py
+++ b/falcon/api.py
@@ -189,7 +189,7 @@ class API(object):
                 # next-hop child resource. In that case, the object
                 # being asked to dispatch to its child will raise an
                 # HTTP exception signalling the problem, e.g. a 404.
-                responder, params, resource = self._get_responder(req)
+                responder, params, resource, req.uri_template = self._get_responder(req)
             except Exception as ex:
                 if not self._handle_exception(ex, req, resp, params):
                     raise
@@ -508,11 +508,18 @@ class API(object):
 
         path = req.path
         method = req.method
+        uri_template = None
 
         route = self._router.find(path)
 
         if route is not None:
-            resource, method_map, params = route
+            try:
+                resource, method_map, params, uri_template = route
+            except ValueError:
+                # NOTE(kgriffs): Older routers may not return the
+                # template. But for performance reasons they should at
+                # least return None if they don't support it.
+                resource, method_map, params = route
         else:
             # NOTE(kgriffs): Older routers may indicate that no route
             # was found by returning (None, None, None). Therefore, we
@@ -538,7 +545,7 @@ class API(object):
             else:
                 responder = falcon.responders.path_not_found
 
-        return (responder, params, resource)
+        return (responder, params, resource, uri_template)
 
     def _compose_status_response(self, req, resp, http_status):
         """Composes a response for the given HTTPStatus instance."""
diff --git a/falcon/request.py b/falcon/request.py
index b063321..851898c 100644
--- a/falcon/request.py
+++ b/falcon/request.py
@@ -68,6 +68,8 @@ class Request(object):
     Args:
         env (dict): A WSGI environment dict passed in from the server. See
             also PEP-3333.
+
+    Keyword Arguments
         options (dict): Set of global options passed from the API handler.
 
     Attributes:
@@ -140,7 +142,6 @@ class Request(object):
                 opposed to a class), the function is called like a method of
                 the current Request instance. Therefore the first argument is
                 the Request instance itself (self).
-
         uri (str): The fully-qualified URI for the request.
         url (str): alias for `uri`.
         relative_uri (str): The path + query string portion of the full URI.
@@ -148,6 +149,13 @@ class Request(object):
             string).
         query_string (str): Query string portion of the request URL, without
             the preceding '?' character.
+        uri_template (str): The template for the route that was matched for
+            this request. May be ``None`` if the request has not yet been
+            routed, as would be the case for `process_request()` middleware
+            methods. May also be ``None`` if your app uses a custom routing
+            engine and the engine does not provide the URI template when
+            resolving a route.
+
         user_agent (str): Value of the User-Agent header, or ``None`` if the
             header is missing.
         accept (str): Value of the Accept header, or '*/*' if the header is
@@ -244,6 +252,7 @@ class Request(object):
         '_cookies',
         '_cached_access_route',
         '__dict__',
+        'uri_template',
     )
 
     # Child classes may override this
@@ -259,6 +268,8 @@ class Request(object):
         self.stream = env['wsgi.input']
         self.method = env['REQUEST_METHOD']
 
+        self.uri_template = None
+
         # Normalize path
         path = env['PATH_INFO']
         if path:
diff --git a/falcon/routing/compiled.py b/falcon/routing/compiled.py
index 395dc72..32becd8 100644
--- a/falcon/routing/compiled.py
+++ b/falcon/routing/compiled.py
@@ -43,7 +43,15 @@ class CompiledRouter(object):
         self._return_values = None
 
     def add_route(self, uri_template, method_map, resource):
-        """Adds a route between URI path template and resource."""
+        """Adds a route between a URI path template and a resource.
+
+        Args:
+            uri_template (str): A URI template to use for the route
+            method_map (dict): A mapping of HTTP methods (e.g., 'GET',
+                'POST') to methods of a resource object.
+            resource (object): The resource instance to associate with
+                the URI template.
+        """
 
         if re.search('\s', uri_template):
             raise ValueError('URI templates may not include whitespace.')
@@ -67,6 +75,7 @@ class CompiledRouter(object):
                         # NOTE(kgriffs): Override previous node
                         node.method_map = method_map
                         node.resource = resource
+                        node.uri_template = uri_template
                     else:
                         insert(node.children, path_index)
 
@@ -85,6 +94,7 @@ class CompiledRouter(object):
             if path_index == len(path) - 1:
                 new_node.method_map = method_map
                 new_node.resource = resource
+                new_node.uri_template = uri_template
             else:
                 insert(new_node.children, path_index + 1)
 
@@ -92,13 +102,23 @@ class CompiledRouter(object):
         self._find = self._compile()
 
     def find(self, uri):
-        """Finds resource and method map for a URI, or returns None."""
+        """Search for a route that matches the given partial URI.
+
+        Args:
+            uri(str): The requested path to route
+
+        Returns:
+            tuple: A 4-member tuple composed of (resource, method_map,
+                params, uri_template), or ``None`` if no route matches
+                the requested path
+        """
+
         path = uri.lstrip('/').split('/')
         params = {}
         node = self._find(path, self._return_values, self._expressions, params)
 
         if node is not None:
-            return node.resource, node.method_map, params
+            return node.resource, node.method_map, params, node.uri_template
         else:
             return None
 
@@ -234,12 +254,14 @@ class CompiledRouterNode(object):
 
     _regex_vars = re.compile('{([-_a-zA-Z0-9]+)}')
 
-    def __init__(self, raw_segment, method_map=None, resource=None):
+    def __init__(self, raw_segment,
+                 method_map=None, resource=None, uri_template=None):
         self.children = []
 
         self.raw_segment = raw_segment
         self.method_map = method_map
         self.resource = resource
+        self.uri_template = uri_template
 
         self.is_var = False
         self.is_complex = False

Expose routing metadata
Per a [discussion][1] on the mailing list, it can be useful to introspect the URI template that is associated with a given resource. One way to implement this would be to check for an attribute and fill it in as part of the `add_route` logic. For example:

```python
class Thing(object):
    def __init__(self):
        self.uri_templates = []

    def on_get(self, req, resp):
        pass

# ...

def add_route(self, uri_template, resource):

    # ...

    if hasattr(resource, 'uri_templates'):
        resource.uri_templates.append(uri_template)

    # ...
``` 

We could also do this:

```python
    if hasattr(resource, 'uri_templates'):
        resource.uri_templates.append(uri_template)
    else:
        resource.uri_templates = [uri_template]
```

But that would break in the case that `Thing` defined `__slots__`.

Another option would be to store the URI template in the routing tree and then set an attribute on each Request instance:

```python
def __call__(self, env, start_response):

    # ...

    responder, params, resource, uri_template = self._get_responder(req)
    
    req = self._request_type(env, options=self.req_options, 
                             uri_template=uri_template)

    # ...
```

Either way, this would provide a way for middleware and hooks to key off the URI template to perform additional actions.

[1]: http://librelist.com/browser//falcon/2015/7/28/getting-the-url-template-when-servicing-a-request/
diff --git a/tests/test_custom_router.py b/tests/test_custom_router.py
index cbe1b48..c425ea8 100644
--- a/tests/test_custom_router.py
+++ b/tests/test_custom_router.py
@@ -21,14 +21,20 @@ class TestCustomRouter(testing.TestBase):
     def test_custom_router_find_should_be_used(self):
 
         def resource(req, resp, **kwargs):
-            resp.body = '{"status": "ok"}'
+            resp.body = '{{"uri_template": "{0}"}}'.format(req.uri_template)
 
         class CustomRouter(object):
             def __init__(self):
                 self.reached_backwards_compat = False
 
             def find(self, uri):
-                if uri == '/test':
+                if uri == '/test/42':
+                    return resource, {'GET': resource}, {}, '/test/{id}'
+
+                if uri == '/test/42/no-uri-template':
+                    return resource, {'GET': resource}, {}, None
+
+                if uri == '/test/42/uri-template/backwards-compat':
                     return resource, {'GET': resource}, {}
 
                 if uri == '/404/backwards-compat':
@@ -39,8 +45,14 @@ class TestCustomRouter(testing.TestBase):
 
         router = CustomRouter()
         self.api = falcon.API(router=router)
-        body = self.simulate_request('/test')
-        self.assertEqual(body, [b'{"status": "ok"}'])
+        body = self.simulate_request('/test/42')
+        self.assertEqual(body, [b'{"uri_template": "/test/{id}"}'])
+
+        body = self.simulate_request('/test/42/no-uri-template')
+        self.assertEqual(body, [b'{"uri_template": "None"}'])
+
+        body = self.simulate_request('/test/42/uri-template/backwards-compat')
+        self.assertEqual(body, [b'{"uri_template": "None"}'])
 
         for uri in ('/404', '/404/backwards-compat'):
             body = self.simulate_request(uri)
diff --git a/tests/test_default_router.py b/tests/test_default_router.py
index 9f3c6d5..28ee2e5 100644
--- a/tests/test_default_router.py
+++ b/tests/test_default_router.py
@@ -24,18 +24,18 @@ class TestRegressionCases(testing.TestBase):
     def test_versioned_url(self):
         self.router.add_route('/{version}/messages', {}, ResourceWithId(2))
 
-        resource, method_map, params = self.router.find('/v2/messages')
+        resource, __, __, __ = self.router.find('/v2/messages')
         self.assertEqual(resource.resource_id, 2)
 
         self.router.add_route('/v2', {}, ResourceWithId(1))
 
-        resource, method_map, params = self.router.find('/v2')
+        resource, __, __, __ = self.router.find('/v2')
         self.assertEqual(resource.resource_id, 1)
 
-        resource, method_map, params = self.router.find('/v2/messages')
+        resource, __, __, __ = self.router.find('/v2/messages')
         self.assertEqual(resource.resource_id, 2)
 
-        resource, method_map, params = self.router.find('/v1/messages')
+        resource, __, __, __ = self.router.find('/v1/messages')
         self.assertEqual(resource.resource_id, 2)
 
         route = self.router.find('/v1')
@@ -47,10 +47,10 @@ class TestRegressionCases(testing.TestBase):
         self.router.add_route(
             '/recipes/baking', {}, ResourceWithId(2))
 
-        resource, method_map, params = self.router.find('/recipes/baking/4242')
+        resource, __, __, __ = self.router.find('/recipes/baking/4242')
         self.assertEqual(resource.resource_id, 1)
 
-        resource, method_map, params = self.router.find('/recipes/baking')
+        resource, __, __, __ = self.router.find('/recipes/baking')
         self.assertEqual(resource.resource_id, 2)
 
         route = self.router.find('/recipes/grilling')
@@ -165,20 +165,20 @@ class TestComplexRouting(testing.TestBase):
     def test_override(self):
         self.router.add_route('/emojis/signs/0', {}, ResourceWithId(-1))
 
-        resource, method_map, params = self.router.find('/emojis/signs/0')
+        resource, __, __, __ = self.router.find('/emojis/signs/0')
         self.assertEqual(resource.resource_id, -1)
 
     def test_literal_segment(self):
-        resource, method_map, params = self.router.find('/emojis/signs/0')
+        resource, __, __, __ = self.router.find('/emojis/signs/0')
         self.assertEqual(resource.resource_id, 12)
 
-        resource, method_map, params = self.router.find('/emojis/signs/1')
+        resource, __, __, __ = self.router.find('/emojis/signs/1')
         self.assertEqual(resource.resource_id, 13)
 
-        resource, method_map, params = self.router.find('/emojis/signs/42')
+        resource, __, __, __ = self.router.find('/emojis/signs/42')
         self.assertEqual(resource.resource_id, 14)
 
-        resource, method_map, params = self.router.find('/emojis/signs/42/small')
+        resource, __, __, __ = self.router.find('/emojis/signs/42/small')
         self.assertEqual(resource.resource_id, 14.1)
 
         route = self.router.find('/emojis/signs/1/small')
@@ -204,18 +204,18 @@ class TestComplexRouting(testing.TestBase):
         self.assertIs(route, None)
 
     def test_literal(self):
-        resource, method_map, params = self.router.find('/user/memberships')
+        resource, __, __, __ = self.router.find('/user/memberships')
         self.assertEqual(resource.resource_id, 8)
 
     def test_variable(self):
-        resource, method_map, params = self.router.find('/teams/42')
+        resource, __, params, __ = self.router.find('/teams/42')
         self.assertEqual(resource.resource_id, 6)
         self.assertEqual(params, {'id': '42'})
 
-        resource, method_map, params = self.router.find('/emojis/signs/stop')
+        __, __, params, __ = self.router.find('/emojis/signs/stop')
         self.assertEqual(params, {'id': 'stop'})
 
-        resource, method_map, params = self.router.find('/gists/42/raw')
+        __, __, params, __ = self.router.find('/gists/42/raw')
         self.assertEqual(params, {'id': '42'})
 
     @ddt.data(
@@ -232,7 +232,7 @@ class TestComplexRouting(testing.TestBase):
     )
     @ddt.unpack
     def test_literal_vs_variable(self, path, expected_id):
-        resource, method_map, params = self.router.find(path)
+        resource, __, __, __ = self.router.find(path)
         self.assertEqual(resource.resource_id, expected_id)
 
     @ddt.data(
@@ -271,12 +271,12 @@ class TestComplexRouting(testing.TestBase):
         self.assertIs(route, None)
 
     def test_multivar(self):
-        resource, method_map, params = self.router.find(
+        resource, __, params, __ = self.router.find(
             '/repos/racker/falcon/commits')
         self.assertEqual(resource.resource_id, 4)
         self.assertEqual(params, {'org': 'racker', 'repo': 'falcon'})
 
-        resource, method_map, params = self.router.find(
+        resource, __, params, __ = self.router.find(
             '/repos/racker/falcon/compare/all')
         self.assertEqual(resource.resource_id, 11)
         self.assertEqual(params, {'org': 'racker', 'repo': 'falcon'})
@@ -285,7 +285,7 @@ class TestComplexRouting(testing.TestBase):
     @ddt.unpack
     def test_complex(self, url_postfix, resource_id):
         uri = '/repos/racker/falcon/compare/johndoe:master...janedoe:dev'
-        resource, method_map, params = self.router.find(uri + url_postfix)
+        resource, __, params, __ = self.router.find(uri + url_postfix)
 
         self.assertEqual(resource.resource_id, resource_id)
         self.assertEqual(params, {
@@ -297,11 +297,14 @@ class TestComplexRouting(testing.TestBase):
             'branch1': 'dev',
         })
 
-    @ddt.data(('', 16), ('/full', 17))
+    @ddt.data(
+        ('', 16, '/repos/{org}/{repo}/compare/{usr0}:{branch0}'),
+        ('/full', 17, '/repos/{org}/{repo}/compare/{usr0}:{branch0}/full')
+    )
     @ddt.unpack
-    def test_complex_alt(self, url_postfix, resource_id):
-        uri = '/repos/falconry/falcon/compare/johndoe:master'
-        resource, method_map, params = self.router.find(uri + url_postfix)
+    def test_complex_alt(self, url_postfix, resource_id, expected_template):
+        uri = '/repos/falconry/falcon/compare/johndoe:master' + url_postfix
+        resource, __, params, uri_template = self.router.find(uri)
 
         self.assertEqual(resource.resource_id, resource_id)
         self.assertEqual(params, {
@@ -310,3 +313,4 @@ class TestComplexRouting(testing.TestBase):
             'usr0': 'johndoe',
             'branch0': 'master',
         })
+        self.assertEqual(uri_template, expected_template)

pip install -e .
parse_log_pytest
requirements.txt
pytest pytest-cov
apt-get update apt-get install -y gcc
3.9
tools/test-requires
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
certifi==2025.1.31
charset-normalizer==3.4.1
coverage==7.8.0
ddt==1.7.2
exceptiongroup==1.2.2
-e git+https://github.com/falconry/falcon.git@18beacf2a84720d5c4de071122eeba3fe5a7f83f#egg=falcon
idna==3.10
iniconfig==2.1.0
packaging==24.2
pluggy==1.5.0
pytest==8.3.5
pytest-cov==6.0.0
python-mimeparse==2.0.0
PyYAML==6.0.2
requests==2.32.3
six==1.17.0
testtools==2.7.2
tomli==2.2.1
urllib3==2.3.0

name: falcon
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - certifi==2025.1.31
      - charset-normalizer==3.4.1
      - coverage==7.8.0
      - ddt==1.7.2
      - exceptiongroup==1.2.2
      - idna==3.10
      - iniconfig==2.1.0
      - packaging==24.2
      - pluggy==1.5.0
      - pytest==8.3.5
      - pytest-cov==6.0.0
      - python-mimeparse==2.0.0
      - pyyaml==6.0.2
      - requests==2.32.3
      - six==1.17.0
      - testtools==2.7.2
      - tomli==2.2.1
      - urllib3==2.3.0
prefix: /opt/conda/envs/falcon

tests/test_custom_router.py::TestCustomRouter::test_custom_router_find_should_be_used tests/test_default_router.py::TestRegressionCases::test_recipes tests/test_default_router.py::TestRegressionCases::test_versioned_url tests/test_default_router.py::TestComplexRouting::test_complex_1______5_ tests/test_default_router.py::TestComplexRouting::test_complex_2____full___10_ tests/test_default_router.py::TestComplexRouting::test_complex_3____part___15_ tests/test_default_router.py::TestComplexRouting::test_complex_alt_1______16____repos__org___repo__compare__usr0___branch0___ tests/test_default_router.py::TestComplexRouting::test_complex_alt_2____full___17____repos__org___repo__compare__usr0___branch0__full__ tests/test_default_router.py::TestComplexRouting::test_literal tests/test_default_router.py::TestComplexRouting::test_literal_segment tests/test_default_router.py::TestComplexRouting::test_literal_vs_variable_01____teams_default___19_ tests/test_default_router.py::TestComplexRouting::test_literal_vs_variable_02____teams_default_members___7_ tests/test_default_router.py::TestComplexRouting::test_literal_vs_variable_03____teams_foo___6_ tests/test_default_router.py::TestComplexRouting::test_literal_vs_variable_04____teams_foo_members___7_ tests/test_default_router.py::TestComplexRouting::test_literal_vs_variable_05____gists_first___20_ tests/test_default_router.py::TestComplexRouting::test_literal_vs_variable_06____gists_first_raw___18_ tests/test_default_router.py::TestComplexRouting::test_literal_vs_variable_07____gists_first_pdf___21_ tests/test_default_router.py::TestComplexRouting::test_literal_vs_variable_08____gists_1776_pdf___21_ tests/test_default_router.py::TestComplexRouting::test_literal_vs_variable_09____emojis_signs_78___13_ tests/test_default_router.py::TestComplexRouting::test_literal_vs_variable_10____emojis_signs_78_small___22_ tests/test_default_router.py::TestComplexRouting::test_multivar tests/test_default_router.py::TestComplexRouting::test_override tests/test_default_router.py::TestComplexRouting::test_variable
tests/test_custom_router.py::TestCustomRouter::test_can_pass_additional_params_to_add_route tests/test_custom_router.py::TestCustomRouter::test_custom_router_add_route_should_be_used tests/test_default_router.py::TestComplexRouting::test_collision_1__teams__collision_ tests/test_default_router.py::TestComplexRouting::test_collision_2__emojis_signs__id_too_ tests/test_default_router.py::TestComplexRouting::test_collision_3__repos__org___repo__compare__complex___vs_____complex2___collision_ tests/test_default_router.py::TestComplexRouting::test_dead_segment_1__teams tests/test_default_router.py::TestComplexRouting::test_dead_segment_2__emojis_signs tests/test_default_router.py::TestComplexRouting::test_dead_segment_3__gists tests/test_default_router.py::TestComplexRouting::test_dead_segment_4__gists_42 tests/test_default_router.py::TestComplexRouting::test_dump tests/test_default_router.py::TestComplexRouting::test_invalid_field_name_1____ tests/test_default_router.py::TestComplexRouting::test_invalid_field_name_2___9v_ tests/test_default_router.py::TestComplexRouting::test_invalid_field_name_3____kgriffs_ tests/test_default_router.py::TestComplexRouting::test_invalid_field_name_4__repos__simple_thing__etc tests/test_default_router.py::TestComplexRouting::test_invalid_field_name_5__repos__or_g___repo__compare__thing_ tests/test_default_router.py::TestComplexRouting::test_invalid_field_name_6__repos__org___repo__compare___ tests/test_default_router.py::TestComplexRouting::test_invalid_field_name_7__repos__complex______thing_ tests/test_default_router.py::TestComplexRouting::test_invalid_field_name_8__repos__complex___9v___thing__etc tests/test_default_router.py::TestComplexRouting::test_malformed_pattern tests/test_default_router.py::TestComplexRouting::test_non_collision_1__repos__org___repo__compare__simple_vs_complex_ tests/test_default_router.py::TestComplexRouting::test_non_collision_2__repos__complex___vs___simple_ tests/test_default_router.py::TestComplexRouting::test_non_collision_3__repos__org___repo__compare__complex___vs_____complex2__full tests/test_default_router.py::TestComplexRouting::test_not_found_01__this_does_not_exist tests/test_default_router.py::TestComplexRouting::test_not_found_02__user_bogus tests/test_default_router.py::TestComplexRouting::test_not_found_03__repos_racker_falcon_compare_johndoe_master___janedoe_dev_bogus tests/test_default_router.py::TestComplexRouting::test_not_found_04__teams tests/test_default_router.py::TestComplexRouting::test_not_found_05__teams_42_members_undefined tests/test_default_router.py::TestComplexRouting::test_not_found_06__teams_42_undefined tests/test_default_router.py::TestComplexRouting::test_not_found_07__teams_42_undefined_segments tests/test_default_router.py::TestComplexRouting::test_not_found_08__teams_default_members_undefined tests/test_default_router.py::TestComplexRouting::test_not_found_09__teams_default_members_thing_undefined tests/test_default_router.py::TestComplexRouting::test_not_found_10__teams_default_members_thing_undefined_segments tests/test_default_router.py::TestComplexRouting::test_not_found_11__teams_default_undefined tests/test_default_router.py::TestComplexRouting::test_not_found_12__teams_default_undefined_segments tests/test_default_router.py::TestComplexRouting::test_not_found_13__emojis_signs tests/test_default_router.py::TestComplexRouting::test_not_found_14__emojis_signs_0_small tests/test_default_router.py::TestComplexRouting::test_not_found_15__emojis_signs_0_undefined tests/test_default_router.py::TestComplexRouting::test_not_found_16__emojis_signs_0_undefined_segments tests/test_default_router.py::TestComplexRouting::test_not_found_17__emojis_signs_20_small tests/test_default_router.py::TestComplexRouting::test_not_found_18__emojis_signs_20_undefined tests/test_default_router.py::TestComplexRouting::test_not_found_19__emojis_signs_42_undefined tests/test_default_router.py::TestComplexRouting::test_not_found_20__emojis_signs_78_undefined tests/test_default_router.py::TestComplexRouting::test_subsegment_not_found
docs/api/routing.rst falcon/request.py falcon/routing/compiled.py falcon/api.py
docs/api/routing.rst falcon/request.py falcon/routing/compiled.py falcon/api.py