1+ # Copyright (C) 2025
2+ # Licensed under the GPL-3.0 License.
3+ # Created for TagStudio: https://github.com/CyanVoxel/TagStudio
4+
5+
16from tagstudio .core .query_lang .ast import (
27 AST ,
38 ANDList ,
@@ -27,7 +32,7 @@ def parse(self) -> AST:
2732 if self .next_token .type == TokenType .EOF :
2833 return ORList ([])
2934 out = self .__or_list ()
30- if self .next_token .type != TokenType .EOF :
35+ if self .next_token .type != TokenType .EOF : # pyright: ignore[reportUnnecessaryComparison]
3136 raise ParsingError (self .next_token .start , self .next_token .end , "Syntax Error" )
3237 return out
3338
@@ -41,7 +46,7 @@ def __or_list(self) -> AST:
4146 return ORList (terms ) if len (terms ) > 1 else terms [0 ]
4247
4348 def __is_next_or (self ) -> bool :
44- return self .next_token .type == TokenType .ULITERAL and self .next_token .value .upper () == "OR"
49+ return self .next_token .type == TokenType .ULITERAL and self .next_token .value .upper () == "OR" # pyright: ignore
4550
4651 def __and_list (self ) -> AST :
4752 elements = [self .__term ()]
@@ -67,7 +72,7 @@ def __skip_and(self) -> None:
6772 raise self .__syntax_error ("Unexpected AND" )
6873
6974 def __is_next_and (self ) -> bool :
70- return self .next_token .type == TokenType .ULITERAL and self .next_token .value .upper () == "AND"
75+ return self .next_token .type == TokenType .ULITERAL and self .next_token .value .upper () == "AND" # pyright: ignore
7176
7277 def __term (self ) -> AST :
7378 if self .__is_next_not ():
@@ -85,11 +90,14 @@ def __term(self) -> AST:
8590 return self .__constraint ()
8691
8792 def __is_next_not (self ) -> bool :
88- return self .next_token .type == TokenType .ULITERAL and self .next_token .value .upper () == "NOT"
93+ return self .next_token .type == TokenType .ULITERAL and self .next_token .value .upper () == "NOT" # pyright: ignore
8994
9095 def __constraint (self ) -> Constraint :
9196 if self .next_token .type == TokenType .CONSTRAINTTYPE :
92- self .last_constraint_type = self .__eat (TokenType .CONSTRAINTTYPE ).value
97+ constraint = self .__eat (TokenType .CONSTRAINTTYPE ).value
98+ if not isinstance (constraint , ConstraintType ):
99+ raise self .__syntax_error ()
100+ self .last_constraint_type = constraint
93101
94102 value = self .__literal ()
95103
@@ -98,7 +106,7 @@ def __constraint(self) -> Constraint:
98106 self .__eat (TokenType .SBRACKETO )
99107 properties .append (self .__property ())
100108
101- while self .next_token .type == TokenType .COMMA :
109+ while self .next_token .type == TokenType .COMMA : # pyright: ignore[reportUnnecessaryComparison]
102110 self .__eat (TokenType .COMMA )
103111 properties .append (self .__property ())
104112
@@ -110,11 +118,16 @@ def __property(self) -> Property:
110118 key = self .__eat (TokenType .ULITERAL ).value
111119 self .__eat (TokenType .EQUALS )
112120 value = self .__literal ()
121+ if not isinstance (key , str ):
122+ raise self .__syntax_error ()
113123 return Property (key , value )
114124
115125 def __literal (self ) -> str :
116126 if self .next_token .type in [TokenType .QLITERAL , TokenType .ULITERAL ]:
117- return self .__eat (self .next_token .type ).value
127+ literal = self .__eat (self .next_token .type ).value
128+ if not isinstance (literal , str ):
129+ raise self .__syntax_error ()
130+ return literal
118131 raise self .__syntax_error ()
119132
120133 def __eat (self , type : TokenType ) -> Token :
0 commit comments