@@ -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
@@ -4027,44 +4050,266 @@ def __init__(self, b):
4027
4050
('bar' , 2 , ..., "keyword_only" )),
4028
4051
...))
4029
4052
4030
- def test_signature_on_class_with_decorated_new (self ):
4031
- def identity (func ):
4032
- @functools .wraps (func )
4033
- def wrapped (* args , ** kwargs ):
4034
- return func (* args , ** kwargs )
4035
- return wrapped
4036
-
4037
- class Foo :
4038
- @identity
4039
- def __new__ (cls , a , b ):
4053
+ def test_signature_on_class_with_wrapped_metaclass_call (self ):
4054
+ class CM (type ):
4055
+ @identity_wrapper
4056
+ def __call__ (cls , a ):
4057
+ pass
4058
+ class C (metaclass = CM ):
4059
+ def __init__ (self , b ):
4040
4060
pass
4041
4061
4042
- self .assertEqual (self .signature (Foo ),
4043
- ((('a' , ..., ..., "positional_or_keyword" ),
4044
- ('b' , ..., ..., "positional_or_keyword" )),
4062
+ self .assertEqual (self .signature (C ),
4063
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4045
4064
...))
4046
4065
4047
- self .assertEqual (self .signature (Foo .__new__ ),
4048
- ((('cls' , ..., ..., "positional_or_keyword" ),
4049
- ('a' , ..., ..., "positional_or_keyword" ),
4050
- ('b' , ..., ..., "positional_or_keyword" )),
4051
- ...))
4066
+ with self .subTest ('classmethod' ):
4067
+ class CM (type ):
4068
+ @classmethod
4069
+ @identity_wrapper
4070
+ def __call__ (cls , a ):
4071
+ return a
4072
+ class C (metaclass = CM ):
4073
+ def __init__ (self , b ):
4074
+ pass
4052
4075
4053
- class Bar :
4054
- __new__ = identity (object .__new__ )
4076
+ self .assertEqual (C (1 ), 1 )
4077
+ self .assertEqual (self .signature (C ),
4078
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4079
+ ...))
4055
4080
4056
- varargs_signature = (
4057
- (('args' , ..., ..., 'var_positional' ),
4058
- ('kwargs' , ..., ..., 'var_keyword' )),
4059
- ...,
4060
- )
4081
+ with self .subTest ('staticmethod' ):
4082
+ class CM (type ):
4083
+ @staticmethod
4084
+ @identity_wrapper
4085
+ def __call__ (a ):
4086
+ return a
4087
+ class C (metaclass = CM ):
4088
+ def __init__ (self , b ):
4089
+ pass
4090
+
4091
+ self .assertEqual (C (1 ), 1 )
4092
+ self .assertEqual (self .signature (C ),
4093
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4094
+ ...))
4095
+
4096
+ with self .subTest ('MethodType' ):
4097
+ class A :
4098
+ @identity_wrapper
4099
+ def call (self , a ):
4100
+ return a
4101
+ class CM (type ):
4102
+ __call__ = A ().call
4103
+ class C (metaclass = CM ):
4104
+ def __init__ (self , b ):
4105
+ pass
4106
+
4107
+ self .assertEqual (C (1 ), 1 )
4108
+ self .assertEqual (self .signature (C ),
4109
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4110
+ ...))
4111
+
4112
+ with self .subTest ('descriptor' ):
4113
+ class CM (type ):
4114
+ @custom_descriptor
4115
+ @identity_wrapper
4116
+ def __call__ (self , a ):
4117
+ return a
4118
+ class C (metaclass = CM ):
4119
+ def __init__ (self , b ):
4120
+ pass
4121
+
4122
+ self .assertEqual (C (1 ), 1 )
4123
+ self .assertEqual (self .signature (C ),
4124
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4125
+ ...))
4126
+ self .assertEqual (self .signature (C .__call__ ),
4127
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4128
+ ...))
4129
+
4130
+ self .assertEqual (self .signature (C , follow_wrapped = False ),
4131
+ varargs_signature )
4132
+ self .assertEqual (self .signature (C .__call__ , follow_wrapped = False ),
4133
+ varargs_signature )
4134
+
4135
+ def test_signature_on_class_with_wrapped_init (self ):
4136
+ class C :
4137
+ @identity_wrapper
4138
+ def __init__ (self , b ):
4139
+ pass
4140
+
4141
+ C (1 ) # does not raise
4142
+ self .assertEqual (self .signature (C ),
4143
+ ((('b' , ..., ..., "positional_or_keyword" ),),
4144
+ ...))
4145
+
4146
+ with self .subTest ('classmethod' ):
4147
+ class C :
4148
+ @classmethod
4149
+ @identity_wrapper
4150
+ def __init__ (cls , b ):
4151
+ pass
4152
+
4153
+ C (1 ) # does not raise
4154
+ self .assertEqual (self .signature (C ),
4155
+ ((('b' , ..., ..., "positional_or_keyword" ),),
4156
+ ...))
4157
+
4158
+ with self .subTest ('staticmethod' ):
4159
+ class C :
4160
+ @staticmethod
4161
+ @identity_wrapper
4162
+ def __init__ (b ):
4163
+ pass
4164
+
4165
+ C (1 ) # does not raise
4166
+ self .assertEqual (self .signature (C ),
4167
+ ((('b' , ..., ..., "positional_or_keyword" ),),
4168
+ ...))
4169
+
4170
+ with self .subTest ('MethodType' ):
4171
+ class A :
4172
+ @identity_wrapper
4173
+ def call (self , a ):
4174
+ pass
4175
+
4176
+ class C :
4177
+ __init__ = A ().call
4178
+
4179
+ C (1 ) # does not raise
4180
+ self .assertEqual (self .signature (C ),
4181
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4182
+ ...))
4183
+
4184
+ with self .subTest ('partial' ):
4185
+ class C :
4186
+ __init__ = functools .partial (identity_wrapper (lambda x , a , b : None ), 2 )
4187
+
4188
+ C (1 ) # does not raise
4189
+ self .assertEqual (self .signature (C ),
4190
+ ((('b' , ..., ..., "positional_or_keyword" ),),
4191
+ ...))
4192
+
4193
+ with self .subTest ('partialmethod' ):
4194
+ class C :
4195
+ @identity_wrapper
4196
+ def _init (self , x , a ):
4197
+ self .a = (x , a )
4198
+ __init__ = functools .partialmethod (_init , 2 )
4199
+
4200
+ self .assertEqual (C (1 ).a , (2 , 1 ))
4201
+ self .assertEqual (self .signature (C ),
4202
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4203
+ ...))
4204
+
4205
+ with self .subTest ('descriptor' ):
4206
+ class C :
4207
+ @custom_descriptor
4208
+ @identity_wrapper
4209
+ def __init__ (self , a ):
4210
+ pass
4211
+
4212
+ C (1 ) # does not raise
4213
+ self .assertEqual (self .signature (C ),
4214
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4215
+ ...))
4216
+ self .assertEqual (self .signature (C .__init__ ),
4217
+ ((('self' , ..., ..., "positional_or_keyword" ),
4218
+ ('a' , ..., ..., "positional_or_keyword" )),
4219
+ ...))
4220
+
4221
+ self .assertEqual (self .signature (C , follow_wrapped = False ),
4222
+ varargs_signature )
4223
+ self .assertEqual (self .signature (C .__new__ , follow_wrapped = False ),
4224
+ varargs_signature )
4225
+
4226
+ def test_signature_on_class_with_wrapped_new (self ):
4227
+ with self .subTest ('FunctionType' ):
4228
+ class C :
4229
+ @identity_wrapper
4230
+ def __new__ (cls , a ):
4231
+ return a
4232
+
4233
+ self .assertEqual (C (1 ), 1 )
4234
+ self .assertEqual (self .signature (C ),
4235
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4236
+ ...))
4237
+
4238
+ with self .subTest ('classmethod' ):
4239
+ class C :
4240
+ @classmethod
4241
+ @identity_wrapper
4242
+ def __new__ (cls , cls2 , a ):
4243
+ return a
4244
+
4245
+ self .assertEqual (C (1 ), 1 )
4246
+ self .assertEqual (self .signature (C ),
4247
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4248
+ ...))
4249
+
4250
+ with self .subTest ('staticmethod' ):
4251
+ class C :
4252
+ @staticmethod
4253
+ @identity_wrapper
4254
+ def __new__ (cls , a ):
4255
+ return a
4256
+
4257
+ self .assertEqual (C (1 ), 1 )
4258
+ self .assertEqual (self .signature (C ),
4259
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4260
+ ...))
4261
+
4262
+ with self .subTest ('MethodType' ):
4263
+ class A :
4264
+ @identity_wrapper
4265
+ def call (self , cls , a ):
4266
+ return a
4267
+ class C :
4268
+ __new__ = A ().call
4269
+
4270
+ self .assertEqual (C (1 ), 1 )
4271
+ self .assertEqual (self .signature (C ),
4272
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4273
+ ...))
4274
+
4275
+ with self .subTest ('partial' ):
4276
+ class C :
4277
+ __new__ = functools .partial (identity_wrapper (lambda x , cls , a : (x , a )), 2 )
4278
+
4279
+ self .assertEqual (C (1 ), (2 , 1 ))
4280
+ self .assertEqual (self .signature (C ),
4281
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4282
+ ...))
4283
+
4284
+ with self .subTest ('partialmethod' ):
4285
+ class C :
4286
+ __new__ = functools .partialmethod (identity_wrapper (lambda cls , x , a : (x , a )), 2 )
4287
+
4288
+ self .assertEqual (C (1 ), (2 , 1 ))
4289
+ self .assertEqual (self .signature (C ),
4290
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4291
+ ...))
4292
+
4293
+ with self .subTest ('descriptor' ):
4294
+ class C :
4295
+ @custom_descriptor
4296
+ @identity_wrapper
4297
+ def __new__ (cls , a ):
4298
+ return a
4299
+
4300
+ self .assertEqual (C (1 ), 1 )
4301
+ self .assertEqual (self .signature (C ),
4302
+ ((('a' , ..., ..., "positional_or_keyword" ),),
4303
+ ...))
4304
+ self .assertEqual (self .signature (C .__new__ ),
4305
+ ((('cls' , ..., ..., "positional_or_keyword" ),
4306
+ ('a' , ..., ..., "positional_or_keyword" )),
4307
+ ...))
4061
4308
4062
- self .assertEqual (self .signature (Bar ), ((), ...))
4063
- self .assertEqual (self .signature (Bar .__new__ ), varargs_signature )
4064
- self .assertEqual (self .signature (Bar , follow_wrapped = False ),
4065
- varargs_signature )
4066
- self .assertEqual (self .signature (Bar .__new__ , follow_wrapped = False ),
4067
- varargs_signature )
4309
+ self .assertEqual (self .signature (C , follow_wrapped = False ),
4310
+ varargs_signature )
4311
+ self .assertEqual (self .signature (C .__new__ , follow_wrapped = False ),
4312
+ varargs_signature )
4068
4313
4069
4314
def test_signature_on_class_with_init (self ):
4070
4315
class C :
0 commit comments