PyPI / greenlet / 3.5.6

greenlet 3.5.6

Source
https://github.com/python-greenlet/greenlet
Tag scanned
3.5.6
Compared with
3.5.5 (0 signals introduced since)
Files
107 scanned, 14 skipped (binary, oversized, or unrecognised)
Signals
0 critical · 0 warn · 8 info
Scan time
6.1 s
LLM review
Reviewed by claude-haiku-5-5 (Anthropic): 8 of 8 warn and critical signals; 8 demoted to info.
Disclude version
4.1.0
Scanned (UTC)
2026-10-22 00:01

Signals

Ordered by severity, then signals introduced in this release. Hidden characters are shown as ⟨U+…⟩.

  1. info warn → info by review recursive-main-call src/greenlet/TThreadStateDestroy.cpp:166:21

    `main` is called from within a function — recursion through main is an IOCCC pattern (ast pass, confidence 0.90)

    #ifndef NDEBUG
            PyGreenlet* main(state->borrow_main_greenlet());
            assert(main);
            assert(main->pimpl->thread_state() == nullptr);
    dismissed LLM, confidence 0.90 Debug-only local variable named `main` initialized from borrow_main_greenlet() in greenlet's thread state destructor.
    Reasoning

    The snippet is a C++ declaration `PyGreenlet* main(state->borrow_main_greenlet());` inside an NDEBUG-guarded debug assert block. The variable is named main and is a local declaration, not a recursive call to a main function. This is a false positive from a naming-based heuristic in a well-known project (greenlet).

  2. info warn → info by review frame-introspection src/greenlet/tests/test_greenlet.py:356:17

    `sys._getframe` — call-stack frame introspection (ast pass, confidence 0.70)

            def f1():
                f = sys._getframe(0) # pylint:disable=protected-access
                self.assertEqual(f.f_back, None)
                greenlet.getcurrent().parent.switch(f)
    likely benign LLM, confidence 0.95 Test helper retrieving its own frame via sys._getframe to check f_back.
    Reasoning

    sys._getframe in a unit test for greenlet frame handling is a normal introspection use in test code. No malicious context.

  3. info warn → info by review frame-introspection src/greenlet/tests/test_greenlet.py:968:25

    `sys._getframe` — call-stack frame introspection (ast pass, confidence 0.70)

            def inner():
                main.switch(sys._getframe(0))
    
            hub = RawGreenlet(outer)
    likely benign LLM, confidence 0.95 Test passes its frame object to another greenlet via switch.
    Reasoning

    sys._getframe(0) passed to a switch in a greenlet test; ordinary test scaffolding for frame passing.

  4. info warn → info by review frame-introspection src/greenlet/tests/test_greenlet.py:1013:19

    `sys._getframe` — call-stack frame introspection (ast pass, confidence 0.70)

            def outer():
                inner(sys._getframe(0))
    
            def inner(frame):
    likely benign LLM, confidence 0.95 Test nested function receives sys._getframe(0) from outer.
    Reasoning

    Same pattern as other test frame introspection in the greenlet test suite; no payload or evasion present.

  5. info warn → info by review dynamic-execution src/greenlet/tests/test_greenlet.py:1062:18

    `open(__file__)` — file reads its own source, common pattern for extracting payloads hidden in comments (ast pass, confidence 0.85)

                # critical sections to get suspended
                with open(__file__, "rt", encoding='utf-8') as f:
                    f.read()
    likely benign LLM, confidence 0.93 Test reads its own source file to exercise suspension in a critical section.
    Reasoning

    open(__file__) reading the test's own source in a greenlet test that checks critical sections. The read is a no-op with the result discarded; it is not payload extraction from comments.

  6. info warn → info by review frame-introspection src/greenlet/tests/test_tracing.py:105:25

    `sys.setprofile` — call-stack frame introspection (ast pass, confidence 0.70)

        def __enter__(self):
            self.oldtrace = sys.setprofile(self)
            return self.actions
    likely benign LLM, confidence 0.95 Context manager installing a profile hook to record test actions.
    Reasoning

    sys.setprofile used in a context manager to record tracing actions in greenlet tests. Standard profiling hook usage for tests.

  7. info warn → info by review frame-introspection src/greenlet/tests/test_tracing.py:109:9

    `sys.setprofile` — call-stack frame introspection (ast pass, confidence 0.70)

        def __exit__(self, *args):
            sys.setprofile(self.oldtrace)
    
    def tpt_callback():
    likely benign LLM, confidence 0.95 Context manager restoring the prior profile hook on exit.
    Reasoning

    Restoring the previous profile function in __exit__. Paired with the enter method; ordinary test cleanup.

  8. info critical → info by review dynamic-execution src/greenlet/tests/test_version.py:36:14

    `os.popen` called on a non-literal command — runtime-determined shell invocation (ast pass, confidence 0.85)

            invoke_setup = "%s %s --version" % (sys.executable, setup_py)
            with os.popen(invoke_setup) as f:
                sversion = f.read().strip()
    likely benign LLM, confidence 0.85 Test runs setup.py --version via os.popen to compare the package version.
    Reasoning

    os.popen on a command built from sys.executable and a setup.py path to read the package version. The command is built from trusted local paths in a test, not attacker input, so the shell call is legitimate though non-literal. Severity is critical in the scanner output but the context is benign.

Reproduce This Scan

Run disclude locally to verify. Add --format sarif for SARIF output. Add --llm (with an API key in the environment) to include the LLM review.

cargo install disclude --version 4.1.0
git clone https://github.com/python-greenlet/greenlet greenlet && cd greenlet
git checkout 3.5.6
disclude scan --severity info --diff 3.5.5 .