comparison mercurial/templateutil.py @ 37404:7c902a8345ef

templater: complain about invalid application of '%' operator (BC) Before, '{x % y % z ...}' was silently evaluated as '{x % y}'. We no longer need this hack since the web template bugs was fixed by earlier patches. At this point, the error message may contain '<generator *>', which will be fixed later.
author Yuya Nishihara <yuya@tcha.org>
date Sun, 18 Mar 2018 21:01:23 +0900
parents 0b64416224d9
children da8e9ecac4a4
comparison
equal deleted inserted replaced
37403:448f7ec247e2 37404:7c902a8345ef
565 if not sym: 565 if not sym:
566 return _("incompatible use of template filter '%s'") % fn 566 return _("incompatible use of template filter '%s'") % fn
567 return (_("template filter '%s' is not compatible with keyword '%s'") 567 return (_("template filter '%s' is not compatible with keyword '%s'")
568 % (fn, sym)) 568 % (fn, sym))
569 569
570 def _checkeditermaps(darg, d):
571 try:
572 for v in d:
573 if not isinstance(v, dict):
574 raise TypeError
575 yield v
576 except TypeError:
577 sym = findsymbolicname(darg)
578 if sym:
579 raise error.ParseError(_("keyword '%s' is not iterable of mappings")
580 % sym)
581 else:
582 raise error.ParseError(_("%r is not iterable of mappings") % d)
583
570 def _iteroverlaymaps(context, origmapping, newmappings): 584 def _iteroverlaymaps(context, origmapping, newmappings):
571 """Generate combined mappings from the original mapping and an iterable 585 """Generate combined mappings from the original mapping and an iterable
572 of partial mappings to override the original""" 586 of partial mappings to override the original"""
573 for i, nm in enumerate(newmappings): 587 for i, nm in enumerate(newmappings):
574 lm = context.overlaymap(origmapping, nm) 588 lm = context.overlaymap(origmapping, nm)
576 yield lm 590 yield lm
577 591
578 def runmap(context, mapping, data): 592 def runmap(context, mapping, data):
579 darg, targ = data 593 darg, targ = data
580 d = evalrawexp(context, mapping, darg) 594 d = evalrawexp(context, mapping, darg)
595 # TODO: a generator should be rejected because it is a thunk of lazy
596 # string, but we can't because hgweb abuses generator as a keyword
597 # that returns a list of dicts.
581 if isinstance(d, wrapped): 598 if isinstance(d, wrapped):
582 diter = d.itermaps(context) 599 diter = d.itermaps(context)
583 else: 600 else:
584 try: 601 diter = _checkeditermaps(darg, d)
585 diter = iter(d)
586 except TypeError:
587 sym = findsymbolicname(darg)
588 if sym:
589 raise error.ParseError(_("keyword '%s' is not iterable") % sym)
590 else:
591 raise error.ParseError(_("%r is not iterable") % d)
592
593 for i, v in enumerate(diter): 602 for i, v in enumerate(diter):
594 if isinstance(v, dict): 603 lm = context.overlaymap(mapping, v)
595 lm = context.overlaymap(mapping, v) 604 lm['index'] = i
596 lm['index'] = i 605 yield evalrawexp(context, lm, targ)
597 yield evalrawexp(context, lm, targ)
598 else:
599 # v is not an iterable of dicts, this happen when 'key'
600 # has been fully expanded already and format is useless.
601 # If so, return the expanded value.
602 yield v
603 606
604 def runmember(context, mapping, data): 607 def runmember(context, mapping, data):
605 darg, memb = data 608 darg, memb = data
606 d = evalrawexp(context, mapping, darg) 609 d = evalrawexp(context, mapping, darg)
607 if util.safehasattr(d, 'tomap'): 610 if util.safehasattr(d, 'tomap'):