From fb4d426ad83f22844b284851b40b1a70709257d4 Mon Sep 17 00:00:00 2001 From: David Salisbury Date: Wed, 10 Feb 2016 18:50:34 -0600 Subject: [PATCH] Optional: add in default_factory argument Supports cases where the user wants to return some mutable object, but a new instance each time. For instance, Optional(something, default={}) will return the exact same dict each time, which may not be the desired behaviour. --- parcon/__init__.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/parcon/__init__.py b/parcon/__init__.py index 99f150d..989a25c 100644 --- a/parcon/__init__.py +++ b/parcon/__init__.py @@ -1347,12 +1347,14 @@ def __repr__(self): class Optional(_GRParser): """ A parser that returns whatever its underlying parser returns, except that - if the specified parser fails, this parser succeeds and returns the default + if the specified parser fails, this parser succeeds and either invokes the + default_factory callable, returning the result, or returns the default result specified to it (which, itself, defaults to None). """ - def __init__(self, parser, default=None): + def __init__(self, parser, default=None, default_factory=None): self.parser = parser self.default = default + self.default_factory = default_factory or (lambda: default) self.railroad_children = [self.parser] def parse(self, text, position, end, space): @@ -1360,7 +1362,7 @@ def parse(self, text, position, end, space): if result: return result else: - return match(position, self.default, result.expected) + return match(position, self.default_factory(), result.expected) def do_graph(self, graph): graph.add_node(id(self), label="Optional, defaulting to:\n%s" % repr(self.default))