diff --git a/src/parsec/__init__.py b/src/parsec/__init__.py index 0bf61a8..8bc07fa 100644 --- a/src/parsec/__init__.py +++ b/src/parsec/__init__.py @@ -364,6 +364,11 @@ def desc(p, description): # These parsers are applied successively and their results are sent back to the # generator using `.send()` protocol. The generator should return the result or # another parser, which is equivalent to applying it and returning its result. +# +# Note that `return` with arguments inside generator is not supported in Python 2. +# Instead, we can raise a `StopIteration` to return the result in Python 2. +# +# See #15 and `test_generate_raise` in tests/test_parsec.py ########################################################################## diff --git a/tests/test_parsec.py b/tests/test_parsec.py index 5aad593..4e8d8ee 100644 --- a/tests/test_parsec.py +++ b/tests/test_parsec.py @@ -326,5 +326,27 @@ def xy(): # should not finish executing xy() self.assertEqual(parser.parse('z'), 'z') + def test_generate_raise(self): + + # `return` with argument inside generator is not supported in Python 2. + # Instead, we can raise a `StopIteration` directly with the intended + # result in generator for Python 2. + # + # Before Python 3.3, the `StopIteration` didn't have the `value` attribute, + # we need to assign the attribute manually. + # + # See #15. + + @generate + def xy(): + yield string('x') + yield string('y') + r = StopIteration('success') + r.value = 'success' # for pre-3.3 Python + raise r + + parser = xy + self.assertEqual(parser.parse('xy'), 'success') + if __name__ == '__main__': unittest.main()