Skip to content

Fix consider-using-sys-exit for exit/quit bound in an enclosing scope - #11752

Open
udsy19 wants to merge 2 commits into
pylint-dev:mainfrom
udsy19:fix/consider-using-sys-exit-enclosing-scope
Open

udsy19 wants to merge 2 commits into
pylint-dev:mainfrom
udsy19:fix/consider-using-sys-exit-enclosing-scope

Conversation

@udsy19

@udsy19 udsy19 commented Oct 29, 2026

Copy link
Copy Markdown
Contributor

Steps to reproduce

def outer():
    from sys import exit

    def inner():
        exit(0)

    return inner

Current behavior

b.py:5:8: R1722: Consider using 'sys.exit' instead (consider-using-sys-exit)

That exit already is sys.exit. The same happens for quit = sys.exit or a local def exit(...) in an enclosing function.

Conversely, from sys import exit in a function also silences a call to the real builtin quit() in that function (false negative).

Cause

_check_quit_exit_call only exempted an exit that was an Import/ImportFrom in node.scope() or node.root(), so it never looked at enclosing function scopes. It also always looked up "exit", whatever name was being called.

Fix

Resolve the called name with lookup() and emit only when it resolves to the builtins (utils.is_builtin_object), so any binding in an enclosing scope exempts it, for the name actually called. _has_exit_in_scope had no other callers and is removed.

Note: any non-builtin binding now exempts the call, not only an import, e.g. a user-defined def exit(): .... The message is about the site builtin, so that seems right to me, but happy to narrow it to imports/assignments from sys if you prefer.

Tests

New functional test consider_using_sys_exit_enclosing_scope (three exempt cases, two still-flagged cases including the quit() false negative). On main it fails with unexpected messages and one missing message; with the fix it passes, as do the existing consider_using_sys_exit* tests. tests/test_functional.py + tests/checkers/ pass locally.

…sing scope

The exemption for an imported ``exit`` only inspected the current scope
and the module scope, so ``from sys import exit`` in an outer function
was ignored when ``exit()`` was called from a nested function. It also
only looked up ``exit``, so importing ``exit`` hid calls to the builtin
``quit``.

Resolve the called name with a scope lookup and only emit when it
resolves to the builtins module.

Signed-off-by: Udaya Tejas <udayatejas2004@gmail.com>
@udsy19
udsy19 force-pushed the fix/consider-using-sys-exit-enclosing-scope branch from 9680d9d to fa2edcf Compare October 29, 2026 00:28
Signed-off-by: Udaya Tejas <udayatejas2004@gmail.com>
@codecov

codecov Bot commented Oct 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.52%. Comparing base (278fc1b) to head (cd058cc).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main   #11752      +/-   ##
==========================================
- Coverage   94.53%   94.52%   -0.01%     
==========================================
  Files         187      187              
  Lines       21174    21169       -5     
  Branches     4698     4698              
==========================================
- Hits        20016    20011       -5     
  Misses        690      690              
  Partials      468      468              
Files with missing lines Coverage Δ
pylint/checkers/refactoring/refactoring_checker.py 97.04% <100.00%> (-0.02%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions

Copy link
Copy Markdown
Contributor

🤖 Effect of this PR on checked open source code: 🤖

Effect on astropy:

Changed messages:

Details
  1. too-many-ancestors:
    message: Too many ancestors (22/7) → Too many ancestors (23/7)
  2. too-many-ancestors:
    message: Too many ancestors (27/7) → Too many ancestors (28/7)
  3. too-many-ancestors:
    message: Too many ancestors (23/7) → Too many ancestors (22/7)
  4. too-many-ancestors:
    message: Too many ancestors (28/7) → Too many ancestors (27/7)

Removed messages:

Details
  1. attribute-defined-outside-init:
    Attribute 'lineno' defined outside init
    https://github.com/astropy/astropy/blob/006f4960ab7311b83c36ca66d5df70274419e144/astropy/extern/ply/yacc.py#L674
  2. attribute-defined-outside-init:
    Attribute 'lexpos' defined outside init
    https://github.com/astropy/astropy/blob/006f4960ab7311b83c36ca66d5df70274419e144/astropy/extern/ply/yacc.py#L675

Effect on django:

New messages:

Details
  1. invalid-name:
    Attribute name "MIGRATION_MODULES" doesn't conform to snake_case naming style
    https://github.com/django/django/blob/2f7f30c320b6517d31fb8852db1875ad3a6a774f/django/db/backends/base/creation.py#L85
  2. invalid-name:
    Attribute name "ALLOWED_HOSTS" doesn't conform to snake_case naming style
    https://github.com/django/django/blob/2f7f30c320b6517d31fb8852db1875ad3a6a774f/django/test/utils.py#L140
  3. invalid-name:
    Attribute name "DEBUG" doesn't conform to snake_case naming style
    https://github.com/django/django/blob/2f7f30c320b6517d31fb8852db1875ad3a6a774f/django/test/utils.py#L143
  4. invalid-name:
    Attribute name "MAILERS" doesn't conform to snake_case naming style
    https://github.com/django/django/blob/2f7f30c320b6517d31fb8852db1875ad3a6a774f/django/test/utils.py#L149
  5. invalid-name:
    Attribute name "EMAIL_BACKEND" doesn't conform to snake_case naming style
    https://github.com/django/django/blob/2f7f30c320b6517d31fb8852db1875ad3a6a774f/django/test/utils.py#L155

Effect on music21:

New messages:

Details
  1. invalid-name:
    Attribute name "id" doesn't conform to '[a-z_][A-Za-z0-9_]{2,30}$' pattern
    https://github.com/cuthbertLab/music21/blob/4e6d4d617cb0bb0259fe3c295276dd85dc07237e/music21/base.py#L609

Removed messages:

Details
  1. invalid-name:
    Attribute name "id" doesn't conform to '[a-z_][A-Za-z0-9_]{2,30}$' pattern
    https://github.com/cuthbertLab/music21/blob/4e6d4d617cb0bb0259fe3c295276dd85dc07237e/music21/prebase.py#L274

This comment was generated for commit cd058cc

@Pierre-Sassoulas Pierre-Sassoulas added the False Positive 🦟 A message is emitted but nothing is wrong with the code label Oct 29, 2026

This branch has not been deployed

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

Labels

False Positive 🦟 A message is emitted but nothing is wrong with the code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants