@@ -130,10 +130,22 @@ def can_advance() -> bool:
130130 yield from send_buffer ()
131131
132132
133+ class PathAction (Enum ):
134+ KEY = auto ()
135+ INDEX = auto ()
136+ APPEND = auto ()
137+
138+ # Pseudo action, used by the interpreter
139+ SET = auto ()
140+
141+ def to_string (self ) -> str :
142+ return self .name .lower ()
143+
144+
133145class Path :
134146 def __init__ (
135147 self ,
136- kind : str ,
148+ kind : PathAction ,
137149 accessor : Optional [Union [str , int ]] = None ,
138150 tokens : Optional [List [Token ]] = None ,
139151 is_root : bool = False ,
@@ -144,13 +156,13 @@ def __init__(
144156 self .is_root = is_root
145157
146158 def reconstruct (self ) -> str :
147- if self .kind == 'key' :
159+ if self .kind is PathAction . KEY :
148160 if self .is_root :
149161 return str (self .accessor )
150162 return '[' + self .accessor + ']'
151- elif self .kind == 'index' :
163+ elif self .kind is PathAction . INDEX :
152164 return '[' + str (self .accessor ) + ']'
153- elif self .kind == 'append' :
165+ elif self .kind is PathAction . APPEND :
154166 return '[]'
155167 else :
156168 assert_cant_happen ()
@@ -202,7 +214,7 @@ def expect(*kinds):
202214 message = f'Expecting { suffix } '
203215 raise HTTPieSyntaxError (source , token , message )
204216
205- root = Path ('key' , '' , is_root = True )
217+ root = Path (PathAction . KEY , '' , is_root = True )
206218 if can_advance ():
207219 token = tokens [cursor ]
208220 if token .kind in {TokenKind .TEXT , TokenKind .NUMBER }:
@@ -221,12 +233,12 @@ def expect(*kinds):
221233 )
222234 path_tokens .append (token )
223235 if token .kind is TokenKind .RIGHT_BRACKET :
224- path = Path ('append' , tokens = path_tokens )
236+ path = Path (PathAction . APPEND , tokens = path_tokens )
225237 elif token .kind is TokenKind .TEXT :
226- path = Path ('key' , token .value , tokens = path_tokens )
238+ path = Path (PathAction . KEY , token .value , tokens = path_tokens )
227239 path_tokens .append (expect (TokenKind .RIGHT_BRACKET ))
228240 elif token .kind is TokenKind .NUMBER :
229- path = Path ('index' , token .value , tokens = path_tokens )
241+ path = Path (PathAction . INDEX , token .value , tokens = path_tokens )
230242 path_tokens .append (expect (TokenKind .RIGHT_BRACKET ))
231243 else :
232244 assert_cant_happen ()
@@ -246,7 +258,7 @@ def interpret(context: Any, key: str, value: Any) -> Any:
246258 cursor = context
247259
248260 paths = list (parse (key ))
249- paths .append (Path ('set' , value ))
261+ paths .append (Path (PathAction . SET , value ))
250262
251263 def type_check (index : int , path : Path , expected_type : Type [Any ]) -> None :
252264 if not isinstance (cursor , expected_type ):
@@ -262,7 +274,7 @@ def type_check(index: int, path: Path, expected_type: Type[Any]) -> None:
262274 )
263275 required_type = JSON_TYPE_MAPPING [expected_type ]
264276
265- message = f"Can't perform { path .kind !r} based access on "
277+ message = f"Can't perform { path .kind . to_string () !r} based access on "
266278 message += repr (
267279 '' .join (path .reconstruct () for path in paths [:index ])
268280 )
@@ -275,24 +287,24 @@ def type_check(index: int, path: Path, expected_type: Type[Any]) -> None:
275287 )
276288
277289 def object_for (kind : str ) -> Any :
278- if kind == 'key' :
290+ if kind is PathAction . KEY :
279291 return {}
280- elif kind in {'index' , 'append' }:
292+ elif kind in {PathAction . INDEX , PathAction . APPEND }:
281293 return []
282294 else :
283295 assert_cant_happen ()
284296
285297 for index , (path , next_path ) in enumerate (zip (paths , paths [1 :])):
286- if path .kind == 'key' :
298+ if path .kind is PathAction . KEY :
287299 type_check (index , path , dict )
288- if next_path .kind == 'set' :
300+ if next_path .kind is PathAction . SET :
289301 cursor [path .accessor ] = next_path .accessor
290302 break
291303
292304 cursor = cursor .setdefault (
293305 path .accessor , object_for (next_path .kind )
294306 )
295- elif path .kind == 'index' :
307+ elif path .kind is PathAction . INDEX :
296308 type_check (index , path , list )
297309 if path .accessor < 0 :
298310 raise HTTPieSyntaxError (
@@ -302,17 +314,17 @@ def object_for(kind: str) -> Any:
302314 message_kind = 'Value' ,
303315 )
304316 cursor .extend ([None ] * (path .accessor - len (cursor ) + 1 ))
305- if next_path .kind == 'set' :
317+ if next_path .kind is PathAction . SET :
306318 cursor [path .accessor ] = next_path .accessor
307319 break
308320
309321 if cursor [path .accessor ] is None :
310322 cursor [path .accessor ] = object_for (next_path .kind )
311323
312324 cursor = cursor [path .accessor ]
313- elif path .kind == 'append' :
325+ elif path .kind is PathAction . APPEND :
314326 type_check (index , path , list )
315- if next_path .kind == 'set' :
327+ if next_path .kind is PathAction . SET :
316328 cursor .append (next_path .accessor )
317329 break
318330
0 commit comments