Skip to content

Commit a017c3c

Browse files
authored
Merge pull request #463 from plowman/bugfix/missing-parse-rule
Fix #460 - missing parse_rule method
2 parents 4e7c306 + 740f7ca commit a017c3c

File tree

1 file changed

+48
-2
lines changed

1 file changed

+48
-2
lines changed

flask_restx/swagger.py

+48-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
from six import string_types, itervalues, iteritems, iterkeys
1616

1717
from flask import current_app
18-
from werkzeug.routing import parse_rule
1918

2019
from . import fields
2120
from .model import Model, ModelBase, OrderedModel
@@ -36,7 +35,6 @@
3635
"default": "string",
3736
}
3837

39-
4038
#: Maps Python primitives types to Swagger ones
4139
PY_TYPES = {
4240
int: "integer",
@@ -55,6 +53,21 @@
5553
r"^:raises\s+(?P<name>[\w\d_]+)\s*:\s*(?P<description>.*)$", re.MULTILINE
5654
)
5755

56+
RE_PARSE_RULE = re.compile(
57+
r"""
58+
(?P<static>[^<]*) # static rule data
59+
<
60+
(?:
61+
(?P<converter>[a-zA-Z_][a-zA-Z0-9_]*) # converter name
62+
(?:\((?P<args>.*?)\))? # converter arguments
63+
\: # variable delimiter
64+
)?
65+
(?P<variable>[a-zA-Z_][a-zA-Z0-9_]*) # variable name
66+
>
67+
""",
68+
re.VERBOSE,
69+
)
70+
5871

5972
def ref(model):
6073
"""Return a reference to model in definitions"""
@@ -74,6 +87,39 @@ def extract_path(path):
7487
return RE_URL.sub(r"{\1}", path)
7588

7689

90+
def parse_rule(rule):
91+
"""
92+
Parse a rule and return it as generator. Each iteration yields tuples in the form
93+
``(converter, arguments, variable)``. If the converter is `None` it's a static url part, otherwise it's a dynamic
94+
one.
95+
96+
Note: This originally lived in werkzeug.routing.parse_rule until it was removed in werkzeug 2.2.0.
97+
"""
98+
pos = 0
99+
end = len(rule)
100+
do_match = RE_PARSE_RULE.match
101+
used_names = set()
102+
while pos < end:
103+
m = do_match(rule, pos)
104+
if m is None:
105+
break
106+
data = m.groupdict()
107+
if data["static"]:
108+
yield None, None, data["static"]
109+
variable = data["variable"]
110+
converter = data["converter"] or "default"
111+
if variable in used_names:
112+
raise ValueError(f"variable name {variable!r} used twice.")
113+
used_names.add(variable)
114+
yield converter, data["args"] or None, variable
115+
pos = m.end()
116+
if pos < end:
117+
remaining = rule[pos:]
118+
if ">" in remaining or "<" in remaining:
119+
raise ValueError(f"malformed url rule: {rule!r}")
120+
yield None, None, remaining
121+
122+
77123
def extract_path_params(path):
78124
"""
79125
Extract Flask-style parameters from an URL pattern as Swagger ones.

0 commit comments

Comments
 (0)