_inspect.py 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. """Subset of inspect module from upstream python
  2. We use this instead of upstream because upstream inspect is slow to import, and
  3. significantly contributes to numpy import times. Importing this copy has almost
  4. no overhead.
  5. """
  6. from __future__ import division, absolute_import, print_function
  7. import types
  8. __all__ = ['getargspec', 'formatargspec']
  9. # ----------------------------------------------------------- type-checking
  10. def ismethod(object):
  11. """Return true if the object is an instance method.
  12. Instance method objects provide these attributes:
  13. __doc__ documentation string
  14. __name__ name with which this method was defined
  15. im_class class object in which this method belongs
  16. im_func function object containing implementation of method
  17. im_self instance to which this method is bound, or None
  18. """
  19. return isinstance(object, types.MethodType)
  20. def isfunction(object):
  21. """Return true if the object is a user-defined function.
  22. Function objects provide these attributes:
  23. __doc__ documentation string
  24. __name__ name with which this function was defined
  25. func_code code object containing compiled function bytecode
  26. func_defaults tuple of any default values for arguments
  27. func_doc (same as __doc__)
  28. func_globals global namespace in which this function was defined
  29. func_name (same as __name__)
  30. """
  31. return isinstance(object, types.FunctionType)
  32. def iscode(object):
  33. """Return true if the object is a code object.
  34. Code objects provide these attributes:
  35. co_argcount number of arguments (not including * or ** args)
  36. co_code string of raw compiled bytecode
  37. co_consts tuple of constants used in the bytecode
  38. co_filename name of file in which this code object was created
  39. co_firstlineno number of first line in Python source code
  40. co_flags bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg
  41. co_lnotab encoded mapping of line numbers to bytecode indices
  42. co_name name with which this code object was defined
  43. co_names tuple of names of local variables
  44. co_nlocals number of local variables
  45. co_stacksize virtual machine stack space required
  46. co_varnames tuple of names of arguments and local variables
  47. """
  48. return isinstance(object, types.CodeType)
  49. # ------------------------------------------------ argument list extraction
  50. # These constants are from Python's compile.h.
  51. CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS = 1, 2, 4, 8
  52. def getargs(co):
  53. """Get information about the arguments accepted by a code object.
  54. Three things are returned: (args, varargs, varkw), where 'args' is
  55. a list of argument names (possibly containing nested lists), and
  56. 'varargs' and 'varkw' are the names of the * and ** arguments or None.
  57. """
  58. if not iscode(co):
  59. raise TypeError('arg is not a code object')
  60. nargs = co.co_argcount
  61. names = co.co_varnames
  62. args = list(names[:nargs])
  63. # The following acrobatics are for anonymous (tuple) arguments.
  64. # Which we do not need to support, so remove to avoid importing
  65. # the dis module.
  66. for i in range(nargs):
  67. if args[i][:1] in ['', '.']:
  68. raise TypeError("tuple function arguments are not supported")
  69. varargs = None
  70. if co.co_flags & CO_VARARGS:
  71. varargs = co.co_varnames[nargs]
  72. nargs = nargs + 1
  73. varkw = None
  74. if co.co_flags & CO_VARKEYWORDS:
  75. varkw = co.co_varnames[nargs]
  76. return args, varargs, varkw
  77. def getargspec(func):
  78. """Get the names and default values of a function's arguments.
  79. A tuple of four things is returned: (args, varargs, varkw, defaults).
  80. 'args' is a list of the argument names (it may contain nested lists).
  81. 'varargs' and 'varkw' are the names of the * and ** arguments or None.
  82. 'defaults' is an n-tuple of the default values of the last n arguments.
  83. """
  84. if ismethod(func):
  85. func = func.__func__
  86. if not isfunction(func):
  87. raise TypeError('arg is not a Python function')
  88. args, varargs, varkw = getargs(func.__code__)
  89. return args, varargs, varkw, func.__defaults__
  90. def getargvalues(frame):
  91. """Get information about arguments passed into a particular frame.
  92. A tuple of four things is returned: (args, varargs, varkw, locals).
  93. 'args' is a list of the argument names (it may contain nested lists).
  94. 'varargs' and 'varkw' are the names of the * and ** arguments or None.
  95. 'locals' is the locals dictionary of the given frame.
  96. """
  97. args, varargs, varkw = getargs(frame.f_code)
  98. return args, varargs, varkw, frame.f_locals
  99. def joinseq(seq):
  100. if len(seq) == 1:
  101. return '(' + seq[0] + ',)'
  102. else:
  103. return '(' + ', '.join(seq) + ')'
  104. def strseq(object, convert, join=joinseq):
  105. """Recursively walk a sequence, stringifying each element.
  106. """
  107. if type(object) in [list, tuple]:
  108. return join([strseq(_o, convert, join) for _o in object])
  109. else:
  110. return convert(object)
  111. def formatargspec(args, varargs=None, varkw=None, defaults=None,
  112. formatarg=str,
  113. formatvarargs=lambda name: '*' + name,
  114. formatvarkw=lambda name: '**' + name,
  115. formatvalue=lambda value: '=' + repr(value),
  116. join=joinseq):
  117. """Format an argument spec from the 4 values returned by getargspec.
  118. The first four arguments are (args, varargs, varkw, defaults). The
  119. other four arguments are the corresponding optional formatting functions
  120. that are called to turn names and values into strings. The ninth
  121. argument is an optional function to format the sequence of arguments.
  122. """
  123. specs = []
  124. if defaults:
  125. firstdefault = len(args) - len(defaults)
  126. for i in range(len(args)):
  127. spec = strseq(args[i], formatarg, join)
  128. if defaults and i >= firstdefault:
  129. spec = spec + formatvalue(defaults[i - firstdefault])
  130. specs.append(spec)
  131. if varargs is not None:
  132. specs.append(formatvarargs(varargs))
  133. if varkw is not None:
  134. specs.append(formatvarkw(varkw))
  135. return '(' + ', '.join(specs) + ')'
  136. def formatargvalues(args, varargs, varkw, locals,
  137. formatarg=str,
  138. formatvarargs=lambda name: '*' + name,
  139. formatvarkw=lambda name: '**' + name,
  140. formatvalue=lambda value: '=' + repr(value),
  141. join=joinseq):
  142. """Format an argument spec from the 4 values returned by getargvalues.
  143. The first four arguments are (args, varargs, varkw, locals). The
  144. next four arguments are the corresponding optional formatting functions
  145. that are called to turn names and values into strings. The ninth
  146. argument is an optional function to format the sequence of arguments.
  147. """
  148. def convert(name, locals=locals,
  149. formatarg=formatarg, formatvalue=formatvalue):
  150. return formatarg(name) + formatvalue(locals[name])
  151. specs = [strseq(arg, convert, join) for arg in args]
  152. if varargs:
  153. specs.append(formatvarargs(varargs) + formatvalue(locals[varargs]))
  154. if varkw:
  155. specs.append(formatvarkw(varkw) + formatvalue(locals[varkw]))
  156. return '(' + ', '.join(specs) + ')'