13
13
DTypeLike = typing .TypeVar ("DTypeLike" )
14
14
SubokLike = typing .TypeVar ("SubokLike" )
15
15
16
+ # annotate e.g. atleast_1d(*arys)
17
+ UnpackedSeqArrayLike = typing .TypeVar ("UnpackedSeqArrayLike" )
18
+
16
19
17
20
import inspect
18
21
@@ -53,30 +56,49 @@ def normalize_subok_like(arg, name):
53
56
ArrayLike : normalize_array_like ,
54
57
Optional [ArrayLike ]: normalize_optional_array_like ,
55
58
Sequence [ArrayLike ]: normalize_seq_array_like ,
59
+ UnpackedSeqArrayLike : normalize_seq_array_like , # cf handling in normalize
56
60
DTypeLike : normalize_dtype ,
57
61
SubokLike : normalize_subok_like ,
58
62
}
59
63
60
64
import functools
61
65
62
66
67
+ def normalize_this (arg , parm ):
68
+ """Normalize arg if a normalizer is registred."""
69
+ normalizer = normalizers .get (parm .annotation , None )
70
+ if normalizer :
71
+ return normalizer (arg )
72
+ else :
73
+ # untyped arguments pass through
74
+ return arg
75
+
76
+
63
77
def normalizer (func ):
64
78
@functools .wraps (func )
65
79
def wrapped (* args , ** kwds ):
66
80
sig = inspect .signature (func )
67
81
68
- lst , dct = [], {}
82
+ # first, check for *args in positional parameters. Case in point:
83
+ # atleast_1d(*arys: UnpackedSequenceArrayLike)
84
+ # if found, consume all args into a tuple to normalize as a whole
85
+ for j , param in enumerate (sig .parameters .values ()):
86
+ if param .annotation == UnpackedSeqArrayLike :
87
+ if j == 0 :
88
+ args = (args ,)
89
+ else :
90
+ # args = args[:j] + (args[j:],) would likely work
91
+ # not present in numpy codebase, so do not bother just yet.
92
+ # NB: branching on j ==0 is to avoid the empty tuple, args[:j]
93
+ raise NotImplementedError
94
+ break
95
+
69
96
# loop over positional parameters and actual arguments
97
+ lst , dct = [], {}
70
98
for arg , (name , parm ) in zip (args , sig .parameters .items ()):
71
99
print (arg , name , parm .annotation )
72
- normalizer = normalizers .get (parm .annotation , None )
73
- if normalizer :
74
- # dct[name] = normalizer(arg, name)
75
- lst .append (normalizer (arg ))
76
- else :
77
- # untyped arguments pass through
78
- # dct[name] = arg
79
- lst .append (arg )
100
+ lst .append (normalize_this (arg , parm ))
101
+
80
102
81
103
# normalize keyword arguments
82
104
for name , arg in kwds .items ():
@@ -88,11 +110,7 @@ def wrapped(*args, **kwds):
88
110
89
111
print ("kw: " , name , sig .parameters [name ].annotation )
90
112
parm = sig .parameters [name ]
91
- normalizer = normalizers .get (parm .annotation , None )
92
- if normalizer :
93
- dct [name ] = normalizer (kwds [name ], name )
94
- else :
95
- dct [name ] = arg
113
+ dct [name ] = normalize_this (arg , parm )
96
114
97
115
ba = sig .bind (* lst , ** dct )
98
116
ba .apply_defaults ()
@@ -113,6 +131,7 @@ def wrapped(*args, **kwds):
113
131
# 5. axes : live in _impl or in types? several ways of handling them
114
132
# 6. keepdims : peel off, postprocess
115
133
# 7. OutLike : normal & keyword-only, peel off, postprocess
134
+ # 8. *args
116
135
117
136
# finally, pass normalized arguments through
118
137
result = func (* ba .args , ** ba .kwargs )
0 commit comments