|
1 | 1 | from test import support
|
2 | 2 | import unittest
|
| 3 | +from types import MethodType |
3 | 4 |
|
4 | 5 | def funcattrs(**kwds):
|
5 | 6 | def decorate(func):
|
@@ -329,6 +330,91 @@ def outer(cls):
|
329 | 330 | self.assertEqual(Class().inner(), 'spam')
|
330 | 331 | self.assertEqual(Class().outer(), 'eggs')
|
331 | 332 |
|
| 333 | + def test_wrapped_classmethod_inside_classmethod(self): |
| 334 | + class MyClassMethod1: |
| 335 | + def __init__(self, func): |
| 336 | + self.func = func |
| 337 | + |
| 338 | + def __call__(self, cls): |
| 339 | + if hasattr(self.func, '__get__'): |
| 340 | + return self.func.__get__(cls, cls)() |
| 341 | + return self.func(cls) |
| 342 | + |
| 343 | + def __get__(self, instance, owner=None): |
| 344 | + if owner is None: |
| 345 | + owner = type(instance) |
| 346 | + return MethodType(self, owner) |
| 347 | + |
| 348 | + class MyClassMethod2: |
| 349 | + def __init__(self, func): |
| 350 | + if isinstance(func, classmethod): |
| 351 | + func = func.__func__ |
| 352 | + self.func = func |
| 353 | + |
| 354 | + def __call__(self, cls): |
| 355 | + return self.func(cls) |
| 356 | + |
| 357 | + def __get__(self, instance, owner=None): |
| 358 | + if owner is None: |
| 359 | + owner = type(instance) |
| 360 | + return MethodType(self, owner) |
| 361 | + |
| 362 | + for myclassmethod in [MyClassMethod1, MyClassMethod2]: |
| 363 | + class A: |
| 364 | + @myclassmethod |
| 365 | + def f1(cls): |
| 366 | + return cls |
| 367 | + |
| 368 | + @classmethod |
| 369 | + @myclassmethod |
| 370 | + def f2(cls): |
| 371 | + return cls |
| 372 | + |
| 373 | + @myclassmethod |
| 374 | + @classmethod |
| 375 | + def f3(cls): |
| 376 | + return cls |
| 377 | + |
| 378 | + @classmethod |
| 379 | + @classmethod |
| 380 | + def f4(cls): |
| 381 | + return cls |
| 382 | + |
| 383 | + @myclassmethod |
| 384 | + @MyClassMethod1 |
| 385 | + def f5(cls): |
| 386 | + re
8000
turn cls |
| 387 | + |
| 388 | + @myclassmethod |
| 389 | + @MyClassMethod2 |
| 390 | + def f6(cls): |
| 391 | + return cls |
| 392 | + |
| 393 | + self.assertIs(A.f1(), A) |
| 394 | + self.assertIs(A.f2(), A) |
| 395 | + self.assertIs(A.f3(), A) |
| 396 | + self.assertIs(A.f4(), A) |
| 397 | + self.assertIs(A.f5(), A) |
| 398 | + self.assertIs(A.f6(), A) |
| 399 | + a = A() |
| 400 | + self.assertIs(a.f1(), A) |
| 401 | + self.assertIs(a.f2(), A) |
| 402 | + self.assertIs(a.f3(), A) |
| 403 | + self.assertIs(a.f4(), A) |
| 404 | + self.assertIs(a.f5(), A) |
| 405 | + self.assertIs(a.f6(), A) |
| 406 | + |
| 407 | + def f(cls): |
| 408 | + return cls |
| 409 | + |
| 410 | + self.assertIs(myclassmethod(f).__get__(a)(), A) |
| 411 | + self.assertIs(myclassmethod(f).__get__(a, A)(), A) |
| 412 | + self.assertIs(myclassmethod(f).__get__(A, A)(), A) |
| 413 | + self.assertIs(myclassmethod(f).__get__(A)(), type(A)) |
| 414 | + self.assertIs(classmethod(f).__get__(a)(), A) |
| 415 | + self.assertIs(classmethod(f).__get__(a, A)(), A) |
| 416 | + self.assertIs(classmethod(f).__get__(A, A)(), A) |
| 417 | + self.assertIs(classmethod(f).__get__(A)(), type(A)) |
332 | 418 |
|
333 | 419 | class TestClassDecorators(unittest.TestCase):
|
334 | 420 |
|
|
0 commit comments