@@ -969,7 +969,8 @@ def getfullargspec(func):
969969
970970 sig = _signature_internal (func ,
971971 follow_wrapper_chains = False ,
972- skip_bound_arg = False )
972+ skip_bound_arg = False ,
973+ sigcls = Signature )
973974 except Exception as ex :
974975 # Most of the times 'signature' will raise ValueError.
975976 # But, it can also raise AttributeError, and, maybe something
@@ -1861,17 +1862,23 @@ def _signature_from_builtin(cls, func, skip_bound_arg=True):
18611862 return _signature_fromstr (cls , func , s , skip_bound_arg )
18621863
18631864
1864- def _signature_internal (obj , follow_wrapper_chains = True , skip_bound_arg = True ):
1865+ def _signature_internal (obj , * ,
1866+ follow_wrapper_chains = True ,
1867+ skip_bound_arg = True ,
1868+ sigcls ):
18651869
18661870 if not callable (obj ):
18671871 raise TypeError ('{!r} is not a callable object' .format (obj ))
18681872
18691873 if isinstance (obj , types .MethodType ):
18701874 # In this case we skip the first parameter of the underlying
18711875 # function (usually `self` or `cls`).
1872- sig = _signature_internal (obj .__func__ ,
1873- follow_wrapper_chains ,
1874- skip_bound_arg )
1876+ sig = _signature_internal (
1877+ obj .__func__ ,
1878+ follow_wrapper_chains = follow_wrapper_chains ,
1879+ skip_bound_arg = skip_bound_arg ,
1880+ sigcls = sigcls )
1881+
18751882 if skip_bound_arg :
18761883 return _signature_bound_method (sig )
18771884 else :
@@ -1902,9 +1909,12 @@ def _signature_internal(obj, follow_wrapper_chains=True, skip_bound_arg=True):
19021909 # (usually `self`, or `cls`) will not be passed
19031910 # automatically (as for boundmethods)
19041911
1905- wrapped_sig = _signature_internal (partialmethod .func ,
1906- follow_wrapper_chains ,
1907- skip_bound_arg )
1912+ wrapped_sig = _signature_internal (
1913+ partialmethod .func ,
1914+ follow_wrapper_chains = follow_wrapper_chains ,
1915+ skip_bound_arg = skip_bound_arg ,
1916+ sigcls = sigcls )
1917+
19081918 sig = _signature_get_partial (wrapped_sig , partialmethod , (None ,))
19091919
19101920 first_wrapped_param = tuple (wrapped_sig .parameters .values ())[0 ]
@@ -1915,16 +1925,18 @@ def _signature_internal(obj, follow_wrapper_chains=True, skip_bound_arg=True):
19151925 if isfunction (obj ) or _signature_is_functionlike (obj ):
19161926 # If it's a pure Python function, or an object that is duck type
19171927 # of a Python function (Cython functions, for instance), then:
1918- return Signature .from_function (obj )
1928+ return sigcls .from_function (obj )
19191929
19201930 if _signature_is_builtin (obj ):
1921- return _signature_from_builtin (Signature , obj ,
1931+ return _signature_from_builtin (sigcls , obj ,
19221932 skip_bound_arg = skip_bound_arg )
19231933
19241934 if isinstance (obj , functools .partial ):
1925- wrapped_sig = _signature_internal (obj .func ,
1926- follow_wrapper_chains ,
1927- skip_bound_arg )
1935+ wrapped_sig = _signature_internal (
1936+ obj .func ,
1937+ follow_wrapper_chains = follow_wrapper_chains ,
1938+ skip_bound_arg = skip_bound_arg ,
1939+ sigcls = sigcls )
19281940 return _signature_get_partial (wrapped_sig , obj )
19291941
19301942 sig = None
@@ -1935,23 +1947,29 @@ def _signature_internal(obj, follow_wrapper_chains=True, skip_bound_arg=True):
19351947 # in its metaclass
19361948 call = _signature_get_user_defined_method (type (obj ), '__call__' )
19371949 if call is not None :
1938- sig = _signature_internal (call ,
1939- follow_wrapper_chains ,
1940- skip_bound_arg )
1950+ sig = _signature_internal (
1951+ call ,
1952+ follow_wrapper_chains = follow_wrapper_chains ,
1953+ skip_bound_arg = skip_bound_arg ,
1954+ sigcls = sigcls )
19411955 else :
19421956 # Now we check if the 'obj' class has a '__new__' method
19431957 new = _signature_get_user_defined_method (obj , '__new__' )
19441958 if new is not None :
1945- sig = _signature_internal (new ,
1946- follow_wrapper_chains ,
1947- skip_bound_arg )
1959+ sig = _signature_internal (
1960+ new ,
1961+ follow_wrapper_chains = follow_wrapper_chains ,
1962+ skip_bound_arg = skip_bound_arg ,
1963+ sigcls = sigcls )
19481964 else :
19491965 # Finally, we should have at least __init__ implemented
19501966 init = _signature_get_user_defined_method (obj , '__init__' )
19511967 if init is not None :
1952- sig = _signature_internal (init ,
1953- follow_wrapper_chains ,
1954- skip_bound_arg )
1968+ sig = _signature_internal (
1969+ init ,
1970+ follow_wrapper_chains = follow_wrapper_chains ,
1971+ skip_bound_arg = skip_bound_arg ,
1972+ sigcls = sigcls )
19551973
19561974 if sig is None :
19571975 # At this point we know, that `obj` is a class, with no user-
@@ -1973,7 +1991,7 @@ def _signature_internal(obj, follow_wrapper_chains=True, skip_bound_arg=True):
19731991 if text_sig :
19741992 # If 'obj' class has a __text_signature__ attribute:
19751993 # return a signature based on it
1976- return _signature_fromstr (Signature , obj , text_sig )
1994+ return _signature_fromstr (sigcls , obj , text_sig )
19771995
19781996 # No '__text_signature__' was found for the 'obj' class.
19791997 # Last option is to check if its '__init__' is
@@ -1993,9 +2011,11 @@ def _signature_internal(obj, follow_wrapper_chains=True, skip_bound_arg=True):
19932011 call = _signature_get_user_defined_method (type (obj ), '__call__' )
19942012 if call is not None :
19952013 try :
1996- sig = _signature_internal (call ,
1997- follow_wrapper_chains ,
1998- skip_bound_arg )
2014+ sig = _signature_internal (
2015+ call ,
2016+ follow_wrapper_chains = follow_wrapper_chains ,
2017+ skip_bound_arg = skip_bound_arg ,
2018+ sigcls = sigcls )
19992019 except ValueError as ex :
20002020 msg = 'no signature found for {!r}' .format (obj )
20012021 raise ValueError (msg ) from ex
@@ -2015,10 +2035,6 @@ def _signature_internal(obj, follow_wrapper_chains=True, skip_bound_arg=True):
20152035
20162036 raise ValueError ('callable {!r} is not supported by signature' .format (obj ))
20172037
2018- def signature (obj ):
2019- '''Get a signature object for the passed callable.'''
2020- return _signature_internal (obj )
2021-
20222038
20232039class _void :
20242040 '''A private marker - used in Parameter & Signature'''
@@ -2464,6 +2480,10 @@ def from_function(cls, func):
24642480 def from_builtin (cls , func ):
24652481 return _signature_from_builtin (cls , func )
24662482
2483+ @classmethod
2484+ def from_callable (cls , obj ):
2485+ return _signature_internal (obj , sigcls = cls )
2486+
24672487 @property
24682488 def parameters (self ):
24692489 return self ._parameters
@@ -2723,6 +2743,12 @@ def __str__(self):
27232743
27242744 return rendered
27252745
2746+
2747+ def signature (obj ):
2748+ '''Get a signature object for the passed callable.'''
2749+ return Signature .from_callable (obj )
2750+
2751+
27262752def _main ():
27272753 """ Logic for inspecting an object given at command line """
27282754 import argparse
0 commit comments