Skip to content

Commit

Permalink
Merge pull request #2472 from pgjones/2.2.x
Browse files Browse the repository at this point in the history
Bugfix the calculation of weighting based on static parts
  • Loading branch information
davidism authored Jul 27, 2022
2 parents 5c85706 + 56a24f7 commit cdee5ce
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ Unreleased
slashes mode is disabled for the rule. :issue:`2467`
- Fix router so that partial part matches are not allowed
i.e. ``/2df`` does not match ``/<int>``. :pr:`2470`
- Fix router static part weighting, so that simpler routes are matched
before more complex ones. :issue:`2471`
- Restore ``ValidationError`` to be importable from
``werkzeug.routing``. :issue:`2465`

Expand Down
8 changes: 6 additions & 2 deletions src/werkzeug/routing/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -592,8 +592,12 @@ def _parse_rule(self, rule: str) -> t.Iterable[RulePart]:

data = match.groupdict()
if data["static"]:
static_weights.append((static_parts, -len(data["static"])))
static_parts += 1
# Only static parts beyond the `/` count towards the
# weighting (more static parts mean the rule should be
# weighted first).
if data["static"] != "/":
static_weights.append((static_parts, -len(data["static"])))
static_parts += 1
self._trace.append((False, data["static"]))

if data["variable"] is not None:
Expand Down
12 changes: 12 additions & 0 deletions tests/test_routing.py
Original file line number Diff line number Diff line change
Expand Up @@ -1394,6 +1394,18 @@ def test_rule_websocket_methods():
r.Rule("/ws", endpoint="ws", websocket=True, methods=["get", "head", "options"])


def test_path_weighting():
m = r.Map(
[
r.Rule("/<path:path>/c", endpoint="simple"),
r.Rule("/<path:path>/<a>/<b>", endpoint="complex"),
]
)
a = m.bind("localhost", path_info="/a/b/c")

assert a.match() == ("simple", {"path": "a/b"})


def test_newline_match():
m = r.Map([r.Rule("/hello", endpoint="hello")])
a = m.bind("localhost")
Expand Down

0 comments on commit cdee5ce

Please sign in to comment.