@@ -451,10 +451,6 @@ class partialmethod:
451
451
__repr__ = _partial_repr
452
452
453
453
def __init__ (self ,func ,/ ,* args ,** keywords ):
454
- if not callable (func )and getattr (func ,'__get__' ,None )is None :
455
- raise TypeError (f'the first argument{ func !r} must be a callable '
456
- 'or a descriptor' )
457
-
458
454
if isinstance (func ,partialmethod ):
459
455
# Subclass optimization
460
456
temp = partial (lambda :None ,* func .args ,** func .keywords )
@@ -467,8 +463,12 @@ def __init__(self, func, /, *args, **keywords):
467
463
self .args = args
468
464
self .keywords = keywords
469
465
470
- if (isinstance (func ,_STD_METHOD_TYPES )or
471
- getattr (func ,'__get__' ,None )is None ):
466
+ if isinstance (func ,_STD_METHOD_TYPES ):
467
+ self .method = None
468
+ elif getattr (func ,'__get__' ,None )is None :
469
+ if not callable (func ):
470
+ raise TypeError (f'the first argument{ func !r} must be a callable '
471
+ 'or a descriptor' )
472
472
self .method = None
473
473
else :
474
474
# Unknown descriptor
@@ -486,22 +486,26 @@ def _make_method(self):
486
486
487
487
# 4 cases
488
488
if isinstance (func ,staticmethod ):
489
- func = partial (func .__wrapped__ ,* args ,** self .keywords )
490
- self ._set_func_attrs (func )
491
- return staticmethod (func )
489
+ deco = staticmethod
490
+ method = partial (func .__wrapped__ ,* args ,** self .keywords )
492
491
elif isinstance (func ,classmethod ):
492
+ deco = classmethod
493
493
ph_args = (Placeholder ,)if args else ()
494
- func = partial (func .__wrapped__ ,* ph_args ,* args ,** self .keywords )
495
- self ._set_func_attrs (func )
496
- return classmethod (func )
494
+ method = partial (func .__wrapped__ ,* ph_args ,* args ,** self .keywords )
497
495
else :
498
496
# instance method. 2 cases:
499
497
# a) FunctionType | partial
500
498
# b) callable object without __get__
499
+ deco = None
501
500
ph_args = (Placeholder ,)if args else ()
502
- func = partial (func ,* ph_args ,* args ,** self .keywords )
503
- self ._set_func_attrs (func )
504
- return func
501
+ method = partial (func ,* ph_args ,* args ,** self .keywords )
502
+
503
+ method .__partialmethod__ = self
504
+ if self .__isabstractmethod__ :
505
+ method = abstractmethod (method )
506
+ if deco is not None :
507
+ method = deco (method )
508
+ return method
505
509
506
510
def __get__ (self ,obj ,cls = None ):
507
511
method = self .method
@@ -510,7 +514,9 @@ def __get__(self, obj, cls=None):
510
514
# Need to get callable at runtime and apply partial on top
511
515
new_func = self .func .__get__ (obj ,cls )
512
516
result = partial (new_func ,* self .args ,** self .keywords )
513
- self ._set_func_attrs (func )
517
+ result .__partialmethod__ = self
518
+ if self .__isabstractmethod__ :
519
+ result = abstractmethod (result )
514
520
__self__ = getattr (new_func ,'__self__' ,_NULL )
515
521
if __self__ is not _NULL :
516
522
result .__self__ = __self__