PyPI / decorator / 5.3.1

decorator 5.3.1

Source
https://github.com/micheles/decorator
Tag scanned
5.3.1
Compared with
5.3.0 (0 signals introduced since)
Files
13 scanned, 4 skipped (binary, oversized, or unrecognised)
Signals
0 critical · 0 warn · 3 info
Scan time
4.2 s
LLM review
Reviewed by claude-haiku-5-5 (Anthropic): 3 of 3 warn and critical signals; 3 demoted to info.
Disclude version
4.0.0
Scanned (UTC)
2026-10-14 18:55

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/decorator/__init__.py:141:21

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

            try:
                frame = sys._getframe(3)
            except AttributeError:  # for IronPython and similar implementations
                callermodule = '?'
    likely benign LLM, confidence 0.93 Call-stack introspection via sys._getframe to determine the caller's module name inside a decorator-utility library.
    Reasoning

    This is the well-known `decorator` library. sys._getframe(3) is used to find the calling module's name so decorated functions keep the correct __module__. The AttributeError fallback is for IronPython and similar runtimes. The anti-analysis label comes only from the file also containing sys.exit/exec/eval, which a library that generates functions naturally does. Nothing here hides behaviour or reaches outside the process.

  2. info warn → info by review dynamic-execution src/decorator/__init__.py:173:20

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

            try:
                code = compile(src, filename, 'single')
                exec(code, evaldict)
            except Exception:
    likely benign LLM, confidence 0.92 Runtime compilation of a generated wrapper function whose source is built from the decorated function's signature.
    Reasoning

    compile(src, filename, 'single') builds the body of a wrapper function whose signature is generated at runtime to match the decorated function. The source is assembled from the function's own argument names, not from attacker-controlled input, and the code sits inside a try/except that reports errors. This is the documented way the decorator library preserves signatures.

  3. info warn → info by review dynamic-execution src/decorator/__init__.py:174:13

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

                code = compile(src, filename, 'single')
                exec(code, evaldict)
            except Exception:
                print('Error in generated code:', file=sys.stderr)
    likely benign LLM, confidence 0.92 exec of the generated wrapper code in a local namespace, paired with the compile call on the previous line.
    Reasoning

    exec runs the compiled wrapper in a dedicated evaldict namespace. This is the same generated-wrapper mechanism as the compile call on line 173. The payload is built from signature metadata of local functions, and there is no network access, decoding, or shell call, so it does not match a dropper pattern.

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/micheles/decorator decorator && cd decorator
git checkout 5.3.1
disclude scan --severity info --diff 5.3.0 .