15
15
from typing import Dict
16
16
from typing import Iterable
17
17
from typing import List
18
+ from typing import Mapping
18
19
from typing import Optional
19
20
from typing import Set
20
21
from typing import Tuple
44
45
from _pytest .compat import STRING_TYPES
45
46
from _pytest .config import Config
46
47
from _pytest .config import ExitCode
48
+ from _pytest .compat import TYPE_CHECKING
47
49
from _pytest .config import hookimpl
48
50
from _pytest .config .argparsing import Parser
49
51
from _pytest .deprecated import FUNCARGNAMES
53
55
from _pytest .mark import ParameterSet
54
56
from _pytest .mark .structures import get_unpacked_marks
55
57
from _pytest .mark .structures import Mark
58
+ from _pytest .mark .structures import MarkDecorator
56
59
from _pytest .mark .structures import normalize_mark_list
57
60
from _pytest .outcomes import fail
58
61
from _pytest .outcomes import skip
59
62
from _pytest .pathlib import parts
60
63
from _pytest .warning_types import PytestCollectionWarning
61
64
from _pytest .warning_types import PytestUnhandledCoroutineWarning
62
65
66
+ if TYPE_CHECKING :
67
+ from typing_extensions import Literal
68
+
63
69
64
70
def pyobj_property (name ):
65
71
def get (self ):
@@ -798,16 +804,17 @@ def hasnew(obj):
798
804
799
805
800
806
class CallSpec2 :
801
- def __init__ (self , metafunc ) :
807
+ def __init__ (self , metafunc : "Metafunc" ) -> None :
802
808
self .metafunc = metafunc
803
- self .funcargs = {}
804
- self ._idlist = []
805
- self .params = {}
806
- self ._arg2scopenum = {} # used for sorting parametrized resources
807
- self .marks = []
808
- self .indices = {}
809
-
810
- def copy (self ):
809
+ self .funcargs = {} # type: Dict[str, object]
810
+ self ._idlist = [] # type: List[str]
811
+ self .params = {} # type: Dict[str, object]
812
+ # Used for sorting parametrized resources.
813
+ self ._arg2scopenum = {} # type: Dict[str, int]
814
+ self .marks = [] # type: List[Mark]
815
+ self .indices = {} # type: Dict[str, int]
816
+
817
+ def copy (self ) -> "CallSpec2" :
811
818
cs = CallSpec2 (self .metafunc )
812
819
cs .funcargs .update (self .funcargs )
813
820
cs .params .update (self .params )
@@ -817,25 +824,39 @@ def copy(self):
817
824
cs ._idlist = list (self ._idlist )
818
825
return cs
819
826
820
- def _checkargnotcontained (self , arg ) :
827
+ def _checkargnotcontained (self , arg : str ) -> None :
821
828
if arg in self .params or arg in self .funcargs :
822
829
raise ValueError ("duplicate {!r}" .format (arg ))
823
830
824
- def getparam (self , name ) :
831
+ def getparam (self , name : str ) -> object :
825
832
try :
826
833
return self .params [name ]
827
834
except KeyError :
828
835
raise ValueError (name )
829
836
830
837
@property
831
- def id (self ):
838
+ def id (self ) -> str :
832
839
return "-" .join (map (str , self ._idlist ))
833
840
834
- def setmulti2 (self , valtypes , argnames , valset , id , marks , scopenum , param_index ):
841
+ def setmulti2 (
842
+ self ,
843
+ valtypes : "Mapping[str, Literal['params', 'funcargs']]" ,
844
+ argnames : typing .Sequence [str ],
845
+ valset : Iterable [object ],
846
+ id : str ,
847
+ marks : Iterable [Union [Mark , MarkDecorator ]],
848
+ scopenum : int ,
849
+ param_index : int ,
850
+ ) -> None :
835
851
for arg , val in zip (argnames , valset ):
836
852
self ._checkargnotcontained (arg )
837
853
valtype_for_arg = valtypes [arg ]
838
- getattr (self , valtype_for_arg )[arg ] = val
854
+ if valtype_for_arg == "params" :
855
+ self .params [arg ] = val
856
+ elif valtype_for_arg == "funcargs" :
857
+ self .funcargs [arg ] = val
858
+ else : # pragma: no cover
859
+ assert False , "Unhandled valtype for arg: {}" .format (valtype_for_arg )
839
860
self .indices [arg ] = param_index
840
861
self ._arg2scopenum [arg ] = scopenum
841
862
self ._idlist .append (id )
@@ -1077,7 +1098,7 @@ def _resolve_arg_value_types(
1077
1098
self ,
1078
1099
argnames : typing .Sequence [str ],
1079
1100
indirect : Union [bool , typing .Sequence [str ]],
1080
- ) -> Dict [str , str ]:
1101
+ ) -> Dict [str , "Literal['params', 'funcargs']" ]:
1081
1102
"""Resolves if each parametrized argument must be considered a parameter to a fixture or a "funcarg"
1082
1103
to the function, based on the ``indirect`` parameter of the parametrized() call.
1083
1104
@@ -1089,7 +1110,9 @@ def _resolve_arg_value_types(
1089
1110
* "funcargs" if the argname should be a parameter to the parametrized test function.
1090
1111
"""
1091
1112
if isinstance (indirect , bool ):
1092
- valtypes = dict .fromkeys (argnames , "params" if indirect else "funcargs" )
1113
+ valtypes = dict .fromkeys (
1114
+ argnames , "params" if indirect else "funcargs"
1115
+ ) # type: Dict[str, Literal["params", "funcargs"]]
1093
1116
elif isinstance (indirect , Sequence ):
1094
1117
valtypes = dict .fromkeys (argnames , "funcargs" )
1095
1118
for arg in indirect :
0 commit comments