@@ -1078,6 +1078,16 @@ def attrs_wo_objs(cls):
1078
1078
1079
1079
1080
1080
class TestClassesAndFunctions (unittest .TestCase ):
1081
+ def assertDeprecated (self ):
1082
+ import re
1083
+ return self .assertWarnsRegex (
1084
+ DeprecationWarning ,
1085
+ re .escape (
1086
+ "'getfullargspec' is deprecated since 3.13 "
1087
+ "and slated for removal in Python 3.15"
1088
+ ),
1089
+ )
1090
+
1081
1091
def test_newstyle_mro (self ):
1082
1092
# The same w/ new-class MRO.
1083
1093
class A (object ): pass
@@ -1094,8 +1104,9 @@ def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
1094
1104
posonlyargs_e = [], kwonlyargs_e = [],
1095
1105
kwonlydefaults_e = None ,
1096
1106
ann_e = {}):
1097
- args , varargs , varkw , defaults , kwonlyargs , kwonlydefaults , ann = \
1098
- inspect .getfullargspec (routine )
1107
+ with self .assertDeprecated ():
1108
+ args , varargs , varkw , defaults , kwonlyargs , kwonlydefaults , ann = \
1109
+ inspect .getfullargspec (routine )
1099
1110
self .assertEqual (args , args_e )
1100
1111
self .assertEqual (varargs , varargs_e )
1101
1112
self .assertEqual (varkw , varkw_e )
@@ -1148,11 +1159,13 @@ def test():
1148
1159
1149
1160
def test_getfullargspec_signature_annos (self ):
1150
1161
def test (a :'spam' ) -> 'ham' : pass
1151
- spec = inspect .getfullargspec (test )
1162
+ with self .assertDeprecated ():
1163
+ spec = inspect .getfullargspec (test )
1152
1164
self .assertEqual (test .__annotations__ , spec .annotations )
1153
1165
1154
1166
def test (): pass
1155
- spec = inspect .getfullargspec (test )
1167
+ with self .assertDeprecated ():
1168
+ spec = inspect .getfullargspec (test )
1156
1169
self .assertEqual (test .__annotations__ , spec .annotations )
1157
1170
1158
1171
@unittest .skipIf (MISSING_C_DOCSTRINGS ,
@@ -1174,7 +1187,8 @@ def test_getfullargspec_builtin_methods(self):
1174
1187
def test_getfullargspec_builtin_func (self ):
1175
1188
import _testcapi
1176
1189
builtin = _testcapi .docstring_with_signature_with_defaults
1177
- spec = inspect .getfullargspec (builtin )
1190
+ with self .assertDeprecated ():
1191
+ spec = inspect .getfullargspec (builtin )
1178
1192
self .assertEqual (spec .defaults [0 ], 'avocado' )
1179
1193
1180
1194
@cpython_only
@@ -1183,7 +1197,7 @@ def test_getfullargspec_builtin_func(self):
1183
1197
def test_getfullargspec_builtin_func_no_signature (self ):
1184
1198
import _testcapi
1185
1199
builtin = _testcapi .docstring_no_signature
1186
- with self .assertRaises (TypeError ):
1200
+ with self .assertRaises (TypeError ), self . assertDeprecated () :
1187
1201
inspect .getfullargspec (builtin )
1188
1202
1189
1203
cls = _testcapi .DocStringNoSignatureTest
@@ -1224,17 +1238,22 @@ def test_getfullargspec_builtin_func_no_signature(self):
1224
1238
tests .append ((stat .S_IMODE , meth_o ))
1225
1239
for builtin , template in tests :
1226
1240
with self .subTest (builtin ):
1227
- self .assertEqual (inspect .getfullargspec (builtin ),
1228
- inspect .getfullargspec (template ))
1241
+ with self .assertDeprecated ():
1242
+ builtin_args = inspect .getfullargspec (builtin )
1243
+ with self .assertDeprecated ():
1244
+ template_args = inspect .getfullargspec (template )
1245
+ self .assertEqual (builtin_args , template_args )
1229
1246
1230
1247
def test_getfullargspec_definition_order_preserved_on_kwonly (self ):
1231
1248
for fn in signatures_with_lexicographic_keyword_only_parameters ():
1232
- signature = inspect .getfullargspec (fn )
1249
+ with self .assertDeprecated ():
1250
+ signature = inspect .getfullargspec (fn )
1233
1251
l = list (signature .kwonlyargs )
1234
1252
sorted_l = sorted (l )
1235
1253
self .assertTrue (l )
1236
1254
self .assertEqual (l , sorted_l )
1237
- signature = inspect .getfullargspec (unsorted_keyword_only_parameters_fn )
1255
+ with self .assertDeprecated ():
1256
+ signature = inspect .getfullargspec (unsorted_keyword_only_parameters_fn )
1238
1257
l = list (signature .kwonlyargs )
1239
1258
self .assertEqual (l , unsorted_keyword_only_parameters )
1240
1259
@@ -4136,6 +4155,49 @@ class D2(D1):
4136
4155
4137
4156
self .assertEqual (inspect .signature (D2 ), inspect .signature (D1 ))
4138
4157
4158
+ def test_signature_as_getfullargspec_replacement (self ):
4159
+ def decorator (func ):
4160
+ @functools .wraps (func ) # set `__wrapper__` attribute
4161
+ def wrapper (* args , ** kwargs ):
4162
+ return func (* args , ** kwargs )
4163
+ return wrapper
4164
+
4165
+ @decorator
4166
+ def func (a : int , / , b : str = '' , * , c : bool = True ) -> int : ...
4167
+
4168
+ sig = inspect .signature (func , follow_wrapped = False , skip_bound_arg = False )
4169
+ self .assertEqual (str (sig ), '(*args, **kwargs) -> int' )
4170
+ self .assertEqual (
4171
+ str (sig ),
4172
+ str (inspect .Signature .from_callable (func ,
4173
+ follow_wrapped = False ,
4174
+ skip_bound_arg = False )),
4175
+ )
4176
+
4177
+ class My :
4178
+ def method (self , arg : int ) -> None : ...
4179
+ @classmethod
4180
+ def cl (cls , arg2 : str ) -> None : ...
4181
+
4182
+ sigs = {
4183
+ My .method : '(self, arg: int) -> None' ,
4184
+ My ().method : '(self, arg: int) -> None' ,
4185
+ My .cl : '(cls, arg2: str) -> None' ,
4186
+ My ().cl : '(cls, arg2: str) -> None' ,
4187
+ }
4188
+ for f , text_sig in sigs .items ():
4189
+ with self .subTest (f = f ):
4190
+ sig = inspect .signature (f ,
4191
+ follow_wrapped = False ,
4192
+ skip_bound_arg = False )
4193
+ self .assertEqual (str (sig ), text_sig )
4194
+ self .assertEqual (
4195
+ str (sig ),
4196
+ str (inspect .Signature .from_callable (f ,
4197
+ follow_wrapped = False ,
4198
+ skip_bound_arg = False )),
4199
+ )
4200
+
4139
4201
4140
4202
class TestParameterObject (unittest .TestCase ):
4141
4203
def test_signature_parameter_kinds (self ):
0 commit comments