GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Compilation emits multiple warnings in the finally block · Issue #131927 · python/cpython

Compilation emits multiple warnings in the finally block #131927

New issue
Copy link
New issue
Copy link
Closed
Closed
Compilation emits multiple warnings in the finally block#131927
Copy link
Labels
3.12only security fixesonly security fixes3.13only security fixesonly security fixes3.14bugs and security fixesbugs and security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

@sobolevn
sobolevn
opened on Mar 31, 2025
Issue body actions

Bug report

This code produces two SyntaxWarnings in the new REPL:

>>> def some():
...     try:
...         return 1
...     finally:
...         return 2
...         
<python-input-14>:5: SyntaxWarning: 'return' in a 'finally' block
<python-input-14>:5: SyntaxWarning: 'return' in a 'finally' block
Image

But, in our old REPL it produces just one:

Image

Other SyntaxWarnings also do not show the same behavior in the new REPL. Example:

Image

So, looks like only PEP-765 is affected, only in the new REPL.

CC @ambv @iritkatriel

Linked PRs

  • gh-131927: Prevent emitting optimizer warnings twice in the REPL #131993
  • [3.13] gh-131927: Prevent emitting optimizer warnings twice in the REPL (GH-131993) #132463
  • gh-131927: Do not emit PEP 765 warnings in ast.parse() #139642
  • gh-131927: Silence PEP 765 warnings in PyREPL #139719
  • [3.14] gh-131927: Do not emit PEP 765 warnings in ast.parse() (GH-139642) #140786

Activity

