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
8.0 s
LLM review
Reviewed by claude-haiku-5-5 (Anthropic): 8 of 8 warn and critical signals; 8 demoted to info.
Disclude version
4.0.0
Scanned (UTC)
2026-10-14 18:21

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.93 A debug-build local variable named `main` is initialized from borrow_main_greenlet().
    Reasoning

    The flagged text is a declaration `PyGreenlet* main(state->borrow_main_greenlet());` inside a debug-only #ifndef NDEBUG block. It declares a local variable named main and does not call or recurse into a main function. The rule matched on the identifier name alone, so this is a false positive.

  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)
    dismissed LLM, confidence 0.95 A greenlet unit test takes its own frame with sys._getframe(0) to check f_back.
    Reasoning

    sys._getframe(0) in a greenlet test function is used to pass a frame object to the parent and check f_back. This is ordinary test code for the greenlet library and shows no malicious or obfuscated behavior.

  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)
    dismissed LLM, confidence 0.95 A greenlet test switches a frame object obtained from sys._getframe(0) to another greenlet.
    Reasoning

    The test passes sys._getframe(0) to another greenlet via switch to exercise frame handling across greenlets. This is standard test scaffolding with no sign of malicious intent.

  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):
    dismissed LLM, confidence 0.95 A nested test helper passes its frame via sys._getframe(0) to inner().
    Reasoning

    The nested outer/inner functions pass sys._getframe(0) between them as part of a greenlet frame test. This is normal introspection in a test suite.

  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()
    dismissed LLM, confidence 0.92 A test opens its own source file and reads it without using the contents.
    Reasoning

    The code opens its own __file__ and calls f.read() with the result discarded, next to a comment about critical sections. It is a test that reads its own source for no evident reason, not a payload extractor. The result is never parsed or executed, so this is benign.

  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
    dismissed LLM, confidence 0.94 A tracing test context manager installs itself via sys.setprofile and saves the old profiler.
    Reasoning

    The context manager saves the previous profile function with sys.setprofile and installs itself as the profiler, a standard pattern for testing greenlet tracing. It is not malicious.

  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():
    dismissed LLM, confidence 0.94 A tracing test context manager restores the previous profiler on exit.
    Reasoning

    __exit__ restores the saved profiler with sys.setprofile(self.oldtrace), which pairs with the __enter__ shown above. This is normal 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.80 A version test runs setup.py --version through os.popen using the current interpreter.
    Reasoning

    os.popen runs a command built from sys.executable and the setup.py path to read the package version. The command is constructed at runtime and is unquoted, so paths with spaces could break, but both inputs come from the test environment and no attacker-controlled data reaches it. The critical severity is overstated for this context.

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.0.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 .