_signatures.py 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817
  1. """Function signature objects for callables.
  2. Back port of Python 3.3's function signature tools from the inspect module,
  3. modified to be compatible with Python 2.7 and 3.2+.
  4. """
  5. #-----------------------------------------------------------------------------
  6. # Python 3.3 stdlib inspect.py is public domain
  7. #
  8. # Backports Copyright (C) 2013 Aaron Iles
  9. # Used under Apache License Version 2.0
  10. #
  11. # Further Changes are Copyright (C) 2013 The IPython Development Team
  12. #
  13. # Distributed under the terms of the BSD License. The full license is in
  14. # the file COPYING, distributed as part of this software.
  15. #-----------------------------------------------------------------------------
  16. from __future__ import absolute_import, division, print_function
  17. import itertools
  18. import functools
  19. import re
  20. import types
  21. # patch for single-file
  22. # we don't support 2.6, so we can just import OrderedDict
  23. from collections import OrderedDict
  24. __version__ = '0.3'
  25. # end patch
  26. __all__ = ['BoundArguments', 'Parameter', 'Signature', 'signature']
  27. _WrapperDescriptor = type(type.__call__)
  28. _MethodWrapper = type(all.__call__)
  29. _NonUserDefinedCallables = (_WrapperDescriptor,
  30. _MethodWrapper,
  31. types.BuiltinFunctionType)
  32. def formatannotation(annotation, base_module=None):
  33. if isinstance(annotation, type):
  34. if annotation.__module__ in ('builtins', '__builtin__', base_module):
  35. return annotation.__name__
  36. return annotation.__module__+'.'+annotation.__name__
  37. return repr(annotation)
  38. def _get_user_defined_method(cls, method_name, *nested):
  39. try:
  40. if cls is type:
  41. return
  42. meth = getattr(cls, method_name)
  43. for name in nested:
  44. meth = getattr(meth, name, meth)
  45. except AttributeError:
  46. return
  47. else:
  48. if not isinstance(meth, _NonUserDefinedCallables):
  49. # Once '__signature__' will be added to 'C'-level
  50. # callables, this check won't be necessary
  51. return meth
  52. def signature(obj):
  53. '''Get a signature object for the passed callable.'''
  54. if not callable(obj):
  55. raise TypeError('{0!r} is not a callable object'.format(obj))
  56. if isinstance(obj, types.MethodType):
  57. if obj.__self__ is None:
  58. # Unbound method - treat it as a function (no distinction in Py 3)
  59. obj = obj.__func__
  60. else:
  61. # Bound method: trim off the first parameter (typically self or cls)
  62. sig = signature(obj.__func__)
  63. return sig.replace(parameters=tuple(sig.parameters.values())[1:])
  64. try:
  65. sig = obj.__signature__
  66. except AttributeError:
  67. pass
  68. else:
  69. if sig is not None:
  70. return sig
  71. try:
  72. # Was this function wrapped by a decorator?
  73. wrapped = obj.__wrapped__
  74. except AttributeError:
  75. pass
  76. else:
  77. return signature(wrapped)
  78. if isinstance(obj, types.FunctionType):
  79. return Signature.from_function(obj)
  80. if isinstance(obj, functools.partial):
  81. sig = signature(obj.func)
  82. new_params = OrderedDict(sig.parameters.items())
  83. partial_args = obj.args or ()
  84. partial_keywords = obj.keywords or {}
  85. try:
  86. ba = sig.bind_partial(*partial_args, **partial_keywords)
  87. except TypeError as ex:
  88. msg = 'partial object {0!r} has incorrect arguments'.format(obj)
  89. raise ValueError(msg)
  90. for arg_name, arg_value in ba.arguments.items():
  91. param = new_params[arg_name]
  92. if arg_name in partial_keywords:
  93. # We set a new default value, because the following code
  94. # is correct:
  95. #
  96. # >>> def foo(a): print(a)
  97. # >>> print(partial(partial(foo, a=10), a=20)())
  98. # 20
  99. # >>> print(partial(partial(foo, a=10), a=20)(a=30))
  100. # 30
  101. #
  102. # So, with 'partial' objects, passing a keyword argument is
  103. # like setting a new default value for the corresponding
  104. # parameter
  105. #
  106. # We also mark this parameter with '_partial_kwarg'
  107. # flag. Later, in '_bind', the 'default' value of this
  108. # parameter will be added to 'kwargs', to simulate
  109. # the 'functools.partial' real call.
  110. new_params[arg_name] = param.replace(default=arg_value,
  111. _partial_kwarg=True)
  112. elif (param.kind not in (_VAR_KEYWORD, _VAR_POSITIONAL) and
  113. not param._partial_kwarg):
  114. new_params.pop(arg_name)
  115. return sig.replace(parameters=new_params.values())
  116. sig = None
  117. if isinstance(obj, type):
  118. # obj is a class or a metaclass
  119. # First, let's see if it has an overloaded __call__ defined
  120. # in its metaclass
  121. call = _get_user_defined_method(type(obj), '__call__')
  122. if call is not None:
  123. sig = signature(call)
  124. else:
  125. # Now we check if the 'obj' class has a '__new__' method
  126. new = _get_user_defined_method(obj, '__new__')
  127. if new is not None:
  128. sig = signature(new)
  129. else:
  130. # Finally, we should have at least __init__ implemented
  131. init = _get_user_defined_method(obj, '__init__')
  132. if init is not None:
  133. sig = signature(init)
  134. elif not isinstance(obj, _NonUserDefinedCallables):
  135. # An object with __call__
  136. # We also check that the 'obj' is not an instance of
  137. # _WrapperDescriptor or _MethodWrapper to avoid
  138. # infinite recursion (and even potential segfault)
  139. call = _get_user_defined_method(type(obj), '__call__', 'im_func')
  140. if call is not None:
  141. sig = signature(call)
  142. if sig is not None:
  143. return sig
  144. if isinstance(obj, types.BuiltinFunctionType):
  145. # Raise a nicer error message for builtins
  146. msg = 'no signature found for builtin function {0!r}'.format(obj)
  147. raise ValueError(msg)
  148. raise ValueError('callable {0!r} is not supported by signature'.format(obj))
  149. class _void(object):
  150. '''A private marker - used in Parameter & Signature'''
  151. class _empty(object):
  152. pass
  153. class _ParameterKind(int):
  154. def __new__(self, *args, **kwargs):
  155. obj = int.__new__(self, *args)
  156. obj._name = kwargs['name']
  157. return obj
  158. def __str__(self):
  159. return self._name
  160. def __repr__(self):
  161. return '<_ParameterKind: {0!r}>'.format(self._name)
  162. _POSITIONAL_ONLY = _ParameterKind(0, name='POSITIONAL_ONLY')
  163. _POSITIONAL_OR_KEYWORD = _ParameterKind(1, name='POSITIONAL_OR_KEYWORD')
  164. _VAR_POSITIONAL = _ParameterKind(2, name='VAR_POSITIONAL')
  165. _KEYWORD_ONLY = _ParameterKind(3, name='KEYWORD_ONLY')
  166. _VAR_KEYWORD = _ParameterKind(4, name='VAR_KEYWORD')
  167. class Parameter(object):
  168. '''Represents a parameter in a function signature.
  169. Has the following public attributes:
  170. * name : str
  171. The name of the parameter as a string.
  172. * default : object
  173. The default value for the parameter if specified. If the
  174. parameter has no default value, this attribute is not set.
  175. * annotation
  176. The annotation for the parameter if specified. If the
  177. parameter has no annotation, this attribute is not set.
  178. * kind : str
  179. Describes how argument values are bound to the parameter.
  180. Possible values: `Parameter.POSITIONAL_ONLY`,
  181. `Parameter.POSITIONAL_OR_KEYWORD`, `Parameter.VAR_POSITIONAL`,
  182. `Parameter.KEYWORD_ONLY`, `Parameter.VAR_KEYWORD`.
  183. '''
  184. __slots__ = ('_name', '_kind', '_default', '_annotation', '_partial_kwarg')
  185. POSITIONAL_ONLY = _POSITIONAL_ONLY
  186. POSITIONAL_OR_KEYWORD = _POSITIONAL_OR_KEYWORD
  187. VAR_POSITIONAL = _VAR_POSITIONAL
  188. KEYWORD_ONLY = _KEYWORD_ONLY
  189. VAR_KEYWORD = _VAR_KEYWORD
  190. empty = _empty
  191. def __init__(self, name, kind, default=_empty, annotation=_empty,
  192. _partial_kwarg=False):
  193. if kind not in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD,
  194. _VAR_POSITIONAL, _KEYWORD_ONLY, _VAR_KEYWORD):
  195. raise ValueError("invalid value for 'Parameter.kind' attribute")
  196. self._kind = kind
  197. if default is not _empty:
  198. if kind in (_VAR_POSITIONAL, _VAR_KEYWORD):
  199. msg = '{0} parameters cannot have default values'.format(kind)
  200. raise ValueError(msg)
  201. self._default = default
  202. self._annotation = annotation
  203. if name is None:
  204. if kind != _POSITIONAL_ONLY:
  205. raise ValueError("None is not a valid name for a "
  206. "non-positional-only parameter")
  207. self._name = name
  208. else:
  209. name = str(name)
  210. if kind != _POSITIONAL_ONLY and not re.match(r'[a-z_]\w*$', name, re.I):
  211. msg = '{0!r} is not a valid parameter name'.format(name)
  212. raise ValueError(msg)
  213. self._name = name
  214. self._partial_kwarg = _partial_kwarg
  215. @property
  216. def name(self):
  217. return self._name
  218. @property
  219. def default(self):
  220. return self._default
  221. @property
  222. def annotation(self):
  223. return self._annotation
  224. @property
  225. def kind(self):
  226. return self._kind
  227. def replace(self, name=_void, kind=_void, annotation=_void,
  228. default=_void, _partial_kwarg=_void):
  229. '''Creates a customized copy of the Parameter.'''
  230. if name is _void:
  231. name = self._name
  232. if kind is _void:
  233. kind = self._kind
  234. if annotation is _void:
  235. annotation = self._annotation
  236. if default is _void:
  237. default = self._default
  238. if _partial_kwarg is _void:
  239. _partial_kwarg = self._partial_kwarg
  240. return type(self)(name, kind, default=default, annotation=annotation,
  241. _partial_kwarg=_partial_kwarg)
  242. def __str__(self):
  243. kind = self.kind
  244. formatted = self._name
  245. if kind == _POSITIONAL_ONLY:
  246. if formatted is None:
  247. formatted = ''
  248. formatted = '<{0}>'.format(formatted)
  249. # Add annotation and default value
  250. if self._annotation is not _empty:
  251. formatted = '{0}:{1}'.format(formatted,
  252. formatannotation(self._annotation))
  253. if self._default is not _empty:
  254. formatted = '{0}={1}'.format(formatted, repr(self._default))
  255. if kind == _VAR_POSITIONAL:
  256. formatted = '*' + formatted
  257. elif kind == _VAR_KEYWORD:
  258. formatted = '**' + formatted
  259. return formatted
  260. def __repr__(self):
  261. return '<{0} at {1:#x} {2!r}>'.format(self.__class__.__name__,
  262. id(self), self.name)
  263. def __hash__(self):
  264. msg = "unhashable type: '{0}'".format(self.__class__.__name__)
  265. raise TypeError(msg)
  266. def __eq__(self, other):
  267. return (issubclass(other.__class__, Parameter) and
  268. self._name == other._name and
  269. self._kind == other._kind and
  270. self._default == other._default and
  271. self._annotation == other._annotation)
  272. def __ne__(self, other):
  273. return not self.__eq__(other)
  274. class BoundArguments(object):
  275. '''Result of :meth:`Signature.bind` call. Holds the mapping of arguments
  276. to the function's parameters.
  277. Has the following public attributes:
  278. arguments : :class:`collections.OrderedDict`
  279. An ordered mutable mapping of parameters' names to arguments' values.
  280. Does not contain arguments' default values.
  281. signature : :class:`Signature`
  282. The Signature object that created this instance.
  283. args : tuple
  284. Tuple of positional arguments values.
  285. kwargs : dict
  286. Dict of keyword arguments values.
  287. '''
  288. def __init__(self, signature, arguments):
  289. self.arguments = arguments
  290. self._signature = signature
  291. @property
  292. def signature(self):
  293. return self._signature
  294. @property
  295. def args(self):
  296. args = []
  297. for param_name, param in self._signature.parameters.items():
  298. if (param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY) or
  299. param._partial_kwarg):
  300. # Keyword arguments mapped by 'functools.partial'
  301. # (Parameter._partial_kwarg is True) are mapped
  302. # in 'BoundArguments.kwargs', along with VAR_KEYWORD &
  303. # KEYWORD_ONLY
  304. break
  305. try:
  306. arg = self.arguments[param_name]
  307. except KeyError:
  308. # We're done here. Other arguments
  309. # will be mapped in 'BoundArguments.kwargs'
  310. break
  311. else:
  312. if param.kind == _VAR_POSITIONAL:
  313. # *args
  314. args.extend(arg)
  315. else:
  316. # plain argument
  317. args.append(arg)
  318. return tuple(args)
  319. @property
  320. def kwargs(self):
  321. kwargs = {}
  322. kwargs_started = False
  323. for param_name, param in self._signature.parameters.items():
  324. if not kwargs_started:
  325. if (param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY) or
  326. param._partial_kwarg):
  327. kwargs_started = True
  328. else:
  329. if param_name not in self.arguments:
  330. kwargs_started = True
  331. continue
  332. if not kwargs_started:
  333. continue
  334. try:
  335. arg = self.arguments[param_name]
  336. except KeyError:
  337. pass
  338. else:
  339. if param.kind == _VAR_KEYWORD:
  340. # **kwargs
  341. kwargs.update(arg)
  342. else:
  343. # plain keyword argument
  344. kwargs[param_name] = arg
  345. return kwargs
  346. def __hash__(self):
  347. msg = "unhashable type: '{0}'".format(self.__class__.__name__)
  348. raise TypeError(msg)
  349. def __eq__(self, other):
  350. return (issubclass(other.__class__, BoundArguments) and
  351. self.signature == other.signature and
  352. self.arguments == other.arguments)
  353. def __ne__(self, other):
  354. return not self.__eq__(other)
  355. class Signature(object):
  356. '''A Signature object represents the overall signature of a function.
  357. It stores a Parameter object for each parameter accepted by the
  358. function, as well as information specific to the function itself.
  359. A Signature object has the following public attributes:
  360. parameters : :class:`collections.OrderedDict`
  361. An ordered mapping of parameters' names to the corresponding
  362. Parameter objects (keyword-only arguments are in the same order
  363. as listed in `code.co_varnames`).
  364. return_annotation
  365. The annotation for the return type of the function if specified.
  366. If the function has no annotation for its return type, this
  367. attribute is not set.
  368. '''
  369. __slots__ = ('_return_annotation', '_parameters')
  370. _parameter_cls = Parameter
  371. _bound_arguments_cls = BoundArguments
  372. empty = _empty
  373. def __init__(self, parameters=None, return_annotation=_empty,
  374. __validate_parameters__=True):
  375. '''Constructs Signature from the given list of Parameter
  376. objects and 'return_annotation'. All arguments are optional.
  377. '''
  378. if parameters is None:
  379. params = OrderedDict()
  380. else:
  381. if __validate_parameters__:
  382. params = OrderedDict()
  383. top_kind = _POSITIONAL_ONLY
  384. for idx, param in enumerate(parameters):
  385. kind = param.kind
  386. if kind < top_kind:
  387. msg = 'wrong parameter order: {0} before {1}'
  388. msg = msg.format(top_kind, param.kind)
  389. raise ValueError(msg)
  390. else:
  391. top_kind = kind
  392. name = param.name
  393. if name is None:
  394. name = str(idx)
  395. param = param.replace(name=name)
  396. if name in params:
  397. msg = 'duplicate parameter name: {0!r}'.format(name)
  398. raise ValueError(msg)
  399. params[name] = param
  400. else:
  401. params = OrderedDict(((param.name, param)
  402. for param in parameters))
  403. self._parameters = params
  404. self._return_annotation = return_annotation
  405. @classmethod
  406. def from_function(cls, func):
  407. '''Constructs Signature for the given python function'''
  408. if not isinstance(func, types.FunctionType):
  409. raise TypeError('{0!r} is not a Python function'.format(func))
  410. Parameter = cls._parameter_cls
  411. # Parameter information.
  412. func_code = func.__code__
  413. pos_count = func_code.co_argcount
  414. arg_names = func_code.co_varnames
  415. positional = tuple(arg_names[:pos_count])
  416. keyword_only_count = getattr(func_code, 'co_kwonlyargcount', 0)
  417. keyword_only = arg_names[pos_count:(pos_count + keyword_only_count)]
  418. annotations = getattr(func, '__annotations__', {})
  419. defaults = func.__defaults__
  420. kwdefaults = getattr(func, '__kwdefaults__', None)
  421. if defaults:
  422. pos_default_count = len(defaults)
  423. else:
  424. pos_default_count = 0
  425. parameters = []
  426. # Non-keyword-only parameters w/o defaults.
  427. non_default_count = pos_count - pos_default_count
  428. for name in positional[:non_default_count]:
  429. annotation = annotations.get(name, _empty)
  430. parameters.append(Parameter(name, annotation=annotation,
  431. kind=_POSITIONAL_OR_KEYWORD))
  432. # ... w/ defaults.
  433. for offset, name in enumerate(positional[non_default_count:]):
  434. annotation = annotations.get(name, _empty)
  435. parameters.append(Parameter(name, annotation=annotation,
  436. kind=_POSITIONAL_OR_KEYWORD,
  437. default=defaults[offset]))
  438. # *args
  439. if func_code.co_flags & 0x04:
  440. name = arg_names[pos_count + keyword_only_count]
  441. annotation = annotations.get(name, _empty)
  442. parameters.append(Parameter(name, annotation=annotation,
  443. kind=_VAR_POSITIONAL))
  444. # Keyword-only parameters.
  445. for name in keyword_only:
  446. default = _empty
  447. if kwdefaults is not None:
  448. default = kwdefaults.get(name, _empty)
  449. annotation = annotations.get(name, _empty)
  450. parameters.append(Parameter(name, annotation=annotation,
  451. kind=_KEYWORD_ONLY,
  452. default=default))
  453. # **kwargs
  454. if func_code.co_flags & 0x08:
  455. index = pos_count + keyword_only_count
  456. if func_code.co_flags & 0x04:
  457. index += 1
  458. name = arg_names[index]
  459. annotation = annotations.get(name, _empty)
  460. parameters.append(Parameter(name, annotation=annotation,
  461. kind=_VAR_KEYWORD))
  462. return cls(parameters,
  463. return_annotation=annotations.get('return', _empty),
  464. __validate_parameters__=False)
  465. @property
  466. def parameters(self):
  467. try:
  468. return types.MappingProxyType(self._parameters)
  469. except AttributeError:
  470. return OrderedDict(self._parameters.items())
  471. @property
  472. def return_annotation(self):
  473. return self._return_annotation
  474. def replace(self, parameters=_void, return_annotation=_void):
  475. '''Creates a customized copy of the Signature.
  476. Pass 'parameters' and/or 'return_annotation' arguments
  477. to override them in the new copy.
  478. '''
  479. if parameters is _void:
  480. parameters = self.parameters.values()
  481. if return_annotation is _void:
  482. return_annotation = self._return_annotation
  483. return type(self)(parameters,
  484. return_annotation=return_annotation)
  485. def __hash__(self):
  486. msg = "unhashable type: '{0}'".format(self.__class__.__name__)
  487. raise TypeError(msg)
  488. def __eq__(self, other):
  489. if (not issubclass(type(other), Signature) or
  490. self.return_annotation != other.return_annotation or
  491. len(self.parameters) != len(other.parameters)):
  492. return False
  493. other_positions = dict((param, idx)
  494. for idx, param in enumerate(other.parameters.keys()))
  495. for idx, (param_name, param) in enumerate(self.parameters.items()):
  496. if param.kind == _KEYWORD_ONLY:
  497. try:
  498. other_param = other.parameters[param_name]
  499. except KeyError:
  500. return False
  501. else:
  502. if param != other_param:
  503. return False
  504. else:
  505. try:
  506. other_idx = other_positions[param_name]
  507. except KeyError:
  508. return False
  509. else:
  510. if (idx != other_idx or
  511. param != other.parameters[param_name]):
  512. return False
  513. return True
  514. def __ne__(self, other):
  515. return not self.__eq__(other)
  516. def _bind(self, args, kwargs, partial=False):
  517. '''Private method. Don't use directly.'''
  518. arguments = OrderedDict()
  519. parameters = iter(self.parameters.values())
  520. parameters_ex = ()
  521. arg_vals = iter(args)
  522. if partial:
  523. # Support for binding arguments to 'functools.partial' objects.
  524. # See 'functools.partial' case in 'signature()' implementation
  525. # for details.
  526. for param_name, param in self.parameters.items():
  527. if (param._partial_kwarg and param_name not in kwargs):
  528. # Simulating 'functools.partial' behavior
  529. kwargs[param_name] = param.default
  530. while True:
  531. # Let's iterate through the positional arguments and corresponding
  532. # parameters
  533. try:
  534. arg_val = next(arg_vals)
  535. except StopIteration:
  536. # No more positional arguments
  537. try:
  538. param = next(parameters)
  539. except StopIteration:
  540. # No more parameters. That's it. Just need to check that
  541. # we have no `kwargs` after this while loop
  542. break
  543. else:
  544. if param.kind == _VAR_POSITIONAL:
  545. # That's OK, just empty *args. Let's start parsing
  546. # kwargs
  547. break
  548. elif param.name in kwargs:
  549. if param.kind == _POSITIONAL_ONLY:
  550. msg = '{arg!r} parameter is positional only, ' \
  551. 'but was passed as a keyword'
  552. msg = msg.format(arg=param.name)
  553. raise TypeError(msg)
  554. parameters_ex = (param,)
  555. break
  556. elif (param.kind == _VAR_KEYWORD or
  557. param.default is not _empty):
  558. # That's fine too - we have a default value for this
  559. # parameter. So, lets start parsing `kwargs`, starting
  560. # with the current parameter
  561. parameters_ex = (param,)
  562. break
  563. else:
  564. if partial:
  565. parameters_ex = (param,)
  566. break
  567. else:
  568. msg = '{arg!r} parameter lacking default value'
  569. msg = msg.format(arg=param.name)
  570. raise TypeError(msg)
  571. else:
  572. # We have a positional argument to process
  573. try:
  574. param = next(parameters)
  575. except StopIteration:
  576. raise TypeError('too many positional arguments')
  577. else:
  578. if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
  579. # Looks like we have no parameter for this positional
  580. # argument
  581. raise TypeError('too many positional arguments')
  582. if param.kind == _VAR_POSITIONAL:
  583. # We have an '*args'-like argument, let's fill it with
  584. # all positional arguments we have left and move on to
  585. # the next phase
  586. values = [arg_val]
  587. values.extend(arg_vals)
  588. arguments[param.name] = tuple(values)
  589. break
  590. if param.name in kwargs:
  591. raise TypeError('multiple values for argument '
  592. '{arg!r}'.format(arg=param.name))
  593. arguments[param.name] = arg_val
  594. # Now, we iterate through the remaining parameters to process
  595. # keyword arguments
  596. kwargs_param = None
  597. for param in itertools.chain(parameters_ex, parameters):
  598. if param.kind == _POSITIONAL_ONLY:
  599. # This should never happen in case of a properly built
  600. # Signature object (but let's have this check here
  601. # to ensure correct behaviour just in case)
  602. raise TypeError('{arg!r} parameter is positional only, '
  603. 'but was passed as a keyword'. \
  604. format(arg=param.name))
  605. if param.kind == _VAR_KEYWORD:
  606. # Memorize that we have a '**kwargs'-like parameter
  607. kwargs_param = param
  608. continue
  609. param_name = param.name
  610. try:
  611. arg_val = kwargs.pop(param_name)
  612. except KeyError:
  613. # We have no value for this parameter. It's fine though,
  614. # if it has a default value, or it is an '*args'-like
  615. # parameter, left alone by the processing of positional
  616. # arguments.
  617. if (not partial and param.kind != _VAR_POSITIONAL and
  618. param.default is _empty):
  619. raise TypeError('{arg!r} parameter lacking default value'. \
  620. format(arg=param_name))
  621. else:
  622. arguments[param_name] = arg_val
  623. if kwargs:
  624. if kwargs_param is not None:
  625. # Process our '**kwargs'-like parameter
  626. arguments[kwargs_param.name] = kwargs
  627. else:
  628. raise TypeError('too many keyword arguments')
  629. return self._bound_arguments_cls(self, arguments)
  630. def bind(self, *args, **kwargs):
  631. '''Get a :class:`BoundArguments` object, that maps the passed `args`
  632. and `kwargs` to the function's signature. Raises :exc:`TypeError`
  633. if the passed arguments can not be bound.
  634. '''
  635. return self._bind(args, kwargs)
  636. def bind_partial(self, *args, **kwargs):
  637. '''Get a :class:`BoundArguments` object, that partially maps the
  638. passed `args` and `kwargs` to the function's signature.
  639. Raises :exc:`TypeError` if the passed arguments can not be bound.
  640. '''
  641. return self._bind(args, kwargs, partial=True)
  642. def __str__(self):
  643. result = []
  644. render_kw_only_separator = True
  645. for idx, param in enumerate(self.parameters.values()):
  646. formatted = str(param)
  647. kind = param.kind
  648. if kind == _VAR_POSITIONAL:
  649. # OK, we have an '*args'-like parameter, so we won't need
  650. # a '*' to separate keyword-only arguments
  651. render_kw_only_separator = False
  652. elif kind == _KEYWORD_ONLY and render_kw_only_separator:
  653. # We have a keyword-only parameter to render and we haven't
  654. # rendered an '*args'-like parameter before, so add a '*'
  655. # separator to the parameters list ("foo(arg1, *, arg2)" case)
  656. result.append('*')
  657. # This condition should be only triggered once, so
  658. # reset the flag
  659. render_kw_only_separator = False
  660. result.append(formatted)
  661. rendered = '({0})'.format(', '.join(result))
  662. if self.return_annotation is not _empty:
  663. anno = formatannotation(self.return_annotation)
  664. rendered += ' -> {0}'.format(anno)
  665. return rendered