PyPI / cloudpickle / 3.1.2

cloudpickle 3.1.2

Source
https://github.com/cloudpipe/cloudpickle
Tag scanned
v3.1.2
Compared with
v3.1.1 (0 signals introduced since)
Files
24 scanned, 32 skipped (binary, oversized, or unrecognised)
Signals
0 critical · 0 warn · 7 info
Scan time
8.4 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:43

Signals

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

  1. info critical → info by review dynamic-import cloudpickle/cloudpickle.py:469:5

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

        # module.
        __import__(name)
        return sys.modules[name]
    likely benign LLM, confidence 0.85 Library helper that imports a module by its name during unpickling of dynamic modules.
    Reasoning

    This is the subimport helper that re-imports a module by name so that dynamically created modules can be restored during unpickling. Calling __import__ on a computed name is the expected mechanism in a serialization library, and the name is a module identifier rather than a payload. The residual concern is that the name comes from pickled data, which is inherent to cloudpickle's design and not evidence of obfuscation.

  2. info warn → info by review decoder-import-with-exec tests/cloudpickle_test.py:553:9

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

            """
            exec(textwrap.dedent(code), mod.__dict__)
            mod2 = pickle_depickle(mod, protocol=self.protocol)
            self.assertEqual(mod.x, mod2.x)
    likely benign LLM, confidence 0.90 Test executes generated module source and checks pickling round-trip behavior.
    Reasoning

    The test writes a source string, executes it into a module's namespace, then round-trips the module through pickle to check attribute equality. The base64/pickle imports are needed for the round-trip. This is ordinary test scaffolding for a pickling library, not a multi-stage payload.

  3. info warn → info by review dynamic-execution tests/cloudpickle_test.py:553:9

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

            """
            exec(textwrap.dedent(code), mod.__dict__)
            mod2 = pickle_depickle(mod, protocol=self.protocol)
            self.assertEqual(mod.x, mod2.x)
    likely benign LLM, confidence 0.90 Test uses exec to populate a dynamically created module from a test string.
    Reasoning

    exec runs a dedented string literal defined in the test to populate a dynamic module's dict. This is the intended way to build a dynamic module for the test, and the code is local to the test file.

  4. info warn → info by review dynamic-execution tests/cloudpickle_test.py:678:9

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

            """
            exec(textwrap.dedent(code), mod.__dict__)
    
            # This script will be ran in a separate child process. It will import
    likely benign LLM, confidence 0.90 Test exec of fixture source to build a module used in a subprocess pickling test.
    Reasoning

    The exec populates a module with test source before a child process is spawned to check import behavior. The code is a fixed test string, and the exec is an expected part of testing dynamic module pickling.

  5. info warn → info by review dynamic-execution tests/cloudpickle_test.py:1071:9

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

            """.format(tup=", ".join(names))
            exec(textwrap.dedent(code), d, d)
            f = d["f"]
            res = f()
    likely benign LLM, confidence 0.90 Test exec of a formatted function template to define a function for a closure test.
    Reasoning

    The exec runs formatted source from a test-defined template to build function f in a namespace dict, which is then called to check behavior. The template is generated locally from test-chosen names, not from external input.

  6. info critical → info by review dynamic-execution tests/cloudpickle_testpkg/_cloudpickle_testpkg/mod.py:50:1

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

    
    exec(code, vars(submodule_three))
    
    # What about a dynamic submodule inside a dynamic submodule inside an
    likely benign LLM, confidence 0.85 Test fixture package exec-ing source into a submodule namespace at import time to create dynamic submodules.
    Reasoning

    This is a test fixture package that builds dynamic submodules by exec-ing source strings at import time, which is what the test needs to exercise nested dynamic submodule pickling. Module-scope exec looks suspicious in isolation, but here it is a deliberate fixture in the library's own test package, with the code defined in the same repository.

  7. info warn → info by review dynamic-execution tests/generate_old_pickles.py:64:5

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

        """
        exec(s, vars(dynamic_module))
        assert dynamic_module.f(2, 1) == 3
        dump_obj(dynamic_module, "simple_module.pkl")
    likely benign LLM, confidence 0.90 Utility script that execs local source to build a dynamic module and dump it as a fixture pickle.
    Reasoning

    The script execs a local source string into a dynamic module's namespace, then dumps the module to a pickle file for backward-compatibility tests. This is a developer utility for generating fixtures, with no external input or network activity.

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/cloudpipe/cloudpickle cloudpickle && cd cloudpickle
git checkout v3.1.2
disclude scan --severity info --diff v3.1.1 .