| 509 | |
| 510 | |
| 511 | class TemplateDef: |
| 512 | def __init__(self, template, func_name, func_signature, |
| 513 | body, ns, pos, bound_self=None): |
| 514 | self._template = template |
| 515 | self._func_name = func_name |
| 516 | self._func_signature = func_signature |
| 517 | self._body = body |
| 518 | self._ns = ns |
| 519 | self._pos = pos |
| 520 | self._bound_self = bound_self |
| 521 | |
| 522 | def __repr__(self): |
| 523 | return '<tempita function %s(%s) at %s:%s>' % ( |
| 524 | self._func_name, self._func_signature, |
| 525 | self._template.name, self._pos) |
| 526 | |
| 527 | def __str__(self): |
| 528 | return self() |
| 529 | |
| 530 | def __call__(self, *args, **kw): |
| 531 | values = self._parse_signature(args, kw) |
| 532 | ns = self._ns.copy() |
| 533 | ns.update(values) |
| 534 | if self._bound_self is not None: |
| 535 | ns['self'] = self._bound_self |
| 536 | out = [] |
| 537 | subdefs = {} |
| 538 | self._template._interpret_codes(self._body, ns, out, subdefs) |
| 539 | return ''.join(out) |
| 540 | |
| 541 | def __get__(self, obj, type=None): |
| 542 | if obj is None: |
| 543 | return self |
| 544 | return self.__class__( |
| 545 | self._template, self._func_name, self._func_signature, |
| 546 | self._body, self._ns, self._pos, bound_self=obj) |
| 547 | |
| 548 | def _parse_signature(self, args, kw): |
| 549 | values = {} |
| 550 | sig_args, var_args, var_kw, defaults = self._func_signature |
| 551 | extra_kw = {} |
| 552 | for name, value in iteritems(kw): |
| 553 | if not var_kw and name not in sig_args: |
| 554 | raise TypeError( |
| 555 | 'Unexpected argument %s' % name) |
| 556 | if name in sig_args: |
| 557 | values[sig_args] = value |
| 558 | else: |
| 559 | extra_kw[name] = value |
| 560 | args = list(args) |
| 561 | sig_args = list(sig_args) |
| 562 | while args: |
| 563 | while sig_args and sig_args[0] in values: |
| 564 | sig_args.pop(0) |
| 565 | if sig_args: |
| 566 | name = sig_args.pop(0) |
| 567 | values[name] = args.pop(0) |
| 568 | elif var_args: |