PyPI / anyio / 4.15.1

anyio 4.15.1

Source
https://github.com/agronholm/anyio
Tag scanned
4.15.1
Compared with
4.15.0 (0 signals introduced since)
Files
105 scanned, 3 skipped (binary, oversized, or unrecognised)
Signals
0 critical · 0 warn · 7 info
Scan time
5.6 s
LLM review
Reviewed by claude-haiku-5-5 (Anthropic): 7 of 7 warn and critical signals; 7 demoted to info.
Disclude version
4.0.0
Scanned (UTC)
2026-10-14 18:12

Signals

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

  1. info critical → info by review frame-introspection src/anyio/_lazyimport.py:19:22

    `sys._getframe` — call-stack frame introspection — file also calls `sys.exit`/`exec`/`eval` (anti-analysis shape) (ast pass, confidence 0.85)

    def install_lazy_importer() -> bool:
        module_globals = sys._getframe(1).f_globals
        module_name = module_globals["__name__"]
        module_prefix = module_name + "."
    likely benign LLM, confidence 0.93 Lazy importer uses caller frame globals to install module __getattr__.
    Reasoning

    sys._getframe(1).f_globals is the standard idiom for installing a module-level lazy importer; the critical severity comes from the anti-analysis heuristic matching sys.exit/exec/eval elsewhere in the file, which is a weak co-signal here. Legitimate anyio code.

  2. info critical → info by review frame-introspection src/anyio/_lazyimport.py:71:22

    `sys._getframe` — call-stack frame introspection — file also calls `sys.exit`/`exec`/`eval` (anti-analysis shape) (ast pass, confidence 0.85)

    def fix_package_names() -> None:
        module_globals = sys._getframe(1).f_globals
        module_prefix = module_globals["__name__"] + "."
        del module_globals[fix_package_names.__name__]
    likely benign LLM, confidence 0.93 Fixes package names by reading the caller's module globals.
    Reasoning

    Retrieves the calling module's globals to prefix package names and delete the helper function; ordinary module-introspection code in a well-known library.

  3. info critical → info by review frame-introspection src/anyio/_lazyimport.py:92:22

    `sys._getframe` — call-stack frame introspection — file also calls `sys.exit`/`exec`/`eval` (anti-analysis shape) (ast pass, confidence 0.85)

    def set_deprecated_aliases(aliases: dict[str, str]) -> None:
        module_globals = sys._getframe(1).f_globals
        module_name = module_globals["__name__"]
        del module_globals[set_deprecated_aliases.__name__]
    likely benign LLM, confidence 0.93 Sets deprecated aliases using caller frame globals.
    Reasoning

    Reads caller globals to register deprecated aliases via a module __getattr__; standard library-style pattern with no payload or obfuscation.

  4. info warn → info by review dynamic-execution src/anyio/_lazyimport.py:120:12

    `compile` called on a non-literal expression (ast pass, confidence 0.70)

    
        tree = compile(source, module.__file__ or "", "exec", ast.PyCF_ONLY_AST)
        assert isinstance(tree, ast.Module)
        out: dict[str, tuple[str, str]] = {}
    likely benign LLM, confidence 0.85 Parses a module source file into an AST via compile with PyCF_ONLY_AST.
    Reasoning

    compile is used with ast.PyCF_ONLY_AST to parse a module's source file for static analysis of re-exports, not to execute it. The non-literal argument is expected for this purpose and the output is only parsed into an AST.

  5. info warn → info by review decoder-import-with-exec src/anyio/to_interpreter.py:71:17

    file imports decoder module(s) pickle and calls `exec`/`eval`/`compile` — multi-stage payload shape (ast pass, confidence 0.80)

    
        _run_func = compile(
            """
    import _interpqueues
    likely benign LLM, confidence 0.80 Compiles a code string for running in a subinterpreter using _interpqueues and pickle.
    Reasoning

    The compiled string is a source snippet that imports _interpqueues to run a function in a subinterpreter, which is the documented way anyio runs code in subinterpreters. The pickle co-import is for passing function payloads between interpreters, a legitimate mechanism here. The heuristic matches the shape but the context is a known library feature.

  6. info warn → info by review frame-introspection tests/conftest.py:178:17

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

        def no_other_refs() -> list[object]:
            return [sys._getframe(1).f_generator]
    
    elif sys.version_info >= (3, 11):
    likely benign LLM, confidence 0.90 Test helper that inspects a generator frame to verify no lingering references.
    Reasoning

    Test helper returning sys._getframe(1).f_generator to check for lingering references to generators; used for resource-leak testing, not malicious.

  7. info warn → info by review frame-introspection tests/conftest.py:187:17

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

        def no_other_refs() -> list[object]:
            return [sys._getframe(1)]
    likely benign LLM, confidence 0.90 Test helper capturing the caller frame for reference checks.
    Reasoning

    Test helper returning the caller frame to check references in tests; standard test-harness introspection with no malicious behavior.

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/agronholm/anyio anyio && cd anyio
git checkout 4.15.1
disclude scan --severity info --diff 4.15.0 .