Next
  1. sobolevn
    added
    3.14bugs and security fixesbugs and security fixes
    topic-replRelated to the interactive shellRelated to the interactive shell
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Mar 31, 2025
  2. tomasr8 commented on Mar 31, 2025

    @tomasr8
    tomasr8
    on Mar 31, 2025
    Member
    More actions

    I think the issue is that we compile the source twice, once we compile to an AST and second time from the AST to a code object. The warning comes from the AST optimizer so it is emitted both times:

    cpython/Lib/_pyrepl/console.py

    Lines 190 to 209 in 6aa88a2

    try:
    tree = self.compile.compiler(
    source,
    filename,
    "exec",
    ast.PyCF_ONLY_AST,
    incomplete_input=False,
    )
    except (SyntaxError, OverflowError, ValueError):
    self.showsyntaxerror(filename, source=source)
    return False
    if tree.body:
    *_, last_stmt = tree.body
    for stmt in tree.body:
    wrapper = ast.Interactive if stmt is last_stmt else ast.Module
    the_symbol = symbol if stmt is last_stmt else "exec"
    item = wrapper([stmt])
    try:
    code = self.compile.compiler(item, filename, the_symbol)
    linecache._register_code(code, source, filename)

    A very simple fix for this would be to catch this warning on the second compilation, something like this:

    diff --git a/Lib/_pyrepl/console.py b/Lib/_pyrepl/console.py
    index 8956fb1242..9d461980be 100644
    --- a/Lib/_pyrepl/console.py
    +++ b/Lib/_pyrepl/console.py
    @@ -204,8 +204,26 @@ def runsource(self, source, filename="<input>", symbol="single"):
                 wrapper = ast.Interactive if stmt is last_stmt else ast.Module
                 the_symbol = symbol if stmt is last_stmt else "exec"
                 item = wrapper([stmt])
    +            import warnings
                 try:
    -                code = self.compile.compiler(item, filename, the_symbol)
    +                with warnings.catch_warnings(record=True) as caught_warnings:
    +                    # Enable all warnings
    +                    warnings.simplefilter("always")
    +                    code = self.compile.compiler(item, filename, the_symbol)
    +                for warning in caught_warnings:
    +                    if issubclass(warning.category, SyntaxWarning) and "in a 'finally' block" in str(warning.message):
    +                        # Ignore this warning as it would've alread been raised
    +                        # when compiling the code above
    +                        pass
    +                    else:
    +                        # Re-emit other warnings
    +                        warnings.warn_explicit(
    +                            message=warning.message,
    +                            category=warning.category,
    +                            filename=warning.filename,
    +                            lineno=warning.lineno,
    +                            source=warning.source
    +                        )
                     linecache._register_code(code, source, filename)
                 except SyntaxError as e:
                     if e.args[0] == "'await' outside function":

    I can send a PR for this later today unless you were already working on it @sobolevn ?

  3. picnixz
    added
    stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
    on Mar 31, 2025
  4. mdboom commented on Mar 31, 2025

    @mdboom
    mdboom
    on Mar 31, 2025
    Contributor
    More actions

    Cc: @iritkatriel

  5. iritkatriel commented on Mar 31, 2025

    @iritkatriel
    iritkatriel
    on Mar 31, 2025
    Member
    More actions

    Why does the repl need the ast?

  6. sobolevn commented on Mar 31, 2025

    @sobolevn
    sobolevn
    on Mar 31, 2025
    MemberAuthor
    More actions

    No, I don't plan to work on this issue, because I don't know how to solve it :)

  7. hugovk
    changed the title [-]PEP765 produces two warnings in the new REPL[/-] [+]PEP 765 produces two warnings in the new REPL[/+] on Mar 31, 2025
  8. iritkatriel commented on Mar 31, 2025

    @iritkatriel
    iritkatriel
    on Mar 31, 2025
    Member
    More actions

    Why does the repl need the ast?

    Looks like it's walking the AST and then constructing an AST for each statement on its own and executing that. Not sure why.

    I don't like the solution proposed above (suppressing the warnings) because I think we will add other syntax warnings to this stage later on (including moving some that are not in the compiler so that they show up in static analysis), and I don't want us to have to special case each one of them. Let's think of something else.

    Reacted by Mikhail Efimov and sobolevn
  9. tomasr8 commented on Mar 31, 2025

    @tomasr8
    tomasr8
    on Mar 31, 2025
    Member
    More actions

    Indeed, the solution I proposed is pretty brittle, especially if we're planning to add more warnings in the future. I'll see if I can come up with another solution.

  10. iritkatriel commented on Mar 31, 2025

    @iritkatriel
    iritkatriel
    on Mar 31, 2025
    Member
    More actions

    One thing we could do is to define a subclass of SyntaxWarning which is only raised from the ast_opt stage, and then this type can be filtered out.

    (note that ast_opt is in the process of being renamed in #131830 (comment), so maybe wait till that's merged).

    Reacted by Tomas R.
  11. tomasr8 commented on Mar 31, 2025

    @tomasr8
    tomasr8
    on Mar 31, 2025
    Member
    More actions

    That sounds like a good option! I'll wait for the other PR to land :)

  12. iritkatriel commented on Mar 31, 2025

    @iritkatriel
    iritkatriel
    on Mar 31, 2025
    Member
    More actions

    Actually, adding a new builtin warning type would need a PEP, and this is probably overkill for this problem.

    Maybe we can just mark the SyntaxWarning as "coming from ast_opt" in some way that the real can query?

  13. tomasr8 commented on Mar 31, 2025

    @tomasr8
    tomasr8
    on Mar 31, 2025
    Member
    More actions

    Or a way to turn off warnings coming from ast_opt? Though that also seems like overkill for such a niche use case.

  14. 14 remaining items

  15. tomasr8
    closed this as completedon Apr 12, 2025
  16. serhiy-storchaka commented on Apr 12, 2025

    @serhiy-storchaka
    serhiy-storchaka
    on Apr 12, 2025
    Member
    More actions

    There were at least three different bugs:

    • Compiling the finally block could emit two warnings, because the code in the finally block is compiled twice.
    • Repeated compile() calls emitted repeated warnings.
    • New REPL also emits repeated PEP-765 related warnings.

    The PR fixed them all. Maybe backport it, as the first two issues are old?

    Reacted by Irit Katriel and Tomas R.
  17. tomasr8
    added 3 commits that reference this issue on Apr 13, 2025

    [3.13] pythongh-131927: Prevent emitting optimizer warnings twice in …

    5c30078

    [3.13] pythongh-131927: Prevent emitting optimizer warnings twice in …

    a0685cb

    [3.13] pythongh-131927: Prevent emitting optimizer warnings twice in …

    f0d8917
  18. serhiy-storchaka
    added a commit that references this issue on Apr 13, 2025

    [3.13] gh-131927: Prevent emitting compiler warnings twice (GH-131993) (

    4ff5d88
  19. serhiy-storchaka commented on Oct 6, 2025

    @serhiy-storchaka
    serhiy-storchaka
    on Oct 6, 2025
    Member
    More actions

    I realized that this was incorrect solution. See #139640.

  20. serhiy-storchaka
    reopened this on Oct 14, 2025
  21. serhiy-storchaka commented on Oct 14, 2025

    @serhiy-storchaka
    serhiy-storchaka
    on Oct 14, 2025
    Member
    More actions

    #139642 and #139719 are two alternative solutions. The former makes ast.parse() not emitting warnings. The simply silences it in the REPR (the original solution by @tomasr8). It may be incomplete because we may need to silence warnings in other places of the stdlib, not mention a third-party code.

  22. ncoghlan commented on Oct 29, 2025

    @ncoghlan
    ncoghlan
    on Oct 29, 2025
    Contributor
    More actions

    @serhiy-storchaka Based on the discussion in #139640, I posted an approving review on #139642, so I think we can close #139719 in favour of the more straightforward (and comprehensive) solution.

  23. serhiy-storchaka
    added a commit that references this issue on Oct 30, 2025

    gh-131927: Do not emit PEP 765 warnings in ast.parse() (GH-139642)

    ad0a3f7
  24. miss-islington
    added a commit that references this issue on Oct 30, 2025

    pythongh-131927: Do not emit PEP 765 warnings in ast.parse() (pythonG…

    c4862da
  25. serhiy-storchaka
    closed this as completedon Oct 30, 2025
  26. serhiy-storchaka
    added a commit that references this issue on Oct 30, 2025

    [3.14] gh-131927: Do not emit PEP 765 warnings in ast.parse() (GH-139642

    a7cfe86
  27. StanFromIreland
    added a commit that references this issue on Dec 6, 2025

    pythongh-131927: Do not emit PEP 765 warnings in ast.parse() (pythonG…

    efb8be8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.12only security fixesonly security fixes3.13only security fixesonly security fixes3.14bugs and security fixesbugs and security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.