15
15
from six import string_types , itervalues , iteritems , iterkeys
16
16
17
17
from flask import current_app
18
- from werkzeug .routing import parse_rule
19
18
20
19
from . import fields
21
20
from .model import Model , ModelBase , OrderedModel
36
35
"default" : "string" ,
37
36
}
38
37
39
-
40
38
#: Maps Python primitives types to Swagger ones
41
39
PY_TYPES = {
42
40
int : "integer" ,
55
53
r"^:raises\s+(?P<name>[\w\d_]+)\s*:\s*(?P<description>.*)$" , re .MULTILINE
56
54
)
57
55
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
+
58
71
59
72
def ref (model ):
60
73
"""Return a reference to model in definitions"""
@@ -74,6 +87,39 @@ def extract_path(path):
74
87
return RE_URL .sub (r"{\1}" , path )
75
88
76
89
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
+
77
123
def extract_path_params (path ):
78
124
"""
79
125
Extract Flask-style parameters from an URL pattern as Swagger ones.
0 commit comments