@@ -1945,15 +1945,17 @@ def _signature_get_user_defined_method(cls, method_name):
1945
1945
named ``method_name`` and returns it only if it is a
1946
1946
pure python function.
1947
1947
"""
1948
- try :
1949
- meth = getattr (cls , method_name )
1950
- except AttributeError :
1951
- return
1948
+ if method_name == '__new__' :
1949
+ meth = getattr (cls , method_name , None )
1952
1950
else :
1953
- if not isinstance (meth , _NonUserDefinedCallables ):
1954
- # Once '__signature__' will be added to 'C'-level
1955
- # callables, this check won't be necessary
1956
- return meth
1951
+ meth = getattr_static (cls , method_name , None )
1952
+ if meth is None or isinstance (meth , _NonUserDefinedCallables ):
1953
+ # Once '__signature__' will be added to 'C'-level
1954
+ # callables, this check won't be necessary
1955
+ return None
1956
+ if method_name != '__new__' :
1957
+ meth = _descriptor_get (meth , cls )
1958
+ return meth
1957
1959
1958
1960
1959
1961
def _signature_get_partial (wrapped_sig , partial , extra_args = ()):
@@ -2421,6 +2423,15 @@ def _signature_from_function(cls, func, skip_bound_arg=True,
2421
2423
__validate_parameters__ = is_duck_function )
2422
2424
2423
2425
2426
+ def _descriptor_get (descriptor , obj ):
2427
+ if isclass (descriptor ):
2428
+ return descriptor
2429
+ get = getattr (type (descriptor ), '__get__' , _sentinel )
2430
+ if get is _sentinel :
2431
+ return descriptor
2432
+ return get (descriptor , obj , type (obj ))
2433
+
2434
+
2424
2435
def _signature_from_callable (obj , * ,
2425
2436
follow_wrapper_chains = True ,
2426
2437
skip_bound_arg = True ,
@@ -2521,96 +2532,72 @@ def _signature_from_callable(obj, *,
2521
2532
wrapped_sig = _get_signature_of (obj .func )
2522
2533
return _signature_get_partial (wrapped_sig , obj )
2523
2534
2524
- sig = None
2525
2535
if isinstance (obj , type ):
2526
2536
# obj is a class or a metaclass
2527
2537
2528
2538
# First, let's see if it has an overloaded __call__ defined
2529
2539
# in its metaclass
2530
2540
call = _signature_get_user_defined_method (type (obj ), '__call__' )
2531
2541
if call is not None :
2532
- sig = _get_signature_of (call )
2533
- else :
2534
- factory_method = None
2535
- new = _signature_get_user_defined_method (obj , '__new__' )
2536
- init = _signature_get_user_defined_method (obj , '__init__' )
2537
-
2538
- # Go through the MRO and see if any class has user-defined
2539
- # pure Python __new__ or __init__ method
2540
- for base in obj .__mro__ :
2541
- # Now we check if the 'obj' class has an own '__new__' method
2542
- if new is not None and '__new__' in base .__dict__ :
2543
- factory_method = new
2544
- break
2545
- # or an own '__init__' method
2546
- elif init is not None and '__init__' in base .__dict__ :
2547
- factory_method = init
2548
- break
2542
+ return _get_signature_of (call )
2549
2543
2550
- if factory_method is not None :
2551
- sig = _get_signature_of (factory_method )
2552
-
2553
- if sig is None :
2554
- # At this point we know, that `obj` is a class, with no user-
2555
- # defined '__init__', '__new__', or class-level '__call__'
2556
-
2557
- for base in obj .__mro__ [:- 1 ]:
2558
- # Since '__text_signature__' is implemented as a
2559
- # descriptor that extracts text signature from the
2560
- # class docstring, if 'obj' is derived from a builtin
2561
- # class, its own '__text_signature__' may be 'None'.
2562
- # Therefore, we go through the MRO (except the last
2563
- # class in there, which is 'object') to find the first
2564
- # class with non-empty text signature.
2565
- try :
2566
- text_sig = base .__text_signature__
2567
- except AttributeError :
2568
- pass
2569
- else :
2570
- if text_sig :
2571
- # If 'base' class has a __text_signature__ attribute:
2572
- # return a signature based on it
2573
- return _signature_fromstr (sigcls , base , text_sig )
2574
-
2575
- # No '__text_signature__' was found for the 'obj' class.
2576
- # Last option is to check if its '__init__' is
2577
- # object.__init__ or type.__init__.
2578
- if type not in obj .__mro__ :
2579
- # We have a class (not metaclass), but no user-defined
2580
- # __init__ or __new__ for it
2581
- if (obj .__init__ is object .__init__ and
2582
- obj .__new__ is object .__new__ ):
2583
- # Return a signature of 'object' builtin.
2584
- return sigcls .from_callable (object )
2585
- else :
2586
- raise ValueError (
2587
- 'no signature found for builtin type {!r}' .format (obj ))
2544
+ new = _signature_get_user_defined_method (obj , '__new__' )
2545
+ init = _signature_get_user_defined_method (obj , '__init__' )
2588
2546
2589
- elif not isinstance (obj , _NonUserDefinedCallables ):
2590
- # An object with __call__
2591
- # We also check that the 'obj' is not an instance of
2592
- # types.WrapperDescriptorType or types.MethodWrapperType to avoid
2593
- # infinite recursion (and even potential segfault)
2594
- call = _signature_get_user_defined_method (type (obj ), '__call__' )
2595
- if call is not None :
2547
+ # Go through the MRO and see if any class has user-defined
2548
+ # pure Python __new__ or __init__ method
2549
+ for base in obj .__mro__ :
2550
+ # Now we check if the 'obj' class has an own '__new__' method
2551
+ if new is not None and '__new__' in base .__dict__ :
2552
+ sig = _get_signature_of (new )
2553
+ if skip_bound_arg :
2554
+ sig = _signature_bound_method (sig )
2555
+ return sig
2556
+ # or an own '__init__' method
2557
+ elif init is not None and '__init__' in base .__dict__ :
2558
+ return _get_signature_of (init )
2559
+
2560
+ # At this point we know, that `obj` is a class, with no user-
2561
+ # defined '__init__', '__new__', or class-level '__call__'
2562
+
2563
+ for base in obj .__mro__ [:- 1 ]:
2564
+ # Since '__text_signature__' is implemented as a
2565
+ # descriptor that extracts text signature from the
2566
+ # class docstring, if 'obj' is derived from a builtin
2567
+ # class, its own '__text_signature__' may be 'None'.
2568
+ # Therefore, we go through the MRO (except the last
2569
+ # class in there, which is 'object') to find the first
2570
+ # class with non-empty text signature.
2596
2571
try :
2597
- sig = _get_signature_of (call )
2598
- except ValueError as ex :
2599
- msg = 'no signature found for {!r}' .format (obj )
2600
- raise ValueError (msg ) from ex
2601
-
2602
- if sig is not None :
2603
- # For classes and objects we skip the first parameter of their
2604
- # __call__, __new__, or __init__ methods
2605
- if skip_bound_arg :
2606
- return _signature_bound_method (sig )
2607
- else :
2608
- return sig
2572
+ text_sig = base .__text_signature__
2573
+ except AttributeError :
2574
+ pass
2575
+ else :
2576
+ if text_sig :
2577
+ # If 'base' class has a __text_signature__ attribute:
2578
+ # return a signature based on it
2579
+ return _signature_fromstr (sigcls , base , text_sig )
2580
+
2581
+ # No '__text_signature__' was found for the 'obj' class.
2582
+ # Last option is to check if its '__init__' is
2583
+ # object.__init__ or type.__init__.
2584
+ if type not in obj .__mro__ :
2585
+ # We have a class (not metaclass), but no user-defined
2586
+ # __init__ or __new__ for it
2587
+ if (obj .__init__ is object .__init__ and
2588
+ obj .__new__ is object .__new__ ):
2589
+ # Return a signature of 'object' builtin.
2590
+ return sigcls .from_callable (object )
2591
+ else :
2592
+ raise ValueError (
2593
+ 'no signature found for builtin type {!r}' .format (obj ))
2609
2594
2610
- if isinstance (obj , types .BuiltinFunctionType ):
2611
- # Raise a nicer error message for builtins
2612
- msg = 'no signature found for builtin function {!r}' .format (obj )
2613
- raise ValueError (msg )
2595
+ else :
2596
+ # An object with __call__
2597
+ call = getattr_static (type (obj ), '__call__' , None )
2598
+ if call is not None :
2599
+ call = _descriptor_get (call , obj )
2600
+ return _get_signature_of (call )
2614
2601
2615
2602
raise ValueError ('callable {!r} is not supported by signature' .format (obj ))
2616
2603
0 commit comments