PyPI / dill / 0.4.1

dill 0.4.1

Source
https://github.com/uqfoundation/dill
Artifact scanned
dill-0.4.1-py3-none-any.whl (wheel · 117.2 KB · SHA-256 1e1ce33e978a…)
Compared with
dill-0.4.0-py3-none-any.whl (0 signals introduced since)
Files
50 scanned, 4 skipped (binary, oversized, or unrecognised)
Signals
2 critical · 17 warn · 30 info
Scan time
29.7 s
LLM review
Reviewed by claude-haiku-5-5 (Anthropic): 33 of 49 warn and critical signals; 30 demoted to info.
Disclude version
4.3.0
Scanned (UTC)
2026-10-23 08:45

Signals

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

  1. critical dynamic-execution dill-0.4.1.data/scripts/get_gprof:63:15

    `os.system` called on a non-literal command — runtime-determined shell invocation (ast pass, confidence 0.85)

        try:
            res = os.system(msg)
        except Exception:
            print ("Please verify install of 'gprof2dot' to view profile graphs")
    inconclusive LLM, confidence 0.50 A dill script that runs a runtime-built shell command to invoke gprof2dot for profile graphs.
    Reasoning

    The file is a profiling-graph helper that calls os.system on msg, and its except branch tells the user to verify a gprof2dot install, which fits its purpose of invoking an external visualization tool. The severity is critical, but the snippet does not show how msg is built, so whether it carries untrusted input cannot be judged from here. This is a shell invocation with unknown inputs, and the verdict is a guess.

  2. critical dynamic-import dill/session.py:125:42

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

            for modname, name in main_module.__dict__.pop('__dill_imported_top_level'):
                main_module.__dict__[name] = __import__(modname)
        except KeyError:
            pass
  3. `exec` called on a non-literal expression (ast pass, confidence 0.70)

        for line in obj[:-1]:
            exec(line)
        # one-line generation of an instance
        try:
    likely benign LLM, confidence 0.65 A dill utility script that execs reconstruction lines for a profiled object instance.
    Reasoning

    This is a helper script shipped with dill that rebuilds a profiled object by executing lines it generated itself, in a one-line instance-generation routine. The exec target comes from the profile data the tool processes, not from network or encoded input. The pattern is a crude serialization shortcut rather than a clear dropper, but the source of obj is not shown, so some doubt remains.

  4. `eval` called on a non-literal expression (ast pass, confidence 0.70)

        try:
            obj = eval(obj[-1])
        except Exception:
            print ("Error processing object instance")
    likely benign LLM, confidence 0.65 A dill helper script that evals the final element of reconstruction data inside a try/except.
    Reasoning

    The eval is applied to the last element of the same object-reconstruction data used by the exec above, inside a try block that prints an error on failure. It is consistent with a developer utility parsing its own output. Eval of data is still risky, and the origin of obj is not visible in the snippet, so the verdict is not fully certain.

  5. warn frame-introspection dill/pointers.py:93:19

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

        ignore.add(id(ignore))
        ignore.add(id(sys._getframe()))  # this function
        ignore.add(id(sys._getframe(1))) # find_chain/find_backref_chain, likely
        gc.collect()
  6. warn frame-introspection dill/pointers.py:94:19

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

        ignore.add(id(sys._getframe()))  # this function
        ignore.add(id(sys._getframe(1))) # find_chain/find_backref_chain, likely
        gc.collect()
        while queue:
  7. warn dynamic-attribute dill/session.py:226:16

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

                warnings.warn(message + ".", PendingDeprecationWarning)
                if locals()[par]:  # the defaults are None and False
                    raise TypeError("both %r and %r arguments were used" % (par, old_par))
        refimported = kwds.pop('byref', refimported)
  8. warn dynamic-attribute dill/session.py:611:26

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

    ):
        setattr(_dill, name, globals()[name])
    del name
  9. warn dynamic-execution dill/source.py:60:13

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

        try: #FIXME: unsafe
            _ = eval("lambda %s : %s" % (lhs,rhs), globals(),locals())
        except Exception: _ = dummy
        # get code objects, for comparison
  10. warn dynamic-execution dill/source.py:82:18

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

            try: #FIXME: unsafe
                _f = eval("lambda %s : %s" % (_lhs,_rhs), globals(),locals())
            except Exception: _f = dummy
            # get code objects, for comparison
  11. warn dynamic-execution dill/source.py:397:23

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

                    lines, lnum = ["%s = __import__('%s', fromlist=['%s']).%s\n" % (name,module,name,name)], 0
                    obj = eval(lines[0].lstrip(name + ' = '))
                    lines, lnum = getsourcelines(obj, enclosing=enclosing)
  12. warn dynamic-execution dill/source.py:543:13

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

                # _ = eval(getsource(f, force=True)) #XXX: safer but less robust
                exec(getimportable(f, alias='_'), __globals__, __locals__)
            except Exception:
                raise ImportError('cannot import name ' + f.__name__)
  13. warn dynamic-execution dill/source.py:713:14

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

           #print(_str)
            try: exec(_str) #XXX: check if == obj? (name collision)
            except ImportError: #XXX: better top-down or bottom-up recursion?
                _head = head.rsplit(".",1)[0] #(or get all, then compare == obj?)
  14. warn decoder-import-with-exec dill/temp.py:71:5

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

        local = {}
        exec(source, local)
        _ = eval("%s" % alias, local)
        return _
  15. warn dynamic-execution dill/temp.py:71:5

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

        local = {}
        exec(source, local)
        _ = eval("%s" % alias, local)
        return _
  16. warn dynamic-execution dill/temp.py:72:9

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

        exec(source, local)
        _ = eval("%s" % alias, local)
        return _
  17. warn dynamic-execution dill/temp.py:220:5

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

        local = {}
        exec(source, local)
        _ = eval("%s" % alias, local)
        return _
  18. warn dynamic-execution dill/temp.py:221:9

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

        exec(source, local)
        _ = eval("%s" % alias, local)
        return _
  19. warn frame-introspection dill/tests/test_detect.py:19:9

    `inspect.currentframe` — call-stack frame introspection (ast pass, confidence 0.70)

    def test_bad_things():
        f = inspect.currentframe()
        assert baditems(f) == [f]
        #assert baditems(globals()) == [f] #XXX
  20. info critical → info by review dynamic-import dill/__diff.py:220:11

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

        before = set(sys.modules.keys())
        mod = __import__(*args, **kwds)
        after = set(sys.modules.keys()).difference(before)
        for m in after:
    likely benign LLM, confidence 0.85 A pass-through __import__ wrapper that records newly imported modules.
    Reasoning

    The wrapper forwards arbitrary args to __import__ inside a helper that records module imports for dill's diff utility. The arguments come from the caller's own import statements, not from untrusted input, so this is a legitimate import-tracking hook.

  21. info critical → info by review builtins-write dill/__diff.py:226:1

    `builtins.__import__ = ...` — patches a built-in for every importer of this module (ast pass, confidence 0.95)

    
    builtins.__import__ = _imp
    if hasattr(builtins, "_"):
        del builtins._
    likely benign LLM, confidence 0.80 Temporarily replaces builtins.__import__ with a tracking hook in the diff utility.
    Reasoning

    The hook replaces builtins.__import__ temporarily to track imports, then removes the leftover '_' name. It is a deliberate, scoped monkeypatch typical of a diagnostic tool, though it is worth noting that it is global while active.

  22. info critical → info by review frame-introspection dill/_dill.py:213:31

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

                # Use the calling frame's module
                self.__module__ = inspect.currentframe().f_back.f_globals['__name__']
            else:
                self.__module__ = module_name # pragma: no cover
    dismissed LLM, confidence 0.90 Reads the calling frame's module name to set __module__ on an object.
    Reasoning

    Reading the caller's frame globals to obtain __name__ is a standard way to set a default module name. The sys.exit/exec/eval co-occurrence is generic in a large library and is not an anti-analysis shape here.

  23. info warn → info by review dynamic-execution dill/_dill.py:596:12

    `marshal.loads` deserializes Python bytecode from bytes — code-object sink (ast pass, confidence 0.75)

    def _unmarshal(string):
        return marshal.loads(string)
    
    def _load_type(name):
    likely benign LLM, confidence 0.80 Unmarshals code-object bytes as part of dill's serialization format.
    Reasoning

    dill is a serializer whose purpose is to save and restore code objects, so marshal.loads on bytes it produced is expected. Loading untrusted pickles is a known risk of the library's design rather than hidden malicious behavior.

  24. info warn → info by review decoder-import-with-exec dill/_dill.py:980:12

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

    def _eval_repr(repr_str):
        return eval(repr_str)
    
    def _create_array(f, args, state, npdict=None):
    likely benign LLM, confidence 0.75 Evaluates a stored repr string to reconstruct an object when loading.
    Reasoning

    eval of a repr string is used to rebuild numpy-style objects during deserialization. It is a known design choice in dill and carries the usual risk of deserializing untrusted data, with no sign of a staged payload.

  25. info warn → info by review dynamic-execution dill/_dill.py:980:12

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

    def _eval_repr(repr_str):
        return eval(repr_str)
    
    def _create_array(f, args, state, npdict=None):
    likely benign LLM, confidence 0.75 Same repr-string eval used to reconstruct objects during loading.
    Reasoning

    This is the same eval of a repr string as the sibling finding. It serves dill's reconstruction path and is not an attacker-controlled dropper.

  26. info critical → info by review dynamic-import dill/_dill.py:1012:26

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

                try:
                    module = __import__(names[0])
                except ImportError:
                    pass
    likely benign LLM, confidence 0.85 Dynamically imports a module by name while resolving a pickled reference.
    Reasoning

    The import resolves a module name recorded in the serialized data, guarded by try/except ImportError. This is ordinary dynamic module lookup for pickled references.

  27. info critical → info by review dynamic-execution dill/_dill.py:1038:16

    `eval` called on a constructed string (ast pass, confidence 0.80)

            attr = repr_str.split("'")[3]
            return eval(attr+'.__dict__["'+name+'"]')
        except Exception:
            try:
    likely benign LLM, confidence 0.70 Evaluates a constructed attribute-access expression to locate a named object.
    Reasoning

    The eval builds an attribute path from names taken from the serialized reference and is wrapped in an exception handler. This is a lookup mechanism, though eval on data-derived strings is risky when the input is untrusted.

  28. info critical → info by review dynamic-import dill/_dill.py:1065:33

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

                obj = items[-1]
                submodule = getattr(__import__(module, None, None, [obj]), obj)
                if isinstance(submodule, (ModuleType, type)):
                    return submodule
    likely benign LLM, confidence 0.85 Imports a module and retrieves an attribute to resolve a referenced object.
    Reasoning

    The code imports a module and then fetches an attribute from it to locate a referenced object, with a type check on the result. This is standard name resolution in dill.

  29. info critical → info by review dynamic-import dill/_dill.py:1068:20

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

                    return submodule
                return __import__(import_name, None, None, [obj])
            else:
                return __import__(import_name)
    likely benign LLM, confidence 0.85 Fallback __import__ used to resolve a dotted object reference.
    Reasoning

    This is the fallback import of a module path during object lookup, inside dill's resolution logic. It shows no payload behavior.

  30. info critical → info by review dynamic-import dill/_dill.py:1070:20

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

            else:
                return __import__(import_name)
        except (ImportError, AttributeError, KeyError):
            if safe:
    likely benign LLM, confidence 0.85 Final import attempt in the name-resolution fallback chain.
    Reasoning

    This is the final import in the lookup chain, with ImportError and AttributeError handled explicitly. It is normal module resolution.

  31. info warn → info by review decoder-import-with-exec dill/_objects.py:239:17

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

    # types module (part of CH 8)
    a['CodeType'] = compile('','','exec')
    a['DictProxyType'] = type.__dict__
    a['DictProxyType2'] = _newclass.__dict__
    dismissed LLM, confidence 0.85 Compiles an empty string to obtain the CodeType type for a table of built-in types.
    Reasoning

    compile('','','exec') produces an empty code object only to obtain its CodeType, and the surrounding code builds a table of built-in type samples. No payload is decoded or run.

  32. info warn → info by review decoder-decompress-payload dill/_objects.py:460:27

    file imports decoder module(s) codecs, zlib, gzip, bz2 and calls `.decompress()` — embedded payload decompressed at runtime (ast pass, confidence 0.75)

    x['ZlibCompressType'] = zlib.compressobj()
    x['ZlibDecompressType'] = zlib.decompressobj()
    # file formats (CH 13)
    x['CSVReaderType'] = csv.reader(_cstrI)
    dismissed LLM, confidence 0.85 Instantiates zlib decompressor objects solely to record their types.
    Reasoning

    zlib.decompressobj() is instantiated only to capture the type of a compression object for a registry of built-in types. It decompresses nothing.

  33. info warn → info by review dynamic-attribute dill/_shims.py:174:12

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

        """
        func = globals().get(name)
        if func is not None:
            _dill.__dict__[name] = func
    likely benign LLM, confidence 0.85 Looks up a module-level function by name to copy it into dill's namespace.
    Reasoning

    globals().get(name) looks up a function by name within the module's own namespace in order to re-export it. The name is internal, so this is a benign reflection pattern.

  34. info critical → info by review dynamic-execution dill/objtypes.py:18:5

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

    for _type in objects.keys():
        exec("%s = type(objects['%s'])" % (_type,_type))
        
    del objects
    likely benign LLM, confidence 0.80 Generates module-level type-name aliases from a fixed internal dictionary.
    Reasoning

    The exec builds type-name assignments from the keys of a fixed internal objects dict at import time. The inputs are static library data rather than external input, so this is a legitimate code-generation idiom.

  35. info warn → info by review dynamic-execution dill/tests/test_module.py:72:12

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

    def get_lambda(str, **kwarg):
        return eval(str, kwarg, None)
    
    obj = get_lambda('lambda x: math.exp(x)', math=math)
    likely benign LLM, confidence 0.90 Test helper that evals a lambda source string to verify dill round-tripping.
    Reasoning

    eval of a string built from a lambda expression inside dill's own test helper; the input is a test literal, not attacker-controlled. Legitimate test of serialization of lambdas.

  36. info warn → info by review dynamic-attribute dill/tests/test_session.py:42:24

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

                for obj in ('json', 'url', 'local_mod', 'sax', 'dom'):
                    assert globals()[obj].__name__ in sys.modules
                assert 'calendar' in sys.modules and 'cmath' in sys.modules
                import calendar, cmath
    likely benign LLM, confidence 0.90 Test checks module presence by name lookup in globals.
    Reasoning

    Reaching module names through globals() in a session-restore test checks that modules were restored; no malicious effect.

  37. info warn → info by review dynamic-attribute dill/tests/test_session.py:47:24

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

                for obj in ('Calendar', 'isleap'):
                    assert globals()[obj] is sys.modules['calendar'].__dict__[obj]
                assert __main__.day_name.__module__ == 'calendar'
                if refimported:
    likely benign LLM, confidence 0.90 Test verifies restored names via globals() lookup.
    Reasoning

    Same pattern as the other session test: globals lookup of known names to verify session state after load.

  38. info warn → info by review dynamic-attribute dill/tests/test_session.py:126:20

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

            for obj in ('json', 'url', 'local_mod', 'sax', 'dom'):
                assert globals()[obj].__name__ == globals_copy[obj].__name__
    
            for obj in ('x', 'empty', 'names'):
    likely benign LLM, confidence 0.90 Test compares restored globals with a copy using fixed names.
    Reasoning

    Compares globals against a copy for fixed test names; standard test assertion with no obfuscation purpose.

  39. info warn → info by review dynamic-execution dill/tests/test_sources.py:118:3

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

      local = {}
      exec(ds.dumpsource(add, alias='raw'), {}, local)
      exec(ds.dumpsource(ts.add, alias='mod'), {}, local)
      assert local['raw'](1,2) == local['mod'](1,2)
    likely benign LLM, confidence 0.90 Test execs dumped source of local functions to verify dill's source extraction.
    Reasoning

    exec of source generated by dill's own dumpsource from local test functions to check source round-tripping; not external input.

  40. info warn → info by review dynamic-execution dill/tests/test_sources.py:119:3

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

      exec(ds.dumpsource(add, alias='raw'), {}, local)
      exec(ds.dumpsource(ts.add, alias='mod'), {}, local)
      assert local['raw'](1,2) == local['mod'](1,2)
      exec(ds.dumpsource(squared, alias='raw'), {}, local)
    likely benign LLM, confidence 0.90 Test execs generated source for a known function and asserts equivalence.
    Reasoning

    Same as adjacent exec: dumpsource output of known test functions, used for equality assertions.

  41. info warn → info by review dynamic-execution dill/tests/test_sources.py:121:3

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

      assert local['raw'](1,2) == local['mod'](1,2)
      exec(ds.dumpsource(squared, alias='raw'), {}, local)
      exec(ds.dumpsource(ts.squared, alias='mod'), {}, local)
      assert local['raw'](3) == local['mod'](3)
    likely benign LLM, confidence 0.90 Test execs generated source for squared function to compare results.
    Reasoning

    Round-trip source check on test functions; exec of self-generated code in a test.

  42. info warn → info by review dynamic-execution dill/tests/test_sources.py:122:3

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

      exec(ds.dumpsource(squared, alias='raw'), {}, local)
      exec(ds.dumpsource(ts.squared, alias='mod'), {}, local)
      assert local['raw'](3) == local['mod'](3)
      assert ds._wrap(add)(1,2) == ds._wrap(ts.add)(1,2)
    likely benign LLM, confidence 0.90 Test execs generated source for squared function and asserts equality.
    Reasoning

    Round-trip source check on test functions; exec of self-generated code in a test.

  43. info warn → info by review dynamic-execution dill/tests/test_sources.py:152:3

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

      local = {}
      exec(ds.getimport(add, alias='raw'), {}, local)
      exec(ds.getimport(ts.add, alias='mod'), {}, local)
      assert local['raw'](1,2) == local['mod'](1,2)
    likely benign LLM, confidence 0.90 Test execs generated import statements to check dill's getimport.
    Reasoning

    exec of getimport output for local test functions, verifying import reconstruction; benign test code.

  44. info warn → info by review dynamic-execution dill/tests/test_sources.py:153:3

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

      exec(ds.getimport(add, alias='raw'), {}, local)
      exec(ds.getimport(ts.add, alias='mod'), {}, local)
      assert local['raw'](1,2) == local['mod'](1,2)
      exec(ds.getimport(squared, alias='raw'), {}, local)
    likely benign LLM, confidence 0.90 Test execs getimport output for add and squared.
    Reasoning

    Same getimport round-trip test pattern with known local functions.

  45. info warn → info by review dynamic-execution dill/tests/test_sources.py:155:3

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

      assert local['raw'](1,2) == local['mod'](1,2)
      exec(ds.getimport(squared, alias='raw'), {}, local)
      exec(ds.getimport(ts.squared, alias='mod'), {}, local)
      assert local['raw'](3) == local['mod'](3)
    likely benign LLM, confidence 0.90 Test execs getimport output for squared.
    Reasoning

    Same getimport round-trip test pattern; benign.

  46. info warn → info by review dynamic-execution dill/tests/test_sources.py:156:3

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

      exec(ds.getimport(squared, alias='raw'), {}, local)
      exec(ds.getimport(ts.squared, alias='mod'), {}, local)
      assert local['raw'](3) == local['mod'](3)
      exec(ds.getimport(Bar, alias='raw'), {}, local)
    likely benign LLM, confidence 0.90 Test execs getimport output for Bar class.
    Reasoning

    Same getimport round-trip test pattern; benign.

  47. info warn → info by review dynamic-execution dill/tests/test_sources.py:158:3

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

      assert local['raw'](3) == local['mod'](3)
      exec(ds.getimport(Bar, alias='raw'), {}, local)
      exec(ds.getimport(ts.Bar, alias='mod'), {}, local)
      assert ds.getname(local['raw']) == ds.getname(local['mod'])
    likely benign LLM, confidence 0.90 Test execs getimport output for Bar and compares names.
    Reasoning

    Same getimport round-trip test pattern; benign.

  48. info warn → info by review dynamic-execution dill/tests/test_sources.py:159:3

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

      exec(ds.getimport(Bar, alias='raw'), {}, local)
      exec(ds.getimport(ts.Bar, alias='mod'), {}, local)
      assert ds.getname(local['raw']) == ds.getname(local['mod'])
      exec(ds.getimport(tm.quad, alias='mod'), {}, local)
    likely benign LLM, confidence 0.90 Test execs getimport output for tm.quad in dill's test suite.
    Reasoning

    Same getimport round-trip test pattern, here for tm.quad; benign.

  49. info warn → info by review dynamic-execution dill/tests/test_sources.py:161:3

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

      assert ds.getname(local['raw']) == ds.getname(local['mod'])
      exec(ds.getimport(tm.quad, alias='mod'), {}, local)
      assert local['mod']()(sum)([1,2,3]) == tm.quad()(sum)([1,2,3])
      #FIXME: wrong results for nested functions (e.g. tm.double_add, tm.quadratic)
    likely benign LLM, confidence 0.90 Test code that execs an import statement generated by dill's getimport helper to check source extraction.
    Reasoning

    This is a test in dill's source-extraction suite. The exec call runs source text produced by ds.getimport for a known test function, using an empty globals dict and a local namespace that the test itself checks. The code is a test harness exercising dill's own round-trip, with no sign of hidden payloads or external input.

Reproduce This Scan

Run disclude locally to verify. These commands scan the published file; the "new in this release" marks come from comparing it with the previous release's file, which they don't repeat. 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.3.0
curl -fsSL -o dill-0.4.1-py3-none-any.whl https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl
printf '%s  %s\n' 1e1ce33e978ae97fcfcff5638477032b801c46c7c65cf717f95fbc2248f79a9d dill-0.4.1-py3-none-any.whl | shasum -a 256 -c -
unzip -q dill-0.4.1-py3-none-any.whl -d pkg
disclude scan --untrusted --severity info pkg