4
4
import inspect
5
5
import os
6
6
import sys
7
+ import typing
7
8
import warnings
8
9
from collections import Counter
9
10
from collections import defaultdict
10
11
from collections .abc import Sequence
11
12
from functools import partial
12
13
from typing import Dict
14
+ from typing import Iterable
13
15
from typing import List
16
+ from typing import Mapping
14
17
from typing import Optional
15
18
from typing import Tuple
16
19
from typing import Union
35
38
from _pytest .compat import safe_getattr
36
39
from _pytest .compat import safe_isclass
37
40
from _pytest .compat import STRING_TYPES
41
+ from _pytest .compat import TYPE_CHECKING
38
42
from _pytest .config import hookimpl
39
43
from _pytest .deprecated import FUNCARGNAMES
40
44
from _pytest .mark import MARK_GEN
41
45
from _pytest .mark import ParameterSet
42
46
from _pytest .mark .structures import get_unpacked_marks
43
47
from _pytest .mark .structures import Mark
48
+ from _pytest .mark .structures import MarkDecorator
44
49
from _pytest .mark .structures import normalize_mark_list
45
50
from _pytest .outcomes import fail
46
51
from _pytest .outcomes import skip
47
52
from _pytest .pathlib import parts
48
53
from _pytest .warning_types import PytestCollectionWarning
49
54
from _pytest .warning_types import PytestUnhandledCoroutineWarning
50
55
56
+ if TYPE_CHECKING :
57
+ from typing_extensions import Literal
58
+
51
59
52
60
def pyobj_property (name ):
53
61
def get (self ):
@@ -784,16 +792,17 @@ def hasnew(obj):
784
792
785
793
786
794
class CallSpec2 :
787
- def __init__ (self , metafunc ) :
795
+ def __init__ (self , metafunc : "Metafunc" ) -> None :
788
796
self .metafunc = metafunc
789
- self .funcargs = {}
790
- self ._idlist = []
791
- self .params = {}
792
- self ._arg2scopenum = {} # used for sorting parametrized resources
793
- self .marks = []
794
- self .indices = {}
795
-
796
- def copy (self ):
797
+ self .funcargs = {} # type: Dict[str, object]
798
+ self ._idlist = [] # type: List[str]
799
+ self .params = {} # type: Dict[str, object]
800
+ # Used for sorting parametrized resources.
801
+ self ._arg2scopenum = {} # type: Dict[str, int]
802
+ self .marks = [] # type: List[Mark]
803
+ self .indices = {} # type: Dict[str, int]
804
+
805
+ def copy (self ) -> "CallSpec2" :
797
806
cs = CallSpec2 (self .metafunc )
798
807
cs .funcargs .update (self .funcargs )
799
808
cs .params .update (self .params )
@@ -803,25 +812,39 @@ def copy(self):
803
812
cs ._idlist = list (self ._idlist )
804
813
return cs
805
814
806
- def _checkargnotcontained (self , arg ) :
815
+ def _checkargnotcontained (self , arg : str ) -> None :
807
816
if arg in self .params or arg in self .funcargs :
808
817
raise ValueError ("duplicate {!r}" .format (arg ))
809
818
810
- def getparam (self , name ) :
819
+ def getparam (self , name : str ) -> object :
811
820
try :
812
821
return self .params [name ]
813
822
except KeyError :
814
823
raise ValueError (name )
815
824
816
825
@property
817
- def id (self ):
826
+ def id (self ) -> str :
818
827
return "-" .join (map (str , self ._idlist ))
819
828
820
- def setmulti2 (self , valtypes , argnames , valset , id , marks , scopenum , param_index ):
829
+ def setmulti2 (
830
+ self ,
831
+ valtypes : "Mapping[str, Literal['params', 'funcargs']]" ,
832
+ argnames : typing .Sequence [str ],
833
+ valset : Iterable [object ],
834
+ id : str ,
835
+ marks : Iterable [Union [Mark , MarkDecorator ]],
836
+ scopenum : int ,
837
+ param_index : int ,
838
+ ) -> None :
821
839
for arg , val in zip (argnames , valset ):
822
840
self ._checkargnotcontained (arg )
823
841
valtype_for_arg = valtypes [arg ]
824
- getattr (self , valtype_for_arg )[arg ] = val
842
+ if valtype_for_arg == "params" :
843
+ self .params [arg ] = val
844
+ elif valtype_for_arg == "funcargs" :
845
+ self .funcargs [arg ] = val
846
+ else :
847
+ assert False , "Unhandled valtype for arg: {}" .format (valtype_for_arg )
825
848
self .indices [arg ] = param_index
826
849
self ._arg2scopenum [arg ] = scopenum
827
850
self ._idlist .append (id )
@@ -1042,7 +1065,9 @@ def _validate_ids(self, ids, parameters, func_name):
1042
1065
)
1043
1066
return new_ids
1044
1067
1045
- def _resolve_arg_value_types (self , argnames : List [str ], indirect ) -> Dict [str , str ]:
1068
+ def _resolve_arg_value_types (
1069
+ self , argnames : List [str ], indirect
1070
+ ) -> Dict [str , "Literal['params', 'funcargs']" ]:
1046
1071
"""Resolves if each parametrized argument must be considered a parameter to a fixture or a "funcarg"
1047
1072
to the function, based on the ``indirect`` parameter of the parametrized() call.
1048
1073
@@ -1054,7 +1079,9 @@ def _resolve_arg_value_types(self, argnames: List[str], indirect) -> Dict[str, s
1054
1079
* "funcargs" if the argname should be a parameter to the parametrized test function.
1055
1080
"""
1056
1081
if isinstance (indirect , bool ):
1057
- valtypes = dict .fromkeys (argnames , "params" if indirect else "funcargs" )
1082
+ valtypes = dict .fromkeys (
1083
+ argnames , "params" if indirect else "funcargs"
1084
+ ) # type: Dict[str, Literal["params", "funcargs"]]
1058
1085
elif isinstance (indirect , Sequence ):
1059
1086
valtypes = dict .fromkeys (argnames , "funcargs" )
1060
1087
for arg in indirect :
0 commit comments