2525import keyword
2626import pydoc
2727import re
28- from collections import namedtuple
2928from dataclasses import dataclass
3029from typing import Any , Callable , Optional , Type , Dict , List
3130from types import MemberDescriptorType , TracebackType
3736from .lazyre import LazyReCompile
3837
3938
40- ArgSpec = namedtuple (
41- "ArgSpec" ,
42- [
43- "args" ,
44- "varargs" ,
45- "varkwargs" ,
46- "defaults" ,
47- "kwonly" ,
48- "kwonly_defaults" ,
49- "annotations" ,
50- ],
51- )
39+ @dataclass
40+ class ArgSpec :
41+ args : List [str ]
42+ varargs : Optional [str ]
43+ varkwargs : Optional [str ]
44+ defaults : Optional [List [Any ]]
45+ kwonly : List [str ]
46+ kwonly_defaults : Optional [Dict [str , Any ]]
47+ annotations : Optional [Dict [str , Any ]]
5248
5349
5450@dataclass
@@ -171,32 +167,33 @@ def parsekeywordpairs(signature: str) -> Dict[str, str]:
171167 return {item [0 ]: "" .join (item [2 :]) for item in stack if len (item ) >= 3 }
172168
173169
174- def fixlongargs (f , argspec ) :
170+ def fixlongargs (f : Callable , argspec : ArgSpec ) -> ArgSpec :
175171 """Functions taking default arguments that are references to other objects
176172 whose str() is too big will cause breakage, so we swap out the object
177173 itself with the name it was referenced with in the source by parsing the
178174 source itself !"""
179- if argspec [ 3 ] is None :
175+ if argspec . defaults is None :
180176 # No keyword args, no need to do anything
181- return
182- values = list (argspec [ 3 ] )
177+ return argspec
178+ values = list (argspec . defaults )
183179 if not values :
184- return
185- keys = argspec [ 0 ] [- len (values ) :]
180+ return argspec
181+ keys = argspec . args [- len (values ) :]
186182 try :
187183 src = inspect .getsourcelines (f )
188184 except (OSError , IndexError ):
189185 # IndexError is raised in inspect.findsource(), can happen in
190186 # some situations. See issue #94.
191- return
187+ return argspec
192188 signature = "" .join (src [0 ])
193189 kwparsed = parsekeywordpairs (signature )
194190
195191 for i , (key , value ) in enumerate (zip (keys , values )):
196192 if len (repr (value )) != len (kwparsed [key ]):
197193 values [i ] = _Repr (kwparsed [key ])
198194
199- argspec [3 ] = values
195+ argspec .defaults = values
196+ return argspec
200197
201198
202199getpydocspec_re = LazyReCompile (
@@ -247,7 +244,7 @@ def getpydocspec(f, func):
247244 )
248245
249246
250- def getfuncprops (func , f ) :
247+ def getfuncprops (func : str , f : Callable ) -> Optional [ FuncProps ] :
251248 # Check if it's a real bound method or if it's implicitly calling __init__
252249 # (i.e. FooClass(...) and not FooClass.__init__(...) -- the former would
253250 # not take 'self', the latter would:
@@ -268,9 +265,8 @@ def getfuncprops(func, f):
268265 # '__init__' throws xmlrpclib.Fault (see #202)
269266 return None
270267 try :
271- argspec = get_argspec_from_signature (f )
272- fixlongargs (f , argspec )
273- argspec = ArgSpec (* argspec )
268+ argspec = _get_argspec_from_signature (f )
269+ argspec = fixlongargs (f , argspec )
274270 fprops = FuncProps (func , argspec , is_bound_method )
275271 except (TypeError , KeyError , ValueError ):
276272 argspec = getpydocspec (f , func )
@@ -289,7 +285,7 @@ def is_eval_safe_name(string: str) -> bool:
289285 )
290286
291287
292- def get_argspec_from_signature ( f ) :
288+ def _get_argspec_from_signature ( f : Callable ) -> ArgSpec :
293289 """Get callable signature from inspect.signature in argspec format.
294290
295291 inspect.signature is a Python 3 only function that returns the signature of
@@ -324,26 +320,15 @@ def get_argspec_from_signature(f):
324320 elif parameter .kind == inspect .Parameter .VAR_KEYWORD :
325321 varkwargs = parameter .name
326322
327- # inspect.getfullargspec returns None for 'defaults', 'kwonly_defaults' and
328- # 'annotations' if there are no values for them.
329- if not defaults :
330- defaults = None
331-
332- if not kwonly_defaults :
333- kwonly_defaults = None
334-
335- if not annotations :
336- annotations = None
337-
338- return [
323+ return ArgSpec (
339324 args ,
340325 varargs ,
341326 varkwargs ,
342- defaults ,
327+ defaults if defaults else None ,
343328 kwonly ,
344- kwonly_defaults ,
345- annotations ,
346- ]
329+ kwonly_defaults if kwonly_defaults else None ,
330+ annotations if annotations else None ,
331+ )
347332
348333
349334get_encoding_line_re = LazyReCompile (r"^.*coding[:=]\s*([-\w.]+).*$" )
0 commit comments