From f241829d3726010f32af8ad494bb7ba089baa7bf Mon Sep 17 00:00:00 2001 From: AntiCompositeNumber Date: Mon, 7 Sep 2020 15:44:11 -0400 Subject: [PATCH] Make nodes.template.Template a bit more dict-like (#252) * nodes: add a `default` param to Template.get Similar to dict.get, Template.get with a default param supplied will return that value instead of raising an exception. If default is unset, Template.get will keep its previous behavior and raise an exception. * nodes: Add __getitem__, __setitem__, and __delitem__ to Template These are just aliases for existing methods, without the ability to specifiy additional parameters. However, including them makes Template more dict-like, so it's a good idea to have them. * nodes: Use def instead of assignment of a lambda in Template Per PEP8, there is no benefit to using a lambda here, and some downsides. It's the same number of SLOC either way, so might as well change it. --- mwparserfromhell/nodes/template.py | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/mwparserfromhell/nodes/template.py b/mwparserfromhell/nodes/template.py index 34cb1e9..9de7641 100644 --- a/mwparserfromhell/nodes/template.py +++ b/mwparserfromhell/nodes/template.py @@ -29,6 +29,8 @@ from ..utils import parse_anything __all__ = ["Template"] FLAGS = re.DOTALL | re.UNICODE +# Used to allow None as a valid fallback value +_UNSET = object() class Template(Node): """Represents a template in wikicode, like ``{{foo}}``.""" @@ -208,23 +210,30 @@ class Template(Node): return True return False - has_param = lambda self, name, ignore_empty=False: \ - self.has(name, ignore_empty) - has_param.__doc__ = "Alias for :meth:`has`." + def has_param(self, name, ignore_empty=False): + """Alias for :meth:`has`.""" + return self.has(name, ignore_empty) - def get(self, name): + def get(self, name, default=_UNSET): """Get the parameter whose name is *name*. The returned object is a :class:`.Parameter` instance. Raises - :exc:`ValueError` if no parameter has this name. Since multiple - parameters can have the same name, we'll return the last match, since - the last parameter is the only one read by the MediaWiki parser. + :exc:`ValueError` if no parameter has this name. If *default* is set, + returns that instead. Since multiple parameters can have the same name, + we'll return the last match, since the last parameter is the only one + read by the MediaWiki parser. """ name = str(name).strip() for param in reversed(self.params): if param.name.strip() == name: return param - raise ValueError(name) + if default is _UNSET: + raise ValueError(name) + else: + return default + + def __getitem__(self, name): + return self.get(name) def add(self, name, value, showkey=None, before=None, preserve_spacing=True): @@ -306,6 +315,9 @@ class Template(Node): self.params.append(param) return param + def __setitem__(self, name, value): + return self.add(name, value) + def remove(self, param, keep_field=False): """Remove a parameter from the template, identified by *param*. @@ -351,3 +363,6 @@ class Template(Node): raise ValueError(name) for i in reversed(to_remove): self.params.pop(i) + + def __delitem__(self, param): + return self.remove(param)