comparison mercurial/templater.py @ 36921:32f9b7e3f056

templater: move hybrid class and functions to templateutil module And make _hybrid and _mappable classes public. _showlist() is still marked as private since it's weird and third-party codes shouldn't depend on it.
author Yuya Nishihara <yuya@tcha.org>
date Thu, 08 Mar 2018 23:15:09 +0900
parents 6ff6e1d6b5b8
children 521f6c7e1756
comparison
equal deleted inserted replaced
36920:6ff6e1d6b5b8 36921:32f9b7e3f056
496 raise error.ParseError(_("duplicated dict key '%s' inferred") % k) 496 raise error.ParseError(_("duplicated dict key '%s' inferred") % k)
497 data[k] = evalfuncarg(context, mapping, v) 497 data[k] = evalfuncarg(context, mapping, v)
498 498
499 data.update((k, evalfuncarg(context, mapping, v)) 499 data.update((k, evalfuncarg(context, mapping, v))
500 for k, v in args['kwargs'].iteritems()) 500 for k, v in args['kwargs'].iteritems())
501 return templatekw.hybriddict(data) 501 return templateutil.hybriddict(data)
502 502
503 @templatefunc('diff([includepattern [, excludepattern]])') 503 @templatefunc('diff([includepattern [, excludepattern]])')
504 def diff(context, mapping, args): 504 def diff(context, mapping, args):
505 """Show a diff, optionally 505 """Show a diff, optionally
506 specifying files to include or exclude.""" 506 specifying files to include or exclude."""
546 546
547 raw = evalstring(context, mapping, args[0]) 547 raw = evalstring(context, mapping, args[0])
548 ctx = context.resource(mapping, 'ctx') 548 ctx = context.resource(mapping, 'ctx')
549 m = ctx.match([raw]) 549 m = ctx.match([raw])
550 files = list(ctx.matches(m)) 550 files = list(ctx.matches(m))
551 return templatekw.compatlist(context, mapping, "file", files) 551 return templateutil.compatlist(context, mapping, "file", files)
552 552
553 @templatefunc('fill(text[, width[, initialident[, hangindent]]])') 553 @templatefunc('fill(text[, width[, initialident[, hangindent]]])')
554 def fill(context, mapping, args): 554 def fill(context, mapping, args):
555 """Fill many 555 """Fill many
556 paragraphs with optional indentation. See the "fill" filter.""" 556 paragraphs with optional indentation. See the "fill" filter."""
716 raise error.ParseError(_("join expects one or two arguments")) 716 raise error.ParseError(_("join expects one or two arguments"))
717 717
718 # TODO: perhaps this should be evalfuncarg(), but it can't because hgweb 718 # TODO: perhaps this should be evalfuncarg(), but it can't because hgweb
719 # abuses generator as a keyword that returns a list of dicts. 719 # abuses generator as a keyword that returns a list of dicts.
720 joinset = evalrawexp(context, mapping, args[0]) 720 joinset = evalrawexp(context, mapping, args[0])
721 joinset = templatekw.unwrapvalue(joinset) 721 joinset = templateutil.unwrapvalue(joinset)
722 joinfmt = getattr(joinset, 'joinfmt', pycompat.identity) 722 joinfmt = getattr(joinset, 'joinfmt', pycompat.identity)
723 joiner = " " 723 joiner = " "
724 if len(args) > 1: 724 if len(args) > 1:
725 joiner = evalstring(context, mapping, args[1]) 725 joiner = evalstring(context, mapping, args[1])
726 726
806 try: 806 try:
807 x = max(pycompat.maybebytestr(iterable)) 807 x = max(pycompat.maybebytestr(iterable))
808 except (TypeError, ValueError): 808 except (TypeError, ValueError):
809 # i18n: "max" is a keyword 809 # i18n: "max" is a keyword
810 raise error.ParseError(_("max first argument should be an iterable")) 810 raise error.ParseError(_("max first argument should be an iterable"))
811 return templatekw.wraphybridvalue(iterable, x, x) 811 return templateutil.wraphybridvalue(iterable, x, x)
812 812
813 @templatefunc('min(iterable)') 813 @templatefunc('min(iterable)')
814 def min_(context, mapping, args, **kwargs): 814 def min_(context, mapping, args, **kwargs):
815 """Return the min of an iterable""" 815 """Return the min of an iterable"""
816 if len(args) != 1: 816 if len(args) != 1:
821 try: 821 try:
822 x = min(pycompat.maybebytestr(iterable)) 822 x = min(pycompat.maybebytestr(iterable))
823 except (TypeError, ValueError): 823 except (TypeError, ValueError):
824 # i18n: "min" is a keyword 824 # i18n: "min" is a keyword
825 raise error.ParseError(_("min first argument should be an iterable")) 825 raise error.ParseError(_("min first argument should be an iterable"))
826 return templatekw.wraphybridvalue(iterable, x, x) 826 return templateutil.wraphybridvalue(iterable, x, x)
827 827
828 @templatefunc('mod(a, b)') 828 @templatefunc('mod(a, b)')
829 def mod(context, mapping, args): 829 def mod(context, mapping, args):
830 """Calculate a mod b such that a / b + a mod b == a""" 830 """Calculate a mod b such that a / b + a mod b == a"""
831 if not len(args) == 2: 831 if not len(args) == 2:
845 845
846 markers = evalfuncarg(context, mapping, args[0]) 846 markers = evalfuncarg(context, mapping, args[0])
847 847
848 try: 848 try:
849 data = obsutil.markersoperations(markers) 849 data = obsutil.markersoperations(markers)
850 return templatekw.hybridlist(data, name='operation') 850 return templateutil.hybridlist(data, name='operation')
851 except (TypeError, KeyError): 851 except (TypeError, KeyError):
852 # i18n: "obsfateoperations" is a keyword 852 # i18n: "obsfateoperations" is a keyword
853 errmsg = _("obsfateoperations first argument should be an iterable") 853 errmsg = _("obsfateoperations first argument should be an iterable")
854 raise error.ParseError(errmsg) 854 raise error.ParseError(errmsg)
855 855
862 862
863 markers = evalfuncarg(context, mapping, args[0]) 863 markers = evalfuncarg(context, mapping, args[0])
864 864
865 try: 865 try:
866 data = obsutil.markersdates(markers) 866 data = obsutil.markersdates(markers)
867 return templatekw.hybridlist(data, name='date', fmt='%d %d') 867 return templateutil.hybridlist(data, name='date', fmt='%d %d')
868 except (TypeError, KeyError): 868 except (TypeError, KeyError):
869 # i18n: "obsfatedate" is a keyword 869 # i18n: "obsfatedate" is a keyword
870 errmsg = _("obsfatedate first argument should be an iterable") 870 errmsg = _("obsfatedate first argument should be an iterable")
871 raise error.ParseError(errmsg) 871 raise error.ParseError(errmsg)
872 872
879 879
880 markers = evalfuncarg(context, mapping, args[0]) 880 markers = evalfuncarg(context, mapping, args[0])
881 881
882 try: 882 try:
883 data = obsutil.markersusers(markers) 883 data = obsutil.markersusers(markers)
884 return templatekw.hybridlist(data, name='user') 884 return templateutil.hybridlist(data, name='user')
885 except (TypeError, KeyError, ValueError): 885 except (TypeError, KeyError, ValueError):
886 # i18n: "obsfateusers" is a keyword 886 # i18n: "obsfateusers" is a keyword
887 msg = _("obsfateusers first argument should be an iterable of " 887 msg = _("obsfateusers first argument should be an iterable of "
888 "obsmakers") 888 "obsmakers")
889 raise error.ParseError(msg) 889 raise error.ParseError(msg)
1118 1118
1119 # template engine 1119 # template engine
1120 1120
1121 def _flatten(thing): 1121 def _flatten(thing):
1122 '''yield a single stream from a possibly nested set of iterators''' 1122 '''yield a single stream from a possibly nested set of iterators'''
1123 thing = templatekw.unwraphybrid(thing) 1123 thing = templateutil.unwraphybrid(thing)
1124 if isinstance(thing, bytes): 1124 if isinstance(thing, bytes):
1125 yield thing 1125 yield thing
1126 elif isinstance(thing, str): 1126 elif isinstance(thing, str):
1127 # We can only hit this on Python 3, and it's here to guard 1127 # We can only hit this on Python 3, and it's here to guard
1128 # against infinite recursion. 1128 # against infinite recursion.
1132 pass 1132 pass
1133 elif not util.safehasattr(thing, '__iter__'): 1133 elif not util.safehasattr(thing, '__iter__'):
1134 yield pycompat.bytestr(thing) 1134 yield pycompat.bytestr(thing)
1135 else: 1135 else:
1136 for i in thing: 1136 for i in thing:
1137 i = templatekw.unwraphybrid(i) 1137 i = templateutil.unwraphybrid(i)
1138 if isinstance(i, bytes): 1138 if isinstance(i, bytes):
1139 yield i 1139 yield i
1140 elif i is None: 1140 elif i is None:
1141 pass 1141 pass
1142 elif not util.safehasattr(i, '__iter__'): 1142 elif not util.safehasattr(i, '__iter__'):