1
1
from inspect import Parameter , signature
2
2
from types import FunctionType
3
- from typing import Dict
3
+ from typing import Callable , Dict
4
4
5
5
import pytest
6
6
7
7
from ._array_module import mod as xp
8
- from .stubs import category_to_funcs
8
+ from .stubs import category_to_funcs , extension_to_funcs
9
9
10
10
kind_to_str : Dict [Parameter , str ] = {
11
11
Parameter .POSITIONAL_OR_KEYWORD : "normal argument" ,
16
16
}
17
17
18
18
19
- @pytest .mark .parametrize (
20
- "stub" ,
21
- [s for stubs in category_to_funcs .values () for s in stubs ],
22
- ids = lambda f : f .__name__ ,
23
- )
24
- def test_signature (stub : FunctionType ):
19
+ def _test_signature (func : Callable , stub : FunctionType ):
25
20
"""
26
21
Signature of function is correct enough to not affect interoperability
27
22
@@ -33,13 +28,12 @@ def add(x1, x2, /):
33
28
34
29
x1 and x2 don't need to be pos-only for the purposes of interoperability.
35
30
"""
36
- assert hasattr (xp , stub .__name__ ), f"{ stub .__name__ } not found in array module"
37
- func = getattr (xp , stub .__name__ )
38
-
39
31
try :
40
32
sig = signature (func )
41
33
except ValueError :
42
- pytest .skip (msg = f"type({ stub .__name__ } )={ type (func )} not supported by inspect" )
34
+ pytest .skip (
35
+ msg = f"type({ stub .__name__ } )={ type (func )} not supported by inspect.signature()"
36
+ )
43
37
stub_sig = signature (stub )
44
38
params = list (sig .parameters .values ())
45
39
stub_params = list (stub_sig .parameters .values ())
@@ -66,7 +60,7 @@ def add(x1, x2, /):
66
60
and stub_param .kind != Parameter .POSITIONAL_ONLY
67
61
):
68
62
pytest .skip (
69
- f"faulty spec - { stub_param .name } should be a "
63
+ f"faulty spec - argument { stub_param .name } should be a "
70
64
f"{ kind_to_str [Parameter .POSITIONAL_OR_KEYWORD ]} "
71
65
)
72
66
f_kind = kind_to_str [param .kind ]
@@ -76,13 +70,47 @@ def add(x1, x2, /):
76
70
Parameter .VAR_POSITIONAL ,
77
71
Parameter .VAR_KEYWORD ,
78
72
]:
79
- assert param . kind == stub_param . kind , (
80
- f" { param .name } is a { f_kind } , " f"but should be a { f_stub_kind } "
81
- )
73
+ assert (
74
+ param .kind == stub_param . kind
75
+ ), f" { param . name } is a { f_kind } , but should be a { f_stub_kind } "
82
76
else :
83
77
# TODO: allow for kw-only args to be out-of-order
84
78
assert param .kind in [stub_param .kind , Parameter .POSITIONAL_OR_KEYWORD ], (
85
79
f"{ param .name } is a { f_kind } , "
86
80
f"but should be a { f_stub_kind } "
87
81
f"(or at least a { kind_to_str [Parameter .POSITIONAL_OR_KEYWORD ]} )"
88
82
)
83
+
84
+
85
+ @pytest .mark .parametrize (
86
+ "stub" ,
87
+ [s for stubs in category_to_funcs .values () for s in stubs ],
88
+ ids = lambda f : f .__name__ ,
89
+ )
90
+ def test_signature (stub : FunctionType ):
91
+ assert hasattr (xp , stub .__name__ ), f"{ stub .__name__ } not found in array module"
92
+ func = getattr (xp , stub .__name__ )
93
+ _test_signature (func , stub )
94
+
95
+
96
+ extension_and_stub_params = []
97
+ for ext , stubs in extension_to_funcs .items ():
98
+ for stub in stubs :
99
+ extension_and_stub_params .append (
100
+ pytest .param (
101
+ ext ,
102
+ stub ,
103
+ id = f"{ ext } .{ stub .__name__ } " ,
104
+ marks = pytest .mark .xp_extension (ext ),
105
+ )
106
+ )
107
+
108
+
109
+ @pytest .mark .parametrize ("extension, stub" , extension_and_stub_params )
110
+ def test_extension_signature (extension : str , stub : FunctionType ):
111
+ mod = getattr (xp , extension )
112
+ assert hasattr (
113
+ mod , stub .__name__
114
+ ), f"{ stub .__name__ } not found in { extension } extension"
115
+ func = getattr (mod , stub .__name__ )
116
+ _test_signature (func , stub )
0 commit comments