@@ -148,6 +148,29 @@ def meth_self_o(self, object, /): pass
148
148
def meth_type_noargs (type , / ): pass
149
149
def meth_type_o (type , object , / ): pass
150
150
151
+ # Decorator decorator that returns a simple wrapped function
152
+ def identity_wrapper (func ):
153
+ @functools .wraps (func )
154
+ def wrapped (* args , ** kwargs ):
155
+ return func (* args , ** kwargs )
156
+ return wrapped
157
+
158
+ # Original signature of the simple wrapped function returned by
159
+ # identity_wrapper().
160
+ varargs_signature = (
161
+ (('args' , ..., ..., 'var_positional' ),
162
+ ('kwargs' , ..., ..., 'var_keyword' )),
163
+ ...,
164
+ )
165
+
166
+ # Decorator decorator that returns a simple descriptor
167
+ class custom_descriptor :
168
+ def __init__ (self , func ):
169
+ self .func = func
170
+
171
+ def __get__ (self , instance , owner ):
172
+ return self .func .__get__ (instance , owner )
173
+
151
174
152
175
class TestPredicates (IsTestBase ):
153
176
@@ -4068,44 +4091,266 @@ def __init__(self, b):
4068
4091
('bar' , 2 , ..., "keyword_only" )),
4069
4092
...))
4070
4093
4071
- def test_signature_on_class_with_decorated_new (self ):
4072
- def identity (func ):
4073
- @functools .wraps (func )
4074
- def wrapped (* args , ** kwargs ):
4075
- return func (* args , ** kwargs )
4076
- return wrapped
4077
-
4078
- class Foo :
4079
- @identity
4080
- def __new__ (cls , a , b ):
4094
+ def test_signature_on_class_with_wrapped_metaclass_call (self ):
4095
+ class CM (type ):
4096
+ @identity_wrapper
4097
+ def __call__ (cls , a ):
4098
+ pass
4099
+ class C (metaclass = CM ):
4100
+ def __init__ (self , b ):
4081
4101
pass
4082
4102
4083
- self .assertEqual (self .signature (Foo ),
4084
- ((('a' , ..., ..., "positional_or_keyword" ),
4085
- ('b' , ..., ..., "positional_or_keyword" )),
4103
+ self .assertEqual (self .signature (C ),
4104
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4086
4105
...))
4087
4106
4088
- self .assertEqual (self .signature (Foo .__new__ ),
4089
- ((('cls' , ..., ..., "positional_or_keyword" ),
4090
- ('a' , ..., ..., "positional_or_keyword" ),
4091
- ('b' , ..., ..., "positional_or_keyword" )),
4092
- ...))
4107
+ with self .subTest ('classmethod' ):
4108
+ class CM (type ):
4109
+ @classmethod
4110
+ @identity_wrapper
4111
+ def __call__ (cls , a ):
4112
+ return a
4113
+ class C (metaclass = CM ):
4114
+ def __init__ (self , b ):
4115
+ pass
4093
4116
4094
- class Bar :
4095
- __new__ = identity (object .__new__ )
4117
+ self .assertEqual (C (1 ), 1 )
4118
+ self .assertEqual (self .signature (C ),
4119
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4120
+ ...))
4096
4121
4097
- varargs_signature = (
4098
- (('args' , ..., ..., 'var_positional' ),
4099
- ('kwargs' , ..., ..., 'var_keyword' )),
4100
- ...,
4101
- )
4122
+ with self .subTest ('staticmethod' ):
4123
+ class CM (type ):
4124
+ @staticmethod
4125
+ @identity_wrapper
4126
+ def __call__ (a ):
4127
+ return a
4128
+ class C (metaclass = CM ):
4129
+ def __init__ (self , b ):
4130
+ pass
4131
+
4132
+ self .assertEqual (C (1 ), 1 )
4133
+ self .assertEqual (self .signature (C ),
4134
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4135
+ ...))
4136
+
4137
+ with self .subTest ('MethodType' ):
4138
+ class A :
4139
+ @identity_wrapper
4140
+ def call (self , a ):
4141
+ return a
4142
+ class CM (type ):
4143
+ __call__ = A ().call
4144
+ class C (metaclass = CM ):
4145
+ def __init__ (self , b ):
4146
+ pass
4147
+
4148
+ self .assertEqual (C (1 ), 1 )
4149
+ self .assertEqual (self .signature (C ),
4150
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4151
+ ...))
4152
+
4153
+ with self .subTest ('descriptor' ):
4154
+ class CM (type ):
4155
+ @custom_descriptor
4156
+ @identity_wrapper
4157
+ def __call__ (self , a ):
4158
+ return a
4159
+ class C (metaclass = CM ):
4160
+ def __init__ (self , b ):
4161
+ pass
4162
+
4163
+ self .assertEqual (C (1 ), 1 )
4164
+ self .assertEqual (self .signature (C ),
4165
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4166
+ ...))
4167
+ self .assertEqual (self .signature (C .__call__ ),
4168
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4169
+ ...))
4170
+
4171
+ self .assertEqual (self .signature (C , follow_wrapped = False ),
4172
+ varargs_signature )
4173
+ self .assertEqual (self .signature (C .__call__ , follow_wrapped = False ),
4174
+ varargs_signature )
4175
+
4176
+ def test_signature_on_class_with_wrapped_init (self ):
4177
+ class C :
4178
+ @identity_wrapper
4179
+ def __init__ (self , b ):
4180
+ pass
4181
+
4182
+ C (1 ) # does not raise
4183
+ self .assertEqual (self .signature (C ),
4184
+ ((('b' , ..., ..., "positional_or_keyword" ),),
4185
+ ...))
4186
+
4187
+ with self .subTest ('classmethod' ):
4188
+ class C :
4189
+ @classmethod
4190
+ @identity_wrapper
4191
+ def __init__ (cls , b ):
4192
+ pass
4193
+
4194
+ C (1 ) # does not raise
4195
+ self .assertEqual (self .signature (C ),
4196
+ ((('b' , ..., ..., "positional_or_keyword" ),),
4197
+ ...))
4198
+
4199
+ with self .subTest ('staticmethod' ):
4200
+ class C :
4201
+ @staticmethod
4202
+ @identity_wrapper
4203
+ def __init__ (b ):
4204
+ pass
4205
+
4206
+ C (1 ) # does not raise
4207
+ self .assertEqual (self .signature (C ),
4208
+ ((('b' , ..., ..., "positional_or_keyword" ),),
4209
+ ...))
4210
+
4211
+ with self .subTest ('MethodType' ):
4212
+ class A :
4213
+ @identity_wrapper
4214
+ def call (self , a ):
4215
+ pass
4216
+
4217
+ class C :
4218
+ __init__ = A ().call
4219
+
4220
+ C (1 ) # does not raise
4221
+ self .assertEqual (self .signature (C ),
4222
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4223
+ ...))
4224
+
4225
+ with self .subTest ('partial' ):
4226
+ class C :
4227
+ __init__ = functools .partial (identity_wrapper (lambda x , a , b : None ), 2 )
4228
+
4229
+ C (1 ) # does not raise
4230
+ self .assertEqual (self .signature (C ),
4231
+ ((('b' , ..., ..., "positional_or_keyword" ),),
4232
+ ...))
4233
+
4234
+ with self .subTest ('partialmethod' ):
4235
+ class C :
4236
+ @identity_wrapper
4237
+ def _init (self , x , a ):
4238
+ self .a = (x , a )
4239
+ __init__ = functools .partialmethod (_init , 2 )
4240
+
4241
+ self .assertEqual (C (1 ).a , (2 , 1 ))
4242
+ self .assertEqual (self .signature (C ),
4243
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4244
+ ...))
4245
+
4246
+ with self .subTest ('descriptor' ):
4247
+ class C :
4248
+ @custom_descriptor
4249
+ @identity_wrapper
4250
+ def __init__ (self , a ):
4251
+ pass
4252
+
4253
+ C (1 ) # does not raise
4254
+ self .assertEqual (self .signature (C ),
4255
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4256
+ ...))
4257
+ self .assertEqual (self .signature (C .__init__ ),
4258
+ ((('self' , ..., ..., "positional_or_keyword" ),
4259
+ ('a' , ..., ..., "positional_or_keyword" )),
4260
+ ...))
4261
+
4262
+ self .assertEqual (self .signature (C , follow_wrapped = False ),
4263
+ varargs_signature )
4264
+ self .assertEqual (self .signature (C .__new__ , follow_wrapped = False ),
4265
+ varargs_signature )
4266
+
4267
+ def test_signature_on_class_with_wrapped_new (self ):
4268
+ with self .subTest ('FunctionType' ):
4269
+ class C :
4270
+ @identity_wrapper
4271
+ def __new__ (cls , a ):
4272
+ return a
4273
+
4274
+ self .assertEqual (C (1 ), 1 )
4275
+ self .assertEqual (self .signature (C ),
4276
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4277
+ ...))
4278
+
4279
+ with self .subTest ('classmethod' ):
4280
+ class C :
4281
+ @classmethod
4282
+ @identity_wrapper
4283
+ def __new__ (cls , cls2 , a ):
4284
+ return a
4285
+
4286
+ self .assertEqual (C (1 ), 1 )
4287
+ self .assertEqual (self .signature (C ),
4288
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4289
+ ...))
4290
+
4291
+ with self .subTest ('staticmethod' ):
4292
+ class C :
4293
+ @staticmethod
4294
+ @identity_wrapper
4295
+ def __new__ (cls , a ):
4296
+ return a
4297
+
4298
+ self .assertEqual (C (1 ), 1 )
4299
+ self .assertEqual (self .signature (C ),
4300
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4301
+ ...))
4302
+
4303
+ with self .subTest ('MethodType' ):
4304
+ class A :
4305
+ @identity_wrapper
4306
+ def call (self , cls , a ):
4307
+ return a
4308
+ class C :
4309
+ __new__ = A ().call
4310
+
4311
+ self .assertEqual (C (1 ), 1 )
4312
+ self .assertEqual (self .signature (C ),
4313
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4314
+ ...))
4315
+
4316
+ with self .subTest ('partial' ):
4317
+ class C :
4318
+ __new__ = functools .partial (identity_wrapper (lambda x , cls , a : (x , a )), 2 )
4319
+
4320
+ self .assertEqual (C (1 ), (2 , 1 ))
4321
+ self .assertEqual (self .signature (C ),
4322
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4323
+ ...))
4324
+
4325
+ with self .subTest ('partialmethod' ):
4326
+ class C :
4327
+ __new__ = functools .partialmethod (identity_wrapper (lambda cls , x , a : (x , a )), 2 )
4328
+
4329
+ self .assertEqual (C (1 ), (2 , 1 ))
4330
+ self .assertEqual (self .signature (C ),
4331
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4332
+ ...))
4333
+
4334
+ with self .subTest ('descriptor' ):
4335
+ class C :
4336
+ @custom_descriptor
4337
+ @identity_wrapper
4338
+ def __new__ (cls , a ):
4339
+ return a
4340
+
4341
+ self .assertEqual (C (1 ), 1 )
4342
+ self .assertEqual (self .signature (C ),
4343
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4344
+ ...))
4345
+ self .assertEqual (self .signature (C .__new__ ),
4346
+ ((('cls' , ..., ..., "positional_or_keyword" ),
4347
+ ('a' , ..., ..., "positional_or_keyword" )),
4348
+ ...))
4102
4349
4103
- self .assertEqual (self .signature (Bar ), ((), ...))
4104
- self .assertEqual (self .signature (Bar .__new__ ), varargs_signature )
4105
- self .assertEqual (self .signature (Bar , follow_wrapped = False ),
4106
- varargs_signature )
4107
- self .assertEqual (self .signature (Bar .__new__ , follow_wrapped = False ),
4108
- varargs_signature )
4350
+ self .assertEqual (self .signature (C , follow_wrapped = False ),
4351
+ varargs_signature )
4352
+ self .assertEqual (self .signature (C .__new__ , follow_wrapped = False ),
4353
+ varargs_signature )
4109
4354
4110
4355
def test_signature_on_class_with_init (self ):
4111
4356
class C :
0 commit comments