Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

arguments.py 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. # This is a copy of the inspect.getcallargs() function from Python 2.7
  2. # so we can provide it for use under Python 2.6. As the code in this
  3. # file derives from the Python distribution, it falls under the version
  4. # of the PSF license used for Python 2.7.
  5. from inspect import getargspec, ismethod
  6. import sys
  7. def getcallargs(func, *positional, **named):
  8. """Get the mapping of arguments to values.
  9. A dict is returned, with keys the function argument names (including the
  10. names of the * and ** arguments, if any), and values the respective bound
  11. values from 'positional' and 'named'."""
  12. args, varargs, varkw, defaults = getargspec(func)
  13. f_name = func.__name__
  14. arg2value = {}
  15. # The following closures are basically because of tuple parameter unpacking.
  16. assigned_tuple_params = []
  17. def assign(arg, value):
  18. if isinstance(arg, str):
  19. arg2value[arg] = value
  20. else:
  21. assigned_tuple_params.append(arg)
  22. value = iter(value)
  23. for i, subarg in enumerate(arg):
  24. try:
  25. subvalue = next(value)
  26. except StopIteration:
  27. raise ValueError('need more than %d %s to unpack' %
  28. (i, 'values' if i > 1 else 'value'))
  29. assign(subarg, subvalue)
  30. try:
  31. next(value)
  32. except StopIteration:
  33. pass
  34. else:
  35. raise ValueError('too many values to unpack')
  36. def is_assigned(arg):
  37. if isinstance(arg, str):
  38. return arg in arg2value
  39. return arg in assigned_tuple_params
  40. if ismethod(func) and func.im_self is not None:
  41. # implicit 'self' (or 'cls' for classmethods) argument
  42. positional = (func.im_self,) + positional
  43. num_pos = len(positional)
  44. num_total = num_pos + len(named)
  45. num_args = len(args)
  46. num_defaults = len(defaults) if defaults else 0
  47. for arg, value in zip(args, positional):
  48. assign(arg, value)
  49. if varargs:
  50. if num_pos > num_args:
  51. assign(varargs, positional[-(num_pos-num_args):])
  52. else:
  53. assign(varargs, ())
  54. elif 0 < num_args < num_pos:
  55. raise TypeError('%s() takes %s %d %s (%d given)' % (
  56. f_name, 'at most' if defaults else 'exactly', num_args,
  57. 'arguments' if num_args > 1 else 'argument', num_total))
  58. elif num_args == 0 and num_total:
  59. if varkw:
  60. if num_pos:
  61. # XXX: We should use num_pos, but Python also uses num_total:
  62. raise TypeError('%s() takes exactly 0 arguments '
  63. '(%d given)' % (f_name, num_total))
  64. else:
  65. raise TypeError('%s() takes no arguments (%d given)' %
  66. (f_name, num_total))
  67. for arg in args:
  68. if isinstance(arg, str) and arg in named:
  69. if is_assigned(arg):
  70. raise TypeError("%s() got multiple values for keyword "
  71. "argument '%s'" % (f_name, arg))
  72. else:
  73. assign(arg, named.pop(arg))
  74. if defaults: # fill in any missing values with the defaults
  75. for arg, value in zip(args[-num_defaults:], defaults):
  76. if not is_assigned(arg):
  77. assign(arg, value)
  78. if varkw:
  79. assign(varkw, named)
  80. elif named:
  81. unexpected = next(iter(named))
  82. if isinstance(unexpected, unicode):
  83. unexpected = unexpected.encode(sys.getdefaultencoding(), 'replace')
  84. raise TypeError("%s() got an unexpected keyword argument '%s'" %
  85. (f_name, unexpected))
  86. unassigned = num_args - len([arg for arg in args if is_assigned(arg)])
  87. if unassigned:
  88. num_required = num_args - num_defaults
  89. raise TypeError('%s() takes %s %d %s (%d given)' % (
  90. f_name, 'at least' if defaults else 'exactly', num_required,
  91. 'arguments' if num_required > 1 else 'argument', num_total))
  92. return arg2value