@@ -151,6 +151,29 @@ def meth_self_o(self, object, /): pass
151
151
def meth_type_noargs (type , / ): pass
152
152
def meth_type_o (type , object , / ): pass
153
153
154
+ # Decorator decorator that returns a simple wrapped function
155
+ def identity_wrapper (func ):
156
+ @functools .wraps (func )
157
+ def wrapped (* args , ** kwargs ):
158
+ return func (* args , ** kwargs )
159
+ return wrapped
160
+
161
+ # Original signature of the simple wrapped function returned by
162
+ # identity_wrapper().
163
+ varargs_signature = (
164
+ (('args' , ..., ..., 'var_positional' ),
165
+ ('kwargs' , ..., ..., 'var_keyword' )),
166
+ ...,
167
+ )
168
+
169
+ # Decorator decorator that returns a simple descriptor
170
+ class custom_descriptor :
171
+ def __init__ (self , func ):
172
+ self .func = func
173
+
174
+ def __get__ (self , instance , owner ):
175
+ return self .func .__get__ (instance , owner )
176
+
154
177
155
178
class TestPredicates (IsTestBase ):
156
179
@@ -4149,44 +4172,268 @@ def __init__(self, b):
4149
4172
('bar' , 2 , ..., "keyword_only" )),
4150
4173
...))
4151
4174
4152
- def test_signature_on_class_with_decorated_new (self ):
4153
- def identity (func ):
4154
- @functools .wraps (func )
4155
- def wrapped (* args , ** kwargs ):
4156
- return func (* args , ** kwargs )
4157
- return wrapped
4158
-
4159
- class Foo :
4160
- @identity
4161
- def __new__ (cls , a , b ):
4175
+ def test_signature_on_class_with_wrapped_metaclass_call (self ):
4176
+ class CM (type ):
4177
+ @identity_wrapper
4178
+ def __call__ (cls , a ):
4179
+ pass
4180
+ class C (metaclass = CM ):
4181
+ def __init__ (self , b ):
4162
4182
pass
4163
4183
4164
- self .assertEqual (self .signature (Foo ),
4165
- ((('a' , ..., ..., "positional_or_keyword" ),
4166
- ('b' , ..., ..., "positional_or_keyword" )),
4184
+ self .assertEqual (self .signature (C ),
4185
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4167
4186
...))
4168
4187
4169
- self .assertEqual (self .signature (Foo .__new__ ),
4170
- ((('cls' , ..., ..., "positional_or_keyword" ),
4171
- ('a' , ..., ..., "positional_or_keyword" ),
4172
- ('b' , ..., ..., "positional_or_keyword" )),
4173
- ...))
4188
+ with self .subTest ('classmethod' ):
4189
+ class CM (type ):
4190
+ @classmethod
4191
+ @identity_wrapper
4192
+ def __call__ (cls , a ):
4193
+ return a
4194
+ class C (metaclass = CM ):
4195
+ def __init__ (self , b ):
4196
+ pass
4174
4197
4175
- class Bar :
4176
- __new__ = identity (object .__new__ )
4198
+ self .assertEqual (C (1 ), 1 )
4199
+ self .assertEqual (self .signature (C ),
4200
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4201
+ ...))
4177
4202
4178
- varargs_signature = (
4179
- (('args' , ..., ..., 'var_positional' ),
4180
- ('kwargs' , ..., ..., 'var_keyword' )),
4181
- ...,
4182
- )
4203
+ with self .subTest ('staticmethod' ):
4204
+ class CM (type ):
4205
+ @staticmethod
4206
+ @identity_wrapper
4207
+ def __call__ (a ):
4208
+ return a
4209
+ class C (metaclass = CM ):
4210
+ def __init__ (self , b ):
4211
+ pass
4212
+
4213
+ self .assertEqual (C (1 ), 1 )
4214
+ self .assertEqual (self .signature (C ),
4215
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4216
+ ...))
4217
+
4218
+ with self .subTest ('MethodType' ):
4219
+ class A :
4220
+ @identity_wrapper
4221
+ def call (self , a ):
4222
+ return a
4223
+ class CM (type ):
4224
+ __call__ = A ().call
4225
+ class C (metaclass = CM ):
4226
+ def __init__ (self , b ):
4227
+ pass
4228
+
4229
+ self .assertEqual (C (1 ), 1 )
4230
+ self .assertEqual (self .signature (C ),
4231
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4232
+ ...))
4233
+
4234
+ with self .subTest ('descriptor' ):
4235
+ class CM (type ):
4236
+ @custom_descriptor
4237
+ @identity_wrapper
4238
+ def __call__ (self , a ):
4239
+ return a
4240
+ class C (metaclass = CM ):
4241
+ def __init__ (self , b ):
4242
+ pass
4243
+
4244
+ self .assertEqual (C (1 ), 1 )
4245
+ self .assertEqual (self .signature (C ),
4246
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4247
+ ...))
4248
+ self .assertEqual (self .signature (C .__call__ ),
4249
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4250
+ ...))
4251
+
4252
+ self .assertEqual (self .signature (C , follow_wrapped = False ),
4253
+ varargs_signature )
4254
+ self .assertEqual (self .signature (C .__call__ , follow_wrapped = False ),
4255
+ varargs_signature )
4256
+
4257
+ def test_signature_on_class_with_wrapped_init (self ):
4258
+ class C :
4259
+ @identity_wrapper
4260
+ def __init__ (self , b ):
4261
+ pass
4262
+
4263
+ C (1 ) # does not raise
4264
+ self .assertEqual (self .signature (C ),
4265
+ ((('b' , ..., ..., "positional_or_keyword" ),),
4266
+ ...))
4267
+
4268
+ with self .subTest ('classmethod' ):
4269
+ class C :
4270
+ @classmethod
4271
+ @identity_wrapper
4272
+ def __init__ (cls , b ):
4273
+ pass
4274
+
4275
+ C (1 ) # does not raise
4276
+ self .assertEqual (self .signature (C ),
4277
+ ((('b' , ..., ..., "positional_or_keyword" ),),
4278
+ ...))
4279
+
4280
+ with self .subTest ('staticmethod' ):
4281
+ class C :
4282
+ @staticmethod
4283
+ @identity_wrapper
4284
+ def __init__ (b ):
4285
+ pass
4286
+
4287
+ C (1 ) # does not raise
4288
+ self .assertEqual (self .signature (C ),
4289
+ ((('b' , ..., ..., "positional_or_keyword" ),),
4290
+ ...))
4291
+
4292
+ with self .subTest ('MethodType' ):
4293
+ class A :
4294
+ @identity_wrapper
4295
+ def call (self , a ):
4296
+ pass
4297
+
4298
+ class C :
4299
+ __init__ = A ().call
4300
+
4301
+ C (1 ) # does not raise
4302
+ self .assertEqual (self .signature (C ),
4303
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4304
+ ...))
4305
+
4306
+ with self .subTest ('partial' ):
4307
+ class C :
4308
+ __init__ = functools .partial (identity_wrapper (lambda x , a : None ), 2 )
4309
+
4310
+ with self .assertWarns (FutureWarning ):
4311
+ C (1 ) # does not raise
4312
+ with self .assertWarns (FutureWarning ):
4313
+ self .assertEqual (self .signature (C ),
4314
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4315
+ ...))
4316
+
4317
+ with self .subTest ('partialmethod' ):
4318
+ class C :
4319
+ @identity_wrapper
4320
+ def _init (self , x , a ):
4321
+ self .a = (x , a )
4322
+ __init__ = functools .partialmethod (_init , 2 )
4323
+
4324
+ self .assertEqual (C (1 ).a , (2 , 1 ))
4325
+ self .assertEqual (self .signature (C ),
4326
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4327
+ ...))
4328
+
4329
+ with self .subTest ('descriptor' ):
4330
+ class C :
4331
+ @custom_descriptor
4332
+ @identity_wrapper
4333
+ def __init__ (self , a ):
4334
+ pass
4335
+
4336
+ C (1 ) # does not raise
4337
+ self .assertEqual (self .signature (C ),
4338
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4339
+ ...))
4340
+ self .assertEqual (self .signature (C .__init__ ),
4341
+ ((('self' , ..., ..., "positional_or_keyword" ),
4342
+ ('a' , ..., ..., "positional_or_keyword" )),
4343
+ ...))
4344
+
4345
+ self .assertEqual (self .signature (C , follow_wrapped = False ),
4346
+ varargs_signature )
4347
+ self .assertEqual (self .signature (C .__new__ , follow_wrapped = False ),
4348
+ varargs_signature )
4349
+
4350
+ def test_signature_on_class_with_wrapped_new (self ):
4351
+ with self .subTest ('FunctionType' ):
4352
+ class C :
4353
+ @identity_wrapper
4354
+ def __new__ (cls , a ):
4355
+ return a
4356
+
4357
+ self .assertEqual (C (1 ), 1 )
4358
+ self .assertEqual (self .signature (C ),
4359
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4360
+ ...))
4361
+
4362
+ with self .subTest ('classmethod' ):
4363
+ class C :
4364
+ @classmethod
4365
+ @identity_wrapper
4366
+ def __new__ (cls , cls2 , a ):
4367
+ return a
4368
+
4369
+ self .assertEqual (C (1 ), 1 )
4370
+ self .assertEqual (self .signature (C ),
4371
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4372
+ ...))
4373
+
4374
+ with self .subTest ('staticmethod' ):
4375
+ class C :
4376
+ @staticmethod
4377
+ @identity_wrapper
4378
+ def __new__ (cls , a ):
4379
+ return a
4380
+
4381
+ self .assertEqual (C (1 ), 1 )
4382
+ self .assertEqual (self .signature (C ),
4383
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4384
+ ...))
4385
+
4386
+ with self .subTest ('MethodType' ):
4387
+ class A :
4388
+ @identity_wrapper
4389
+ def call (self , cls , a ):
4390
+ return a
4391
+ class C :
4392
+ __new__ = A ().call
4393
+
4394
+ self .assertEqual (C (1 ), 1 )
4395
+ self .assertEqual (self .signature (C ),
4396
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4397
+ ...))
4398
+
4399
+ with self .subTest ('partial' ):
4400
+ class C :
4401
+ __new__ = functools .partial (identity_wrapper (lambda x , cls , a : (x , a )), 2 )
4402
+
4403
+ self .assertEqual (C (1 ), (2 , 1 ))
4404
+ self .assertEqual (self .signature (C ),
4405
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4406
+ ...))
4407
+
4408
+ with self .subTest ('partialmethod' ):
4409
+ class C :
4410
+ __new__ = functools .partialmethod (identity_wrapper (lambda cls , x , a : (x , a )), 2 )
4411
+
4412
+ self .assertEqual (C (1 ), (2 , 1 ))
4413
+ self .assertEqual (self .signature (C ),
4414
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4415
+ ...))
4416
+
4417
+ with self .subTest ('descriptor' ):
4418
+ class C :
4419
+ @custom_descriptor
4420
+ @identity_wrapper
4421
+ def __new__ (cls , a ):
4422
+ return a
4423
+
4424
+ self .assertEqual (C (1 ), 1 )
4425
+ self .assertEqual (self .signature (C ),
4426
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4427
+ ...))
4428
+ self .assertEqual (self .signature (C .__new__ ),
4429
+ ((('cls' , ..., ..., "positional_or_keyword" ),
4430
+ ('a' , ..., ..., "positional_or_keyword" )),
4431
+ ...))
4183
4432
4184
- self .assertEqual (self .signature (Bar ), ((), ...))
4185
- self .assertEqual (self .signature (Bar .__new__ ), varargs_signature )
4186
- self .assertEqual (self .signature (Bar , follow_wrapped = False ),
4187
- varargs_signature )
4188
- self .assertEqual (self .signature (Bar .__new__ , follow_wrapped = False ),
4189
- varargs_signature )
4433
+ self .assertEqual (self .signature (C , follow_wrapped = False ),
4434
+ varargs_signature )
4435
+ self .assertEqual (self .signature (C .__new__ , follow_wrapped = False ),
4436
+ varargs_signature )
4190
4437
4191
4438
def test_signature_on_class_with_init (self ):
4192
4439
class C :
0 commit comments