diff options
author | da-woods <dw-git@d-woods.co.uk> | 2023-04-28 10:36:56 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-28 11:36:56 +0200 |
commit | cdce132997b60ace744da88572ee457e3a9444de (patch) | |
tree | f2bcaddbb4ed574c5163de9b35d209d9dc3a3aea | |
parent | 31d847ea1e64714dd75017c68f70aedc566eccb9 (diff) | |
download | cython-cdce132997b60ace744da88572ee457e3a9444de.tar.gz |
Fix parsing of bracketed then called context managers (GH-5404)
Require the bracketed multiple context managers to be followed by a
colon, so that the bracketed called context manager is identified as
regular parentheses in old-style syntax.
Fixes https://github.com/cython/cython/issues/5403
-rw-r--r-- | Cython/Compiler/Parsing.py | 4 | ||||
-rw-r--r-- | tests/run/withstat_py.py | 20 |
2 files changed, 24 insertions, 0 deletions
diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index 7c7b7f8a8..a796c865a 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -2141,6 +2141,10 @@ def p_with_items(s, is_async=False): s.next() items = p_with_items_list(s, is_async) s.expect(")") + if s.sy != ":": + # Fail - the message doesn't matter because we'll try the + # non-bracket version so it'll never be shown + s.error("") brackets_succeeded = not errors if not brackets_succeeded: # try the non-bracket version diff --git a/tests/run/withstat_py.py b/tests/run/withstat_py.py index 53197dc04..3cc327fb2 100644 --- a/tests/run/withstat_py.py +++ b/tests/run/withstat_py.py @@ -205,3 +205,23 @@ def manager_from_expression(): g = GetManager() with g.get(2) as x: print(x) + +def manager_from_ternary(use_first): + """ + >>> manager_from_ternary(True) + enter + exit <type 'type'> <type 'ValueError'> <type 'traceback'> + >>> manager_from_ternary(False) + enter + exit <type 'type'> <type 'ValueError'> <type 'traceback'> + In except + """ + # This is mostly testing a parsing problem, hence the + # result of the ternary must be callable + cm1_getter = lambda: ContextManager("1", exit_ret=True) + cm2_getter = lambda: ContextManager("2") + try: + with (cm1_getter if use_first else cm2_getter)(): + raise ValueError + except ValueError: + print("In except") |