PyPI / hypothesis / 6.170.7

hypothesis 6.170.7

Source
https://github.com/HypothesisWorks/hypothesis
Artifact scanned
hypothesis-6.170.7.tar.gz (sdist · 506.7 KB · SHA-256 78ab4107d34f…)
Compared with
hypothesis-6.170.5.tar.gz (1 signals introduced since)
Files
114 scanned, 6 skipped (binary, oversized, or unrecognised)
Signals
0 critical · 0 warn · 34 info
Scan time
14.2 s
LLM review
Reviewed by claude-haiku-5-5 (Anthropic): 15 of 15 warn and critical signals; 15 demoted to info.
Disclude version
4.3.0
Scanned (UTC)
2026-10-23 14:13

Signals

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

  1. info warn → info by review dynamic-execution src/hypothesis/extra/ghostwriter.py:1841:13 new in this release

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

                # executed; so you still shouldn't ghostwrite for hostile code.
                compile(identity_repr, "<string>", "exec")
            except SyntaxError:
                identity_repr = repr(identity_repr)
    likely benign LLM, confidence 0.90 Validates that an identity repr compiles, falling back to repr() on SyntaxError.
    Reasoning

    compile(..., 'exec') is wrapped in a SyntaxError handler and the comment notes that ghostwriting for hostile code is not supported. It only validates a repr string and falls back to repr() on failure, with no execution of the result.

  2. info warn → info by review frame-introspection src/hypothesis/control.py:50:13

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

            )
        frame = inspect.currentframe()
        where = _calling_function_location("reject", frame)
        if currently_in_test_context():
    likely benign LLM, confidence 0.95 Captures the caller's frame to report where reject() was invoked.
    Reasoning

    inspect.currentframe() is used to find the calling location for reject() so Hypothesis can report where the rejection happened. This is ordinary introspection for diagnostics, with no network, decoding, or process activity.

  3. info warn → info by review frame-introspection src/hypothesis/control.py:78:17

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

        if observability_enabled() or not condition:
            frame = inspect.currentframe()
            where = _calling_function_location("assume", frame)
            if observability_enabled() and currently_in_test_context():
    likely benign LLM, confidence 0.95 Captures the caller's frame to record the location of an assume() call.
    Reasoning

    Same pattern as the reject() site: the frame is used only to record the source location of an assume() call for observability output. Nothing here is executed from data.

  4. info warn → info by review decoder-decompress-payload src/hypothesis/core.py:442:23

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

            try:
                decoded = zlib.decompress(decoded[1:])
            except zlib.error as err:
                raise InvalidArgument(
    likely benign LLM, confidence 0.85 Base64-decodes and zlib-decompresses a versioned blob, raising InvalidArgument on corrupt data.
    Reasoning

    This decodes a prefixed, base64-encoded value and inflates it with zlib, then raises InvalidArgument on zlib.error. It looks like Hypothesis's own serialization format for stored examples or a seed/blob, not a hidden payload. Decompressing data is not executing it, and the error handling is consistent with parsing user-supplied input.

  5. info warn → info by review dynamic-execution src/hypothesis/extra/ghostwriter.py:293:17

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

                with contextlib.suppress(SyntaxError):
                    compile(repr(st.just(param.default)), "<string>", "eval")
                    elements.insert(0, param.default)
            if elements or types:
    likely benign LLM, confidence 0.90 Checks whether a strategy repr is valid Python syntax before using it in generated code.
    Reasoning

    compile() is applied to repr() of a Hypothesis strategy inside a contextlib.suppress(SyntaxError) block, purely to check whether the repr is valid Python before using it as a fallback. The compiled code is never run, and the input is generated internally from the library's own strategies.

  6. info warn → info by review dynamic-execution src/hypothesis/extra/ghostwriter.py:719:9

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

            r = re.sub(r"(lambda.*?: )(<unknown>)([,)])", r"\1...\3", r)
            compile(r, "<string>", "eval")
            # Finally, try to work out the imports we need for builds(), .map(),
            # .filter(), and .flatmap() to work without NameError
    likely benign LLM, confidence 0.90 Syntax-checks a generated expression string used in ghostwritten tests.
    Reasoning

    The compile() call checks syntax of a regex-cleaned expression string that is being assembled for ghostwritten test code. It is a syntax validation step; the result is not executed.

  7. identifier `aᵏ` mixes scripts: Latin + Other (in string/comment) (raw pass, confidence 0.40)

        # The sum of a geometric series is given by (ref: wikipedia):
        #     ᵐ∑ₖ₌₀ aᵏ = (aᵐ⁺¹ - 1) / (a - 1)
        #               = S(m) / S(0)
        # assuming a != 1 and using the definition
  8. identifier `aᵐ` mixes scripts: Latin + Other (in string/comment) (raw pass, confidence 0.40)

        # The sum of a geometric series is given by (ref: wikipedia):
        #     ᵐ∑ₖ₌₀ aᵏ = (aᵐ⁺¹ - 1) / (a - 1)
        #               = S(m) / S(0)
        # assuming a != 1 and using the definition
  9. identifier `aᵐ` mixes scripts: Latin + Other (in string/comment) (raw pass, confidence 0.40)

        # assuming a != 1 and using the definition
        #         S(m) := aᵐ⁺¹ - 1.
        # The sum we want, starting from a number n [0 <= n <= m] rather than zero, is
        #     ᵐ∑ₖ₌ₙ aᵏ = ᵐ∑ₖ₌₀ aᵏ - ⁿ⁻¹∑ₖ₌₀ aᵏ = S(m) / S(0) - S(n - 1) / S(0)
  10. identifier `aᵏ` mixes scripts: Latin + Other (in string/comment) (raw pass, confidence 0.40)

        # The sum we want, starting from a number n [0 <= n <= m] rather than zero, is
        #     ᵐ∑ₖ₌ₙ aᵏ = ᵐ∑ₖ₌₀ aᵏ - ⁿ⁻¹∑ₖ₌₀ aᵏ = S(m) / S(0) - S(n - 1) / S(0)
        def S(n):
            return alphabet_size ** (n + 1) - 1
  11. identifier `aᵏ` mixes scripts: Latin + Other (in string/comment) (raw pass, confidence 0.40)

        # The sum we want, starting from a number n [0 <= n <= m] rather than zero, is
        #     ᵐ∑ₖ₌ₙ aᵏ = ᵐ∑ₖ₌₀ aᵏ - ⁿ⁻¹∑ₖ₌₀ aᵏ = S(m) / S(0) - S(n - 1) / S(0)
        def S(n):
            return alphabet_size ** (n + 1) - 1
  12. identifier `aᵏ` mixes scripts: Latin + Other (in string/comment) (raw pass, confidence 0.40)

        # The sum we want, starting from a number n [0 <= n <= m] rather than zero, is
        #     ᵐ∑ₖ₌ₙ aᵏ = ᵐ∑ₖ₌₀ aᵏ - ⁿ⁻¹∑ₖ₌₀ aᵏ = S(m) / S(0) - S(n - 1) / S(0)
        def S(n):
            return alphabet_size ** (n + 1) - 1
  13. info warn → info by review frame-introspection src/hypothesis/internal/conjecture/junkdrawer.py:316:13

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

        """
        frame = sys._getframe(2)
        size = 1
        while frame:
    likely benign LLM, confidence 0.95 Walks the call stack to measure its depth for an internal size estimate.
    Reasoning

    sys._getframe(2) is used to walk the stack and measure its size, likely for a recursion or stack-depth heuristic inside the engine. This is internal bookkeeping with no effect outside the process.

  14. identifier `ˆøπ` mixes scripts: Other + Latin + Greek (in string/comment) (raw pass, confidence 0.40)

        # common unicode characters
        "Ω≈ç√∫˜µ≤≥÷åß∂ƒ©˙∆˚¬…æœ∑´®†¥¨ˆøπ“‘¡™£¢∞§¶•ªº–≠¸˛Ç◊ı˜Â¯˘¿ÅÍÎÏ˝ÓÔ⟨U+F8FF⟩ÒÚÆ☃Œ„´‰ˇÁ¨ˆØ∏”’`⁄€‹›fifl‡°·‚—±",
        # characters which increase in length when lowercased
  15. identifier `ˇÁ` mixes scripts: Other + Latin (in string/comment) (raw pass, confidence 0.40)

        # common unicode characters
        "Ω≈ç√∫˜µ≤≥÷åß∂ƒ©˙∆˚¬…æœ∑´®†¥¨ˆøπ“‘¡™£¢∞§¶•ªº–≠¸˛Ç◊ı˜Â¯˘¿ÅÍÎÏ˝ÓÔ⟨U+F8FF⟩ÒÚÆ☃Œ„´‰ˇÁ¨ˆØ∏”’`⁄€‹›fifl‡°·‚—±",
        # characters which increase in length when lowercased
  16. identifier `ˆØ` mixes scripts: Other + Latin (in string/comment) (raw pass, confidence 0.40)

        # common unicode characters
        "Ω≈ç√∫˜µ≤≥÷åß∂ƒ©˙∆˚¬…æœ∑´®†¥¨ˆøπ“‘¡™£¢∞§¶•ªº–≠¸˛Ç◊ı˜Â¯˘¿ÅÍÎÏ˝ÓÔ⟨U+F8FF⟩ÒÚÆ☃Œ„´‰ˇÁ¨ˆØ∏”’`⁄€‹›fifl‡°·‚—±",
        # characters which increase in length when lowercased
  17. identifier `æœÆŒffʤʨß` mixes scripts: Latin + Other (in string/comment) (raw pass, confidence 0.40)

        # ligatures
        "æœÆŒffʤʨß",
        # emoticons
        "(╯°□°)╯︵ ┻━┻)",
  18. identifier `ʇǝɯɐ` mixes scripts: Other + Latin (in string/comment) (raw pass, confidence 0.40)

        # upsidown text
        "ʇǝɯɐ ʇᴉs ɹolop ɯnsdᴉ ɯǝɹo˥",
        # reserved strings in windows
        "NUL",
  19. identifier `ʇᴉs` mixes scripts: Other + Latin (in string/comment) (raw pass, confidence 0.40)

        # upsidown text
        "ʇǝɯɐ ʇᴉs ɹolop ɯnsdᴉ ɯǝɹo˥",
        # reserved strings in windows
        "NUL",
  20. identifier `ɹolop` mixes scripts: Other + Latin (in string/comment) (raw pass, confidence 0.40)

        # upsidown text
        "ʇǝɯɐ ʇᴉs ɹolop ɯnsdᴉ ɯǝɹo˥",
        # reserved strings in windows
        "NUL",
  21. identifier `ɯnsdᴉ` mixes scripts: Other + Latin (in string/comment) (raw pass, confidence 0.40)

        # upsidown text
        "ʇǝɯɐ ʇᴉs ɹolop ɯnsdᴉ ɯǝɹo˥",
        # reserved strings in windows
        "NUL",
  22. identifier `ɯǝɹo` mixes scripts: Other + Latin (in string/comment) (raw pass, confidence 0.40)

        # upsidown text
        "ʇǝɯɐ ʇᴉs ɹolop ɯnsdᴉ ɯǝɹo˥",
        # reserved strings in windows
        "NUL",
  23. identifier `ͅi` mixes scripts: Other + Latin (in string/comment) (raw pass, confidence 0.40)

    �̲e͇̣̰̦̬͎ ̢̼̻̱̘h͚͎͙̜̣̲ͅi̦̲̣̰̤v̻͍e̺̭̳̪̰-m̢iͅn̖̺̞̲̯̰d̵̼̟͙̩̼̘̳ ̞̥̱̳̭r̛̗̘e͙p͠r̼̞̻̭̗e̺̠̣͟s̘͇̳͍̝͉e͉̥̯̞̲͚̬͜ǹ̬͎͎̟̖͇̤t͍̬̤͓̼̭͘ͅi̪̱n͠g̴͉ ⟨U+034F⟩͉ͅc̬̟h͡a̫̻̯͘o̫̟̖͍̙̝͉s̗̦̲.̨̹͈̣",
  24. identifier `iͅn` mixes scripts: Latin + Other (in string/comment) (raw pass, confidence 0.40)

    �̜̣̲ͅi̦̲̣̰̤v̻͍e̺̭̳̪̰-m̢iͅn̖̺̞̲̯̰d̵̼̟͙̩̼̘̳ ̞̥̱̳̭r̛̗̘e͙p͠r̼̞̻̭̗e̺̠̣͟s̘͇̳͍̝͉e͉̥̯̞̲͚̬͜ǹ̬͎͎̟̖͇̤t͍̬̤͓̼̭͘ͅi̪̱n͠g̴͉ ⟨U+034F⟩͉ͅc̬̟h͡a̫̻̯͘o̫̟̖͍̙̝͉s̗̦̲.̨̹͈̣",
  25. identifier `ͅi` mixes scripts: Other + Latin (in string/comment) (raw pass, confidence 0.40)

    �̲͚̬͜ǹ̬͎͎̟̖͇̤t͍̬̤͓̼̭͘ͅi̪̱n͠g̴͉ ⟨U+034F⟩͉ͅc̬̟h͡a̫̻̯͘o̫̟̖͍̙̝͉s̗̦̲.̨̹͈̣",
  26. identifier `ͅc` mixes scripts: Other + Latin (in string/comment) (raw pass, confidence 0.40)

    �͇̤t͍̬̤͓̼̭͘ͅi̪̱n͠g̴͉ ⟨U+034F⟩͉ͅc̬̟h͡a̫̻̯͘o̫̟̖͍̙̝͉s̗̦̲.̨̹͈̣",
  27. info warn → info by review frame-introspection src/hypothesis/internal/coverage.py:74:18

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

            # stack frames up.
            caller = sys._getframe(depth + 2)
            fname = pretty_file_name(caller.f_code.co_filename)
            local_description = f"{name} at {fname}:{caller.f_lineno}"
    likely benign LLM, confidence 0.95 Reads the caller's filename and line number to label a coverage entry.
    Reasoning

    The caller frame is used to build a human-readable description (file name and line number) for coverage or observability labels. This is a standard introspection pattern for naming, not evasion.

  28. info warn → info by review dynamic-execution src/hypothesis/internal/lambda_sources.py:265:20

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

        if not f_code.co_freevars and not referenced_modules:
            compiled = eval(source, f_globals)
        else:
            if f_code.co_freevars:
    likely benign LLM, confidence 0.85 Evaluates reconstructed lambda source in the function's globals to rebuild the callable.
    Reasoning

    eval() evaluates a source string reconstructed from a lambda's code object in its original globals. This is how Hypothesis recovers lambda source for repr and reproduction. The source comes from the program's own code objects, not from external input, and the surrounding code is a documented reconstruction path.

  29. info warn → info by review dynamic-execution src/hypothesis/internal/lambda_sources.py:298:9

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

            )
            exec(exec_str, f_globals)
            compiled = f_globals["__construct_lambda"]()
    likely benign LLM, confidence 0.85 Executes a generated constructor snippet to rebuild a lambda that has closure variables.
    Reasoning

    exec() runs a generated helper that rebuilds a lambda with its free variables, as part of the same source-reconstruction mechanism. The string is built from the local code object's structure, not from untrusted input, so this is a known and intentional pattern.

  30. info warn → info by review dynamic-execution src/hypothesis/internal/reflection.py:367:5

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

        assert isinstance(source, str)
        exec(source, result.__dict__)
        eval_cache[source] = result
        return result
    likely benign LLM, confidence 0.85 Executes reconstructed function source into a fresh namespace and caches the result.
    Reasoning

    exec(source, result.__dict__) runs source text that was produced by Hypothesis's own lambda and function source extraction and caches the result. This is the core dynamic-reconstruction step used when rebuilding functions, not an obfuscated dropper.

  31. info warn → info by review frame-introspection src/hypothesis/internal/scrutineer.py:114:13

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

            if not hasattr(sys, "monitoring"):  # pragma: no cover  # only on Python < 3.12
                sys.settrace(self.trace)
                return self
    likely benign LLM, confidence 0.90 Installs a trace function for line-level coverage while a scrutinized block runs.
    Reasoning

    sys.settrace(self.trace) is installed inside a context manager guarded for Python below 3.12. It is a coverage/scrutiny tool that records lines executed during a test, a well-known and documented technique, and it is removed on exit.

  32. info warn → info by review frame-introspection src/hypothesis/internal/scrutineer.py:137:13

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

            if not hasattr(sys, "monitoring"):  # pragma: no cover  # only on Python < 3.12
                sys.settrace(None)
                return
    likely benign LLM, confidence 0.90 Removes the trace function on exit from the scrutinized block.
    Reasoning

    sys.settrace(None) is the matching teardown for the trace installed on entry. Clearing the trace function is expected cleanup and carries no malicious signal.

  33. info warn → info by review frame-introspection src/hypothesis/strategies/_internal/strategies.py:103:31

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

            return location
        frame: FrameType | None = sys._getframe(1)
        while frame is not None and is_hypothesis_file(frame.f_code.co_filename):
            frame = frame.f_back
    likely benign LLM, confidence 0.95 Walks up the stack past Hypothesis's own files to find the user's calling location.
    Reasoning

    sys._getframe(1) walks up past Hypothesis's own files to find the user's calling location, which is used to report where a strategy was defined. This is ordinary frame introspection for error reporting.

  34. info warn → info by review frame-introspection src/hypothesis/strategies/_internal/types.py:227:37

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

        found_loc: str | None = None
        frame: types.FrameType | None = sys._getframe()
        while frame is not None:
            loc = f"{frame.f_code.co_filename}:{frame.f_lineno}"
    likely benign LLM, confidence 0.95 Hypothesis's type-strategy code walks the call stack via sys._getframe to record source locations for reporting.
    Reasoning

    sys._getframe() is used here to walk the call stack to locate the user's source file and line where a strategy was defined, which is a common legitimate pattern in a property-based testing library for error reporting. No network, process spawning, decoding or dynamic execution is present in the snippet.

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 hypothesis-6.170.7.tar.gz https://files.pythonhosted.org/packages/0c/ce/b83d3c34e92721c84369350a74f5ccbe693b54a07b79a89f9dc90ab82e9f/hypothesis-6.170.7.tar.gz
printf '%s  %s\n' 78ab4107d34f33a90f5abede6cc80aa51387ffea043efc61f1793a6ed8575824 hypothesis-6.170.7.tar.gz | shasum -a 256 -c -
mkdir pkg && tar -xzf hypothesis-6.170.7.tar.gz -C pkg --strip-components 1
disclude scan --untrusted --severity info pkg