@@ -949,9 +949,9 @@ def getfullargspec(func):
949
949
The first four items in the tuple correspond to getargspec().
950
950
"""
951
951
952
- builtin_method_param = None
953
-
954
- if ismethod ( func ):
952
+ try :
953
+ # Re: `skip_bound_arg=False`
954
+ #
955
955
# There is a notable difference in behaviour between getfullargspec
956
956
# and Signature: the former always returns 'self' parameter for bound
957
957
# methods, whereas the Signature always shows the actual calling
@@ -960,20 +960,15 @@ def getfullargspec(func):
960
960
# To simulate this behaviour, we "unbind" bound methods, to trick
961
961
# inspect.signature to always return their first parameter ("self",
962
962
# usually)
963
- func = func .__func__
964
963
965
- elif isbuiltin (func ):
966
- # We have a builtin function or method. For that, we check the
967
- # special '__text_signature__' attribute, provided by the
968
- # Argument Clinic. If it's a method, we'll need to make sure
969
- # that its first parameter (usually "self") is always returned
970
- # (see the previous comment).
971
- text_signature = getattr (func , '__text_signature__' , None )
972
- if text_signature and text_signature .startswith ('($' ):
973
- builtin_method_param = _signature_get_bound_param (text_signature )
964
+ # Re: `follow_wrapper_chains=False`
965
+ #
966
+ # getfullargspec() historically ignored __wrapped__ attributes,
967
+ # so we ensure that remains the case in 3.3+
974
968
975
- try :
976
- sig = signature (func )
969
+ sig = _signature_internal (func ,
970
+ follow_wrapper_chains = False ,
971
+ skip_bound_arg = False )
977
972
except Exception as ex :
978
973
# Most of the times 'signature' will raise ValueError.
979
974
# But, it can also raise AttributeError, and, maybe something
@@ -1023,13 +1018,6 @@ def getfullargspec(func):
1023
1018
# compatibility with 'func.__defaults__'
1024
1019
defaults = None
1025
1020
1026
- if builtin_method_param and (not args or args [0 ] != builtin_method_param ):
1027
- # `func` is a method, and we always need to return its
1028
- # first parameter -- usually "self" (to be backwards
1029
- # compatible with the previous implementation of
1030
- # getfullargspec)
1031
- args .insert (0 , builtin_method_param )
1032
-
1033
1021
return FullArgSpec (args , varargs , varkw , defaults ,
1034
1022
kwonlyargs , kwdefaults , annotations )
1035
1023
@@ -1719,7 +1707,7 @@ def _signature_strip_non_python_syntax(signature):
1719
1707
return clean_signature , self_parameter , last_positional_only
1720
1708
1721
1709
1722
- def _signature_fromstr (cls , obj , s ):
1710
+ def _signature_fromstr (cls , obj , s , skip_bound_arg = True ):
1723
1711
# Internal helper to parse content of '__text_signature__'
1724
1712
# and return a Signature based on it
1725
1713
Parameter = cls ._parameter_cls
@@ -1840,7 +1828,7 @@ def p(name_node, default_node, default=empty):
1840
1828
1841
1829
if self_parameter is not None :
1842
1830
assert parameters
1843
- if getattr (obj , '__self__' , None ):
1831
+ if getattr (obj , '__self__' , None ) and skip_bound_arg :
1844
1832
# strip off self, it's already been bound
1845
1833
parameters .pop (0 )
1846
1834
else :
@@ -1851,20 +1839,39 @@ def p(name_node, default_node, default=empty):
1851
1839
return cls (parameters , return_annotation = cls .empty )
1852
1840
1853
1841
1854
- def signature (obj ):
1855
- '''Get a signature object for the passed callable.'''
1842
+ def _signature_from_builtin (cls , func , skip_bound_arg = True ):
1843
+ # Internal helper function to get signature for
1844
+ # builtin callables
1845
+ if not _signature_is_builtin (func ):
1846
+ raise TypeError ("{!r} is not a Python builtin "
1847
+ "function" .format (func ))
1848
+
1849
+ s = getattr (func , "__text_signature__" , None )
1850
+ if not s :
1851
+ raise ValueError ("no signature found for builtin {!r}" .format (func ))
1852
+
1853
+ return _signature_fromstr (cls , func , s , skip_bound_arg )
1854
+
1855
+
1856
+ def _signature_internal (obj , follow_wrapper_chains = True , skip_bound_arg = True ):
1856
1857
1857
1858
if not callable (obj ):
1858
1859
raise TypeError ('{!r} is not a callable object' .format (obj ))
1859
1860
1860
1861
if isinstance (obj , types .MethodType ):
1861
1862
# In this case we skip the first parameter of the underlying
1862
1863
# function (usually `self` or `cls`).
1863
- sig = signature (obj .__func__ )
1864
- return _signature_bound_method (sig )
1864
+ sig = _signature_internal (obj .__func__ ,
1865
+ follow_wrapper_chains ,
1866
+ skip_bound_arg )
1867
+ if skip_bound_arg :
1868
+ return _signature_bound_method (sig )
1869
+ else :
1870
+ return sig
1865
1871
1866
1872
# Was this function wrapped by a decorator?
1867
- obj = unwrap (obj , stop = (lambda f : hasattr (f , "__signature__" )))
1873
+ if follow_wrapper_chains :
1874
+ obj = unwrap (obj , stop = (lambda f : hasattr (f , "__signature__" )))
1868
1875
1869
1876
try :
1870
1877
sig = obj .__signature__
@@ -1887,7 +1894,9 @@ def signature(obj):
1887
1894
# (usually `self`, or `cls`) will not be passed
1888
1895
# automatically (as for boundmethods)
1889
1896
1890
- wrapped_sig = signature (partialmethod .func )
1897
+ wrapped_sig = _signature_internal (partialmethod .func ,
1898
+ follow_wrapper_chains ,
1899
+ skip_bound_arg )
1891
1900
sig = _signature_get_partial (wrapped_sig , partialmethod , (None ,))
1892
1901
1893
1902
first_wrapped_param = tuple (wrapped_sig .parameters .values ())[0 ]
@@ -1896,15 +1905,18 @@ def signature(obj):
1896
1905
return sig .replace (parameters = new_params )
1897
1906
1898
1907
if _signature_is_builtin (obj ):
1899
- return Signature .from_builtin (obj )
1908
+ return _signature_from_builtin (Signature , obj ,
1909
+ skip_bound_arg = skip_bound_arg )
1900
1910
1901
1911
if isfunction (obj ) or _signature_is_functionlike (obj ):
1902
1912
# If it's a pure Python function, or an object that is duck type
1903
1913
# of a Python function (Cython functions, for instance), then:
1904
1914
return Signature .from_function (obj )
1905
1915
1906
1916
if isinstance (obj , functools .partial ):
1907
- wrapped_sig = signature (obj .func )
1917
+ wrapped_sig = _signature_internal (obj .func ,
1918
+ follow_wrapper_chains ,
1919
+ skip_bound_arg )
1908
1920
return _signature_get_partial (wrapped_sig , obj )
1909
1921
1910
1922
sig = None
@@ -1915,17 +1927,23 @@ def signature(obj):
1915
1927
# in its metaclass
1916
1928
call = _signature_get_user_defined_method (type (obj ), '__call__' )
1917
1929
if call is not None :
1918
- sig = signature (call )
1930
+ sig = _signature_internal (call ,
1931
+ follow_wrapper_chains ,
1932
+ skip_bound_arg )
1919
1933
else :
1920
1934
# Now we check if the 'obj' class has a '__new__' method
1921
1935
new = _signature_get_user_defined_method (obj , '__new__' )
1922
1936
if new is not None :
1923
- sig = signature (new )
1937
+ sig = _signature_internal (new ,
1938
+ follow_wrapper_chains ,
1939
+ skip_bound_arg )
1924
1940
else :
1925
1941
# Finally, we should have at least __init__ implemented
1926
1942
init = _signature_get_user_defined_method (obj , '__init__' )
1927
1943
if init is not None :
1928
- sig = signature (init )
1944
+ sig = _signature_internal (init ,
1945
+ follow_wrapper_chains ,
1946
+ skip_bound_arg )
1929
1947
1930
1948
if sig is None :
1931
1949
# At this point we know, that `obj` is a class, with no user-
@@ -1967,15 +1985,20 @@ def signature(obj):
1967
1985
call = _signature_get_user_defined_method (type (obj ), '__call__' )
1968
1986
if call is not None :
1969
1987
try :
1970
- sig = signature (call )
1988
+ sig = _signature_internal (call ,
1989
+ follow_wrapper_chains ,
1990
+ skip_bound_arg )
1971
1991
except ValueError as ex :
1972
1992
msg = 'no signature found for {!r}' .format (obj )
1973
1993
raise ValueError (msg ) from ex
1974
1994
1975
1995
if sig is not None :
1976
1996
# For classes and objects we skip the first parameter of their
1977
1997
# __call__, __new__, or __init__ methods
1978
- return _signature_bound_method (sig )
1998
+ if skip_bound_arg :
1999
+ return _signature_bound_method (sig )
2000
+ else :
2001
+ return sig
1979
2002
1980
2003
if isinstance (obj , types .BuiltinFunctionType ):
1981
2004
# Raise a nicer error message for builtins
@@ -1984,6 +2007,10 @@ def signature(obj):
1984
2007
1985
2008
raise ValueError ('callable {!r} is not supported by signature' .format (obj ))
1986
2009
2010
+ def signature (obj ):
2011
+ '''Get a signature object for the passed callable.'''
2012
+ return _signature_internal (obj )
2013
+
1987
2014
1988
2015
class _void :
1989
2016
'''A private marker - used in Parameter & Signature'''
@@ -2417,15 +2444,7 @@ def from_function(cls, func):
2417
2444
2418
2445
@classmethod
2419
2446
def from_builtin (cls , func ):
2420
- if not _signature_is_builtin (func ):
2421
- raise TypeError ("{!r} is not a Python builtin "
2422
- "function" .format (func ))
2423
-
2424
- s = getattr (func , "__text_signature__" , None )
2425
- if not s :
2426
- raise ValueError ("no signature found for builtin {!r}" .format (func ))
2427
-
2428
- return _signature_fromstr (cls , func , s )
2447
+ return _signature_from_builtin (cls , func )
2429
2448
2430
2449
@property
2431
2450
def parameters (self ):
0 commit comments