PyPI / wrapt / 2.5.2rc1

wrapt 2.5.2rc1

Source
https://github.com/GrahamDumpleton/wrapt
Tag scanned
2.5.2rc1
Compared with
2.5.1 (0 signals introduced since)
Files
166 scanned, 47 skipped (binary, oversized, or unrecognised)
Signals
0 critical · 0 warn · 26 info
Scan time
18.7 s
LLM review
Reviewed by claude-haiku-5-5 (Anthropic): 26 of 26 warn and critical signals; 26 demoted to info.
Disclude version
4.0.0
Scanned (UTC)
2026-10-19 18:11

Signals

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

  1. info warn → info by review frame-introspection blog/09-performance-overhead-of-using-decorators.md:103:1

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

    
    sys.setprofile(tracer)
    
    function()
    likely benign LLM, confidence 0.85 Markdown tutorial snippet demonstrating sys.setprofile for measuring decorator overhead.
    Reasoning

    A blog post's embedded Python example calls sys.setprofile(tracer) to illustrate profiling overhead. This is documentation, not executed code.

  2. info warn → info by review frame-introspection blog/10-performance-overhead-when-applying-decorators-to-methods.md:90:1

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

    
    sys.setprofile(tracer)
    
    instance.method()
    likely benign LLM, confidence 0.85 Markdown tutorial snippet using sys.setprofile to trace a method call.
    Reasoning

    Same pattern as the sibling blog post: an educational example of profiling a method call with sys.setprofile. No malicious behaviour is shown.

  3. info critical → info by review dynamic-import blog/13-ordering-issues-when-monkey-patching-in-python.md:105:9

    [embedded python] `__import__` called on a non-literal expression (ast pass, confidence 0.70)

        def _load_and_execute(target_module):
            __import__(name)
            patch_module = sys.modules[name]
            getattr(patch_module, 'apply_patch')(target_module)
    likely benign LLM, confidence 0.80 Blog example of dynamically importing a patch module by name during monkey patching.
    Reasoning

    An illustrative monkey-patching example in a blog post loads a module by name with __import__ and applies a patch. The name is a parameter in a tutorial, not an obfuscated payload.

  4. info critical → info by review dynamic-execution docs/conf.py:55:9

    `exec` at module scope (runs on import) on a non-literal expression (ast pass, confidence 0.80)

        if isinstance(node, ast.FunctionDef) and node.name == "_format_version":
            exec(compile(ast.Module(body=[node], type_ignores=[]), "<v>", "exec"), _ns)
        elif isinstance(node, ast.Assign) and any(
            getattr(t, "id", None) in ("__version_info__", "__version__")
    likely benign LLM, confidence 0.85 Docs config executes extracted version-helper AST nodes to derive the package version.
    Reasoning

    Sphinx conf.py parses its own source with ast, extracts a _format_version function and version assignments, then execs them into a namespace to read the version without importing the package. The compiled source comes from the local file's AST, a common and legitimate technique.

  5. info critical → info by review dynamic-execution docs/conf.py:55:14

    `compile` at module scope (runs on import) on a non-literal expression (ast pass, confidence 0.80)

        if isinstance(node, ast.FunctionDef) and node.name == "_format_version":
            exec(compile(ast.Module(body=[node], type_ignores=[]), "<v>", "exec"), _ns)
        elif isinstance(node, ast.Assign) and any(
            getattr(t, "id", None) in ("__version_info__", "__version__")
    likely benign LLM, confidence 0.85 compile() of an AST module built from the project's own version definitions.
    Reasoning

    This is the compile() half of the same AST-extraction version-reading pattern, operating on the project's own source tree.

  6. info critical → info by review dynamic-execution docs/conf.py:60:9

    `exec` at module scope (runs on import) on a non-literal expression (ast pass, confidence 0.80)

        ):
            exec(compile(ast.Module(body=[node], type_ignores=[]), "<v>", "exec"), _ns)
    
    version_info = _ns["__version_info__"]
    likely benign LLM, confidence 0.85 Second exec in the docs version-extraction logic, reading __version_info__ from a namespace.
    Reasoning

    The exec of the extracted version nodes into _ns, followed by reading __version_info__ from the namespace, is the same benign self-introspection for version metadata.

  7. info critical → info by review dynamic-execution docs/conf.py:60:14

    `compile` at module scope (runs on import) on a non-literal expression (ast pass, confidence 0.80)

        ):
            exec(compile(ast.Module(body=[node], type_ignores=[]), "<v>", "exec"), _ns)
    
    version_info = _ns["__version_info__"]
    likely benign LLM, confidence 0.85 compile() paired with the exec in the docs version-reading logic.
    Reasoning

    The compile call supports the same benign version-extraction flow in the Sphinx config.

  8. info warn → info by review dynamic-attribute src/wrapt/patches.py:103:32

    reach-by-name through `vars` (ast pass, confidence 0.60)

                        if attribute in vars(cls):
                            return vars(cls)[attribute]
                    else:
                        return getattr(parent, attribute)
    likely benign LLM, confidence 0.90 Attribute lookup via vars(cls) during path resolution in the wrapt patching utility.
    Reasoning

    wrapt is a decorator and wrapping library, and vars(cls)/getattr is standard attribute resolution for patching. Name-based attribute access is inherent to its function, not obfuscation.

  9. info warn → info by review dynamic-attribute src/wrapt/patches.py:348:13

    reach-by-name through `vars.get` (ast pass, confidence 0.60)

        parent = resolve_path(module, path)[2]
        prior = vars(parent).get(attribute, MISSING)
        wrapper = AttributeWrapper(prior, attribute, factory, args, kwargs)
        apply_patch(parent, attribute, wrapper)
    likely benign LLM, confidence 0.90 Fetches the original attribute from a parent's __dict__ before applying a wrapper.
    Reasoning

    Reading the prior attribute value through vars(parent).get before wrapping it is the normal mechanism for a monkey-patching library to preserve the original.

  10. info warn → info by review dynamic-attribute src/wrapt/patches.py:840:17

    reach-by-name through `vars` (ast pass, confidence 0.60)

                (
                    vars(cls)[attribute]
                    for cls in inspect.getmro(owner)[1:]
                    if attribute in vars(cls)
    likely benign LLM, confidence 0.90 MRO traversal using vars(cls) to locate an attribute definition.
    Reasoning

    Walking the MRO with vars(cls) to find an attribute is standard descriptor and inheritance handling in a proxy/patching library.

  11. info critical → info by review dynamic-import src/wrapt/proxies.py:379:18

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

        def _import():
            module = __import__(name, fromlist=[""])
    
            if attribute is not None:
    likely benign LLM, confidence 0.85 Lazy module import helper in the wrapt object proxy implementation.
    Reasoning

    wrapt's lazy import helper calls __import__(name, fromlist=[""]) to load a module on demand. The name comes from the library's own lazy-proxy machinery, which is a normal pattern.

  12. info critical → info by review dynamic-execution tests/core/test_adapter.py:18:1

    `exec` at module scope (runs on import) on a non-literal expression (ast pass, confidence 0.80)

    decorators = types.ModuleType("decorators")
    exec(DECORATORS_CODE, decorators.__dict__, decorators.__dict__)
    likely benign LLM, confidence 0.80 Test setup that execs a constant source string into a synthetic decorators module.
    Reasoning

    A test fixture builds a types.ModuleType and execs a DECORATORS_CODE string constant defined in the test file, to create decorators for adapter tests. This is a test-harness pattern, not a payload.

  13. info critical → info by review dynamic-execution tests/core/test_adapter_annotations.py:26:1

    `exec` at module scope (runs on import) on a non-literal expression (ast pass, confidence 0.80)

    decorators = types.ModuleType("decorators")
    exec(DECORATORS_CODE, decorators.__dict__, decorators.__dict__)
    likely benign LLM, confidence 0.80 Test fixture exec of a local decorators source string for annotation adapter tests.
    Reasoning

    The same test-fixture pattern of exec-ing a local DECORATORS_CODE constant into a ModuleType, used for annotation tests.

  14. info critical → info by review dynamic-execution tests/core/test_adapter_kwonly.py:18:1

    `exec` at module scope (runs on import) on a non-literal expression (ast pass, confidence 0.80)

    decorators = types.ModuleType("decorators")
    exec(DECORATORS_CODE, decorators.__dict__, decorators.__dict__)
    likely benign LLM, confidence 0.80 Test fixture exec of decorators source for keyword-only adapter tests.
    Reasoning

    Keyword-only adapter tests use the same local exec of a constant decorators source, consistent with a test harness.

  15. info critical → info by review dynamic-execution tests/core/test_class.py:16:1

    `exec` at module scope (runs on import) on a non-literal expression (ast pass, confidence 0.80)

    decorators = types.ModuleType("decorators")
    exec(DECORATORS_CODE, decorators.__dict__, decorators.__dict__)
    likely benign LLM, confidence 0.80 Test fixture exec of a decorators source string for class-decorator tests.
    Reasoning

    The class tests exec the same local DECORATORS_CODE constant into a synthetic module. The pattern is consistent with a test fixture rather than a dropper.

  16. info critical → info by review dynamic-import tests/core/test_find_wrapper.py:90:27

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

    
            wrapt.apply_patch(__import__(__name__), "function_closure", their_closure)
    
            current = wrapt.resolve_path(__name__, "function_closure")[2]
    likely benign LLM, confidence 0.90 Test helper that imports its own module via __import__(__name__) to patch a function.
    Reasoning

    `__import__(__name__)` imports the test module itself to pass it to wrapt.apply_patch. This is a common self-reference idiom in test code, with no network, decoding, or shell activity in the snippet.

  17. info critical → info by review dynamic-import tests/core/test_find_wrapper.py:219:27

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

    
            wrapt.apply_patch(__import__(__name__), "function_replaced", original)
    
            current = wrapt.resolve_path(__name__, "function_replaced")[2]
    likely benign LLM, confidence 0.90 Test code using __import__(__name__) to obtain its own module for patching in the wrapt test suite.
    Reasoning

    Same self-import pattern as the other finding in this file: __import__(__name__) passed to wrapt.apply_patch in a unit test. Nothing suggests malicious intent.

  18. info critical → info by review dynamic-execution tests/core/test_function.py:16:1

    `exec` at module scope (runs on import) on a non-literal expression (ast pass, confidence 0.80)

    decorators = types.ModuleType("decorators")
    exec(DECORATORS_CODE, decorators.__dict__, decorators.__dict__)
    likely benign LLM, confidence 0.88 Test fixture that execs a locally defined decorators code string into a synthetic module.
    Reasoning

    The module-level exec runs a DECORATORS_CODE string into a ModuleType namespace, which is a known wrapt test idiom for generating decorator fixtures. The string is defined in the same test suite, and the snippet shows no network or shell calls.

  19. info critical → info by review dynamic-execution tests/core/test_inner_classmethod.py:16:1

    `exec` at module scope (runs on import) on a non-literal expression (ast pass, confidence 0.80)

    decorators = types.ModuleType("decorators")
    exec(DECORATORS_CODE, decorators.__dict__, decorators.__dict__)
    likely benign LLM, confidence 0.88 Test fixture executing a local decorators code constant to build classmethod test decorators.
    Reasoning

    Identical fixture pattern: exec of a local DECORATORS_CODE constant into a types.ModuleType namespace inside the wrapt test suite. This is a deliberate way to build decorator variants for testing.

  20. info critical → info by review dynamic-execution tests/core/test_inner_staticmethod.py:16:1

    `exec` at module scope (runs on import) on a non-literal expression (ast pass, confidence 0.80)

    decorators = types.ModuleType("decorators")
    exec(DECORATORS_CODE, decorators.__dict__, decorators.__dict__)
    likely benign LLM, confidence 0.88 Test fixture executing a local decorators code constant to build staticmethod test decorators.
    Reasoning

    Same DECORATORS_CODE exec-into-ModuleType fixture pattern used across wrapt's tests. The code is a local constant, not external input.

  21. info critical → info by review dynamic-execution tests/core/test_instancemethod.py:16:1

    `exec` at module scope (runs on import) on a non-literal expression (ast pass, confidence 0.80)

    decorators = types.ModuleType("decorators")
    exec(DECORATORS_CODE, decorators.__dict__, decorators.__dict__)
    likely benign LLM, confidence 0.88 Test fixture executing a local decorators code constant to build instance method test decorators.
    Reasoning

    Identical DECORATORS_CODE exec fixture in a wrapt unit test. The exec input is static test code defined in the same suite.

  22. info critical → info by review dynamic-execution tests/core/test_nested_function.py:16:1

    `exec` at module scope (runs on import) on a non-literal expression (ast pass, confidence 0.80)

    decorators = types.ModuleType("decorators")
    exec(DECORATORS_CODE, decorators.__dict__, decorators.__dict__)
    likely benign LLM, confidence 0.88 Test fixture executing a local decorators code constant to build nested function test decorators.
    Reasoning

    Same DECORATORS_CODE exec pattern as the other wrapt test modules. It runs trusted, in-repo test code into an isolated module namespace.

  23. info critical → info by review dynamic-execution tests/core/test_object_proxy.py:23:1

    `exec` at module scope (runs on import) on a non-literal expression (ast pass, confidence 0.80)

    objects = types.ModuleType("objects")
    exec(OBJECTS_CODE, objects.__dict__, objects.__dict__)
    likely benign LLM, confidence 0.88 Test fixture executing a local objects code constant to build proxy test objects.
    Reasoning

    exec of a local OBJECTS_CODE string into a ModuleType namespace for object proxy testing. This is a standard fixture technique in wrapt's test suite with no external input or malicious signals.

  24. info critical → info by review dynamic-execution tests/core/test_outer_classmethod.py:18:1

    `exec` at module scope (runs on import) on a non-literal expression (ast pass, confidence 0.80)

    decorators = types.ModuleType("decorators")
    exec(DECORATORS_CODE, decorators.__dict__, decorators.__dict__)
    likely benign LLM, confidence 0.88 Test fixture executing a local decorators code constant to build outer classmethod test decorators.
    Reasoning

    Same DECORATORS_CODE exec-into-module fixture in a wrapt test. The source is an in-repo constant and the snippet shows no harmful behavior.

  25. info critical → info by review dynamic-execution tests/core/test_outer_staticmethod.py:16:1

    `exec` at module scope (runs on import) on a non-literal expression (ast pass, confidence 0.80)

    decorators = types.ModuleType("decorators")
    exec(DECORATORS_CODE, decorators.__dict__, decorators.__dict__)
    likely benign LLM, confidence 0.88 Test fixture executing a local decorators code constant to build outer staticmethod test decorators.
    Reasoning

    Same DECORATORS_CODE exec fixture used throughout wrapt's test suite. The code is static test input.

  26. info critical → info by review dynamic-execution tests/core/test_type_module_attribute.py:31:1

    `exec` at module scope (runs on import) on a non-literal expression (ast pass, confidence 0.80)

    objects = types.ModuleType("objects")
    exec(OBJECTS_CODE, objects.__dict__, objects.__dict__)
    likely benign LLM, confidence 0.88 Test fixture executing a local objects code constant to build module attribute test objects.
    Reasoning

    exec of a local OBJECTS_CODE constant into a ModuleType namespace, matching the other wrapt test fixtures. It is deliberate test scaffolding, not an obfuscated payload.

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/GrahamDumpleton/wrapt wrapt && cd wrapt
git checkout 2.5.2rc1
disclude scan --severity info --diff 2.5.1 .