4040# Default patterns for name types that do not have styles 
4141DEFAULT_PATTERNS  =  {
4242    "typevar" : re .compile (
43-         r"^_{0,2}(?!T[A-Z])(?:[A-Z]+|(?:[A-Z]+[a-z]+)+T ?(?<!Type))(?:_co(?:ntra)?)?$" 
43+         r"^_{0,2}(?!T[A-Z])(?:[A-Z]+|(?:[A-Z]+[a-z]+)+(?:T) ?(?<!Type))(?:_co(?:ntra)?)?$" 
4444    ),
45+     "paramspec" : re .compile (r"^_{0,2}(?:[A-Z]+|(?:[A-Z]+[a-z]+)+(?:P)?(?<!Type))$" ),
46+     "typevartuple" : re .compile (r"^_{0,2}(?:[A-Z]+|(?:[A-Z]+[a-z]+)+(?:Ts)?(?<!Type))$" ),
4547    "typealias" : re .compile (
4648        r"^_{0,2}(?!T[A-Z]|Type)[A-Z]+[a-z0-9]+(?:[A-Z][a-z0-9]+)*$" 
4749    ),
4850}
4951
5052BUILTIN_PROPERTY  =  "builtins.property" 
51- TYPE_VAR_QNAME  =  frozenset ( 
52-     ( 
53+ TYPE_VAR_QNAMES  =  { 
54+     "typevar" : { 
5355        "typing.TypeVar" ,
5456        "typing_extensions.TypeVar" ,
55-     )
56- )
57+     },
58+     "paramspec" : {
59+         "typing.ParamSpec" ,
60+         "typing_extensions.ParamSpec" ,
61+     },
62+     "typevartuple" : {
63+         "typing.TypeVarTuple" ,
64+         "typing_extensions.TypeVarTuple" ,
65+     },
66+ }
5767
5868
5969class  TypeVarVariance (Enum ):
@@ -400,7 +410,7 @@ def visit_functiondef(self, node: nodes.FunctionDef) -> None:
400410        "typevar-double-variance" , 
401411        "typevar-name-mismatch" , 
402412    ) 
403-     def  visit_assignname (  # pylint: disable=too-many-branches 
413+     def  visit_assignname (  # pylint: disable=too-many-branches,too-many-statements  
404414        self , node : nodes .AssignName 
405415    ) ->  None :
406416        """Check module level assigned names.""" 
@@ -414,6 +424,12 @@ def visit_assignname(  # pylint: disable=too-many-branches
414424        elif  isinstance (assign_type , nodes .TypeVar ):
415425            self ._check_name ("typevar" , node .name , node )
416426
427+         elif  isinstance (assign_type , nodes .ParamSpec ):
428+             self ._check_name ("paramspec" , node .name , node )
429+ 
430+         elif  isinstance (assign_type , nodes .TypeVarTuple ):
431+             self ._check_name ("typevartuple" , node .name , node )
432+ 
417433        elif  isinstance (assign_type , nodes .TypeAlias ):
418434            self ._check_name ("typealias" , node .name , node )
419435
@@ -433,8 +449,10 @@ def visit_assignname(  # pylint: disable=too-many-branches
433449
434450                # Check TypeVar's and TypeAliases assigned alone or in tuple assignment 
435451                if  isinstance (node .parent , nodes .Assign ):
436-                     if  self ._assigns_typevar (assign_type .value ):
437-                         self ._check_name ("typevar" , assign_type .targets [0 ].name , node )
452+                     if  typevar_node_type  :=  self ._assigns_typevar (assign_type .value ):
453+                         self ._check_name (
454+                             typevar_node_type , assign_type .targets [0 ].name , node 
455+                         )
438456                        return 
439457                    if  self ._assigns_typealias (assign_type .value ):
440458                        self ._check_name ("typealias" , assign_type .targets [0 ].name , node )
@@ -447,9 +465,9 @@ def visit_assignname(  # pylint: disable=too-many-branches
447465                    and  node .parent .elts .index (node ) <  len (assign_type .value .elts )
448466                ):
449467                    assigner  =  assign_type .value .elts [node .parent .elts .index (node )]
450-                     if  self ._assigns_typevar (assigner ):
468+                     if  typevar_node_type   :=   self ._assigns_typevar (assigner ):
451469                        self ._check_name (
452-                             "typevar" ,
470+                             typevar_node_type ,
453471                            assign_type .targets [0 ]
454472                            .elts [node .parent .elts .index (node )]
455473                            .name ,
@@ -629,16 +647,16 @@ def _should_exempt_from_invalid_name(node: nodes.NodeNG) -> bool:
629647            self ._check_typevar (name , node )
630648
631649    @staticmethod  
632-     def  _assigns_typevar (node : nodes .NodeNG  |  None ) ->  bool :
633-         """Check if a node is assigning a TypeVar.""" 
650+     def  _assigns_typevar (node : nodes .NodeNG  |  None ) ->  str   |   None :
651+         """Check if a node is assigning a TypeVar and return TypeVar type .""" 
634652        if  isinstance (node , astroid .Call ):
635653            inferred  =  utils .safe_infer (node .func )
636-             if  ( 
637-                 isinstance ( inferred ,  astroid . ClassDef )
638-                 and   inferred . qname ()  in  TYPE_VAR_QNAME 
639-             ) :
640-                 return  True 
641-         return  False 
654+             if  isinstance ( inferred ,  astroid . ClassDef ): 
655+                 qname   =   inferred . qname ( )
656+                 for   typevar_node_typ ,  qnames   in  TYPE_VAR_QNAMES . items (): 
657+                      if   qname   in   qnames :
658+                          return  typevar_node_typ 
659+         return  None 
642660
643661    @staticmethod  
644662    def  _assigns_typealias (node : nodes .NodeNG  |  None ) ->  bool :
0 commit comments