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