1414from __future__ import annotations
1515
1616import re
17- from collections .abc import Callable
18- from typing import TYPE_CHECKING , Optional , cast
17+ from typing import TYPE_CHECKING , cast
1918
2019from cssselect .parser import (
2120 Attrib ,
3837)
3938
4039if TYPE_CHECKING :
40+ from collections .abc import Callable
41+
4142 # typing.Self requires Python 3.11
4243 from typing_extensions import Self
4344
@@ -289,7 +290,7 @@ def xpath(self, parsed_selector: Tree) -> XPathExpr:
289290 """Translate any parsed selector object."""
290291 type_name = type (parsed_selector ).__name__
291292 method = cast (
292- Optional [ Callable [[Tree ], XPathExpr ]] ,
293+ " Callable[[Tree], XPathExpr] | None" ,
293294 getattr (self , f"xpath_{ type_name .lower ()} " , None ),
294295 )
295296 if method is None :
@@ -302,7 +303,7 @@ def xpath_combinedselector(self, combined: CombinedSelector) -> XPathExpr:
302303 """Translate a combined selector."""
303304 combinator = self .combinator_mapping [combined .combinator ]
304305 method = cast (
305- Callable [[XPathExpr , XPathExpr ], XPathExpr ],
306+ " Callable[[XPathExpr, XPathExpr], XPathExpr]" ,
306307 getattr (self , f"xpath_{ combinator } _combinator" ),
307308 )
308309 return method (self .xpath (combined .selector ), self .xpath (combined .subselector ))
@@ -321,10 +322,10 @@ def xpath_relation(self, relation: Relation) -> XPathExpr:
321322 subselector = relation .subselector
322323 right = self .xpath (subselector .parsed_tree )
323324 method = cast (
324- Callable [[XPathExpr , XPathExpr ], XPathExpr ],
325+ " Callable[[XPathExpr, XPathExpr], XPathExpr]" ,
325326 getattr (
326327 self ,
327- f"xpath_relation_{ self .combinator_mapping [cast (str , combinator .value )]} _combinator" ,
328+ f"xpath_relation_{ self .combinator_mapping [cast (' str' , combinator .value )]} _combinator" ,
328329 ),
329330 )
330331 return method (xpath , right )
@@ -351,7 +352,7 @@ def xpath_function(self, function: Function) -> XPathExpr:
351352 """Translate a functional pseudo-class."""
352353 method_name = "xpath_{}_function" .format (function .name .replace ("-" , "_" ))
353354 method = cast (
354- Optional [ Callable [[XPathExpr , Function ], XPathExpr ]] ,
355+ " Callable[[XPathExpr, Function], XPathExpr] | None" ,
355356 getattr (self , method_name , None ),
356357 )
357358 if not method :
@@ -362,7 +363,8 @@ def xpath_pseudo(self, pseudo: Pseudo) -> XPathExpr:
362363 """Translate a pseudo-class."""
363364 method_name = "xpath_{}_pseudo" .format (pseudo .ident .replace ("-" , "_" ))
364365 method = cast (
365- Optional [Callable [[XPathExpr ], XPathExpr ]], getattr (self , method_name , None )
366+ "Callable[[XPathExpr], XPathExpr] | None" ,
367+ getattr (self , method_name , None ),
366368 )
367369 if not method :
368370 # TODO: better error message for pseudo-elements?
@@ -373,7 +375,7 @@ def xpath_attrib(self, selector: Attrib) -> XPathExpr:
373375 """Translate an attribute selector."""
374376 operator = self .attribute_operator_mapping [selector .operator ]
375377 method = cast (
376- Callable [[XPathExpr , str , Optional [ str ]] , XPathExpr ],
378+ " Callable[[XPathExpr, str, str | None] , XPathExpr]" ,
377379 getattr (self , f"xpath_attrib_{ operator } " ),
378380 )
379381 if self .lower_case_attribute_names :
@@ -391,7 +393,7 @@ def xpath_attrib(self, selector: Attrib) -> XPathExpr:
391393 if selector .value is None :
392394 value = None
393395 elif self .lower_case_attribute_values :
394- value = cast (str , selector .value .value ).lower ()
396+ value = cast (" str" , selector .value .value ).lower ()
395397 else :
396398 value = selector .value .value
397399 return method (self .xpath (selector .selector ), attrib , value )
@@ -645,15 +647,15 @@ def xpath_contains_function(
645647 raise ExpressionError (
646648 f"Expected a single string or ident for :contains(), got { function .arguments !r} "
647649 )
648- value = cast (str , function .arguments [0 ].value )
650+ value = cast (" str" , function .arguments [0 ].value )
649651 return xpath .add_condition (f"contains(., { self .xpath_literal (value )} )" )
650652
651653 def xpath_lang_function (self , xpath : XPathExpr , function : Function ) -> XPathExpr :
652654 if function .argument_types () not in (["STRING" ], ["IDENT" ]):
653655 raise ExpressionError (
654656 f"Expected a single string or ident for :lang(), got { function .arguments !r} "
655657 )
656- value = cast (str , function .arguments [0 ].value )
658+ value = cast (" str" , function .arguments [0 ].value )
657659 return xpath .add_condition (f"lang({ self .xpath_literal (value )} )" )
658660
659661 # Pseudo: dispatch by pseudo-class name
0 commit comments