PyPI / pip / 26.2.1

pip 26.2.1

Source
https://github.com/pypa/pip
Tag scanned
26.2.1
Compared with
26.2 (0 signals introduced since)
Files
787 scanned, 229 skipped (binary, oversized, or unrecognised)
Signals
0 critical · 0 warn · 149 info
Scan time
25.0 s
LLM review
Reviewed by claude-haiku-5-5 (Anthropic): 36 of 36 warn and critical signals; 36 demoted to info.
Disclude version
4.0.0
Scanned (UTC)
2026-10-14 18:19

Signals

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

  1. info warn → info by review unicode-zero-width AUTHORS.txt:798:2

    U+200B ZERO WIDTH SPACE in source (raw pass, confidence 0.75)

    Sylvain
    S⟨U+200B⟩age Abdullah
    Takayuki SHIMIZUKAWA
    Taneli Hukkinen
    likely benign LLM, confidence 0.97 A zero-width space appears inside a contributor name in AUTHORS.txt.
    Reasoning

    A zero-width space inside a author name in a plain-text contributors list is a typographic/encoding artifact, not executable code; no obfuscation purpose is evident.

  2. info critical → info by review dynamic-execution docs/html/user_guide.rst:924:5

    [markup prose] `eval` called on a dynamic (variable/substitution) expression (ast pass, confidence 0.90)

        eval "`pip completion --bash`"
    likely benign LLM, confidence 0.90 Docs show eval of pip completion output for shell tab-completion setup.
    Reasoning

    This is an eval of the output of pip completion in a shell setup snippet in documentation, a standard pattern for enabling shell completion; it is documentation prose, not executed code in the package.

  3. compression ratio 0.764 is >2σ above file mean 0.626 (raw pass, confidence 0.50)

    > "I would like some security advisor, [like in npm]https://docs.npmjs.com/auditing-package-dependencies-for-security-vulnerabilities - it works very well, when you install a package "there are security vulns. with this package - 1 low, 5 medium, 8 high. I haven't come across security issues with Python packages." **
  4. info warn → info by review dynamic-execution src/pip/_internal/commands/configuration.py:248:13

    `subprocess.check_call` called with `shell=True` and a literal command (ast pass, confidence 0.70)

            try:
                subprocess.check_call(f'{editor} "{fname}"', shell=True)
            except FileNotFoundError as e:
                if not e.filename:
    likely benign LLM, confidence 0.90 Launches the user's editor via shell with the config filename.
    Reasoning

    The shell=True call runs the user's configured editor with a filename; this is a deliberate user-controlled editor invocation, a known pattern, though interpolation of the filename is a minor quoting concern rather than obfuscation.

  5. info critical → info by review dynamic-import src/pip/_internal/commands/install.py:114:13

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

            try:
                __import__(module)
            except ImportError:
                # Record the module as missing so the hook can raise ImportError
    likely benign LLM, confidence 0.93 Dynamic import of a module inside an ImportError-guarded hook.
    Reasoning

    Dynamic __import__ inside a try/except ImportError used to record missing optional modules for a hook; a normal dynamic import pattern in a package manager.

  6. U+200B ZERO WIDTH SPACE in source (in string/comment) (raw pass, confidence 0.45)

        """Fallback for Python without tarfile.data_filter"""
        # NOTE: This function can be removed once pip requires CPython ≥ 3.12.⟨U+200B⟩
        # PEP 706 added tarfile.data_filter, made tarfile extraction operations more secure.
        # This feature is fully supported from CPython 3.12 onward.
  7. info critical → info by review dynamic-import src/pip/_vendor/__init__.py:33:9

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

        try:
            __import__(modulename, globals(), locals(), level=0)
        except ImportError:
            # We can just silently allow import failures to pass here. If we
    likely benign LLM, confidence 0.93 Vendor alias loader performing dynamic __import__ with ImportError suppression.
    Reasoning

    Vendoring shim that imports a module by name and tolerates ImportError; standard legitimate vendoring mechanism.

  8. info critical → info by review dynamic-import src/pip/_vendor/distlib/resources.py:337:13

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

            if package not in sys.modules:
                __import__(package)
            module = sys.modules[package]
            path = getattr(module, '__path__', None)
    likely benign LLM, confidence 0.93 Imports a package dynamically to resolve its filesystem path for resources.
    Reasoning

    Standard resource finder importing a package by name to locate its __path__; ordinary library behavior.

  9. info critical → info by review dynamic-import src/pip/_vendor/distlib/util.py:680:15

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

        else:
            mod = __import__(module_name)
        if dotted_path is None:
            result = mod
    likely benign LLM, confidence 0.92 Resolves a dotted module path for entry-point lookup via __import__.
    Reasoning

    Resolves a dotted path string to an object via __import__, a common resolver pattern in distlib for entry points.

  10. info unicode-mixed-script src/pip/_vendor/idna/uts46data.py:8850:6

    identifier `ʼn` mixes scripts: Other + Latin (in string/comment) (raw pass, confidence 0.40)

        None,
        "ʼn",
        "ŋ",
        None,
  11. identifier `α` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)

        None,
        "α",
        "β",
        "γ",
  12. identifier `η` contains homoglyph candidates: η (03B7)→n (in string/comment) (raw pass, confidence 0.35)

        "ζ",
        "η",
        "θ",
        "ι",
  13. identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)

        "ι",
        "κ",
        "λ",
        "μ",
  14. identifier `ν` contains homoglyph candidates: ν (03BD)→v (in string/comment) (raw pass, confidence 0.35)

        "μ",
        "ν",
        "ξ",
        "ο",
  15. identifier `ο` contains homoglyph candidates: ο (03BF)→o (in string/comment) (raw pass, confidence 0.35)

        "ξ",
        "ο",
        "π",
        "ρ",
  16. identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)

        "π",
        "ρ",
        None,
        "σ",
  17. identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)

        None,
        "κ",
        "ρ",
        "σ",
  18. identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)

        "κ",
        "ρ",
        "σ",
        None,
  19. identifier `і` contains homoglyph candidates: і (0456)→i (in string/comment) (raw pass, confidence 0.35)

        "ѕ",
        "і",
        "ї",
        "ј",
  20. identifier `а` contains homoglyph candidates: а (0430)→a (in string/comment) (raw pass, confidence 0.35)

        "џ",
        "а",
        "б",
        "в",
  21. identifier `е` contains homoglyph candidates: е (0435)→e (in string/comment) (raw pass, confidence 0.35)

        "д",
        "е",
        "ж",
        "з",
  22. identifier `о` contains homoglyph candidates: о (043E)→o (in string/comment) (raw pass, confidence 0.35)

        "н",
        "о",
        "п",
        "р",
  23. identifier `р` contains homoglyph candidates: р (0440)→p (in string/comment) (raw pass, confidence 0.35)

        "п",
        "р",
        "с",
        "т",
  24. identifier `с` contains homoglyph candidates: с (0441)→c (in string/comment) (raw pass, confidence 0.35)

        "р",
        "с",
        "т",
        "у",
  25. identifier `у` contains homoglyph candidates: у (0443)→y (in string/comment) (raw pass, confidence 0.35)

        "т",
        "у",
        "ф",
        "х",
  26. identifier `х` contains homoglyph candidates: х (0445)→x (in string/comment) (raw pass, confidence 0.35)

        "ф",
        "х",
        "ц",
        "ч",
  27. identifier `о` contains homoglyph candidates: о (043E)→o (in string/comment) (raw pass, confidence 0.35)

        "д",
        "о",
        "с",
        "т",
  28. identifier `с` contains homoglyph candidates: с (0441)→c (in string/comment) (raw pass, confidence 0.35)

        "о",
        "с",
        "т",
        "ъ",
  29. identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)

        "γ",
        "ρ",
        "φ",
        "χ",
  30. info unicode-mixed-script src/pip/_vendor/idna/uts46data.py:10374:6

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

        None,
        "aʾ",
        "ṡ",
        None,
  31. info unicode-mixed-script src/pip/_vendor/idna/uts46data.py:12023:6

    identifier `kω` mixes scripts: Latin + Greek (in string/comment) (raw pass, confidence 0.40)

        "mw",
        "kω",
        "mω",
        None,
  32. info unicode-mixed-script src/pip/_vendor/idna/uts46data.py:12024:6

    identifier `mω` mixes scripts: Latin + Greek (in string/comment) (raw pass, confidence 0.40)

        "kω",
        "mω",
        None,
        "bq",
  33. identifier `α` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)

        None,
        "α",
        "β",
        "γ",
  34. identifier `η` contains homoglyph candidates: η (03B7)→n (in string/comment) (raw pass, confidence 0.35)

        "ζ",
        "η",
        "θ",
        "ι",
  35. identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)

        "ι",
        "κ",
        "λ",
        "μ",
  36. identifier `ν` contains homoglyph candidates: ν (03BD)→v (in string/comment) (raw pass, confidence 0.35)

        "μ",
        "ν",
        "ξ",
        "ο",
  37. identifier `ο` contains homoglyph candidates: ο (03BF)→o (in string/comment) (raw pass, confidence 0.35)

        "ξ",
        "ο",
        "π",
        "ρ",
  38. identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)

        "π",
        "ρ",
        "θ",
        "σ",
  39. identifier `α` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)

        "∇",
        "α",
        "β",
        "γ",
  40. identifier `η` contains homoglyph candidates: η (03B7)→n (in string/comment) (raw pass, confidence 0.35)

        "ζ",
        "η",
        "θ",
        "ι",
  41. identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)

        "ι",
        "κ",
        "λ",
        "μ",
  42. identifier `ν` contains homoglyph candidates: ν (03BD)→v (in string/comment) (raw pass, confidence 0.35)

        "μ",
        "ν",
        "ξ",
        "ο",
  43. identifier `ο` contains homoglyph candidates: ο (03BF)→o (in string/comment) (raw pass, confidence 0.35)

        "ξ",
        "ο",
        "π",
        "ρ",
  44. identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)

        "π",
        "ρ",
        "σ",
        "τ",
  45. identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)

        "θ",
        "κ",
        "φ",
        "ρ",
  46. identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)

        "φ",
        "ρ",
        "π",
        "α",
  47. identifier `α` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)

        "π",
        "α",
        "β",
        "γ",
  48. identifier `η` contains homoglyph candidates: η (03B7)→n (in string/comment) (raw pass, confidence 0.35)

        "ζ",
        "η",
        "θ",
        "ι",
  49. identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)

        "ι",
        "κ",
        "λ",
        "μ",
  50. identifier `ν` contains homoglyph candidates: ν (03BD)→v (in string/comment) (raw pass, confidence 0.35)

        "μ",
        "ν",
        "ξ",
        "ο",
  51. identifier `ο` contains homoglyph candidates: ο (03BF)→o (in string/comment) (raw pass, confidence 0.35)

        "ξ",
        "ο",
        "π",
        "ρ",
  52. identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)

        "π",
        "ρ",
        "θ",
        "σ",
  53. identifier `α` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)

        "∇",
        "α",
        "β",
        "γ",
  54. identifier `η` contains homoglyph candidates: η (03B7)→n (in string/comment) (raw pass, confidence 0.35)

        "ζ",
        "η",
        "θ",
        "ι",
  55. identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)

        "ι",
        "κ",
        "λ",
        "μ",
  56. identifier `ν` contains homoglyph candidates: ν (03BD)→v (in string/comment) (raw pass, confidence 0.35)

        "μ",
        "ν",
        "ξ",
        "ο",
  57. identifier `ο` contains homoglyph candidates: ο (03BF)→o (in string/comment) (raw pass, confidence 0.35)

        "ξ",
        "ο",
        "π",
        "ρ",
  58. identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)

        "π",
        "ρ",
        "σ",
        "τ",
  59. identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)

        "θ",
        "κ",
        "φ",
        "ρ",
  60. identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)

        "φ",
        "ρ",
        "π",
        "α",
  61. identifier `α` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)

        "π",
        "α",
        "β",
        "γ",
  62. identifier `η` contains homoglyph candidates: η (03B7)→n (in string/comment) (raw pass, confidence 0.35)

        "ζ",
        "η",
        "θ",
        "ι",
  63. identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)

        "ι",
        "κ",
        "λ",
        "μ",
  64. identifier `ν` contains homoglyph candidates: ν (03BD)→v (in string/comment) (raw pass, confidence 0.35)

        "μ",
        "ν",
        "ξ",
        "ο",
  65. identifier `ο` contains homoglyph candidates: ο (03BF)→o (in string/comment) (raw pass, confidence 0.35)

        "ξ",
        "ο",
        "π",
        "ρ",
  66. identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)

        "π",
        "ρ",
        "θ",
        "σ",
  67. identifier `α` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)

        "∇",
        "α",
        "β",
        "γ",
  68. identifier `η` contains homoglyph candidates: η (03B7)→n (in string/comment) (raw pass, confidence 0.35)

        "ζ",
        "η",
        "θ",
        "ι",
  69. identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)

        "ι",
        "κ",
        "λ",
        "μ",
  70. identifier `ν` contains homoglyph candidates: ν (03BD)→v (in string/comment) (raw pass, confidence 0.35)

        "μ",
        "ν",
        "ξ",
        "ο",
  71. identifier `ο` contains homoglyph candidates: ο (03BF)→o (in string/comment) (raw pass, confidence 0.35)

        "ξ",
        "ο",
        "π",
        "ρ",
  72. identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)

        "π",
        "ρ",
        "σ",
        "τ",
  73. identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)

        "θ",
        "κ",
        "φ",
        "ρ",
  74. identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)

        "φ",
        "ρ",
        "π",
        "α",
  75. identifier `α` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)

        "π",
        "α",
        "β",
        "γ",
  76. identifier `η` contains homoglyph candidates: η (03B7)→n (in string/comment) (raw pass, confidence 0.35)

        "ζ",
        "η",
        "θ",
        "ι",
  77. identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)

        "ι",
        "κ",
        "λ",
        "μ",
  78. identifier `ν` contains homoglyph candidates: ν (03BD)→v (in string/comment) (raw pass, confidence 0.35)

        "μ",
        "ν",
        "ξ",
        "ο",
  79. identifier `ο` contains homoglyph candidates: ο (03BF)→o (in string/comment) (raw pass, confidence 0.35)

        "ξ",
        "ο",
        "π",
        "ρ",
  80. identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)

        "π",
        "ρ",
        "θ",
        "σ",
  81. identifier `α` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)

        "∇",
        "α",
        "β",
        "γ",
  82. identifier `η` contains homoglyph candidates: η (03B7)→n (in string/comment) (raw pass, confidence 0.35)

        "ζ",
        "η",
        "θ",
        "ι",
  83. identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)

        "ι",
        "κ",
        "λ",
        "μ",
  84. identifier `ν` contains homoglyph candidates: ν (03BD)→v (in string/comment) (raw pass, confidence 0.35)

        "μ",
        "ν",
        "ξ",
        "ο",
  85. identifier `ο` contains homoglyph candidates: ο (03BF)→o (in string/comment) (raw pass, confidence 0.35)

        "ξ",
        "ο",
        "π",
        "ρ",
  86. identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)

        "π",
        "ρ",
        "σ",
        "τ",
  87. identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)

        "θ",
        "κ",
        "φ",
        "ρ",
  88. identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)

        "φ",
        "ρ",
        "π",
        "α",
  89. identifier `α` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)

        "π",
        "α",
        "β",
        "γ",
  90. identifier `η` contains homoglyph candidates: η (03B7)→n (in string/comment) (raw pass, confidence 0.35)

        "ζ",
        "η",
        "θ",
        "ι",
  91. identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)

        "ι",
        "κ",
        "λ",
        "μ",
  92. identifier `ν` contains homoglyph candidates: ν (03BD)→v (in string/comment) (raw pass, confidence 0.35)

        "μ",
        "ν",
        "ξ",
        "ο",
  93. identifier `ο` contains homoglyph candidates: ο (03BF)→o (in string/comment) (raw pass, confidence 0.35)

        "ξ",
        "ο",
        "π",
        "ρ",
  94. identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)

        "π",
        "ρ",
        "θ",
        "σ",
  95. identifier `α` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)

        "∇",
        "α",
        "β",
        "γ",
  96. identifier `η` contains homoglyph candidates: η (03B7)→n (in string/comment) (raw pass, confidence 0.35)

        "ζ",
        "η",
        "θ",
        "ι",
  97. identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)

        "ι",
        "κ",
        "λ",
        "μ",
  98. identifier `ν` contains homoglyph candidates: ν (03BD)→v (in string/comment) (raw pass, confidence 0.35)

        "μ",
        "ν",
        "ξ",
        "ο",
  99. identifier `ο` contains homoglyph candidates: ο (03BF)→o (in string/comment) (raw pass, confidence 0.35)

        "ξ",
        "ο",
        "π",
        "ρ",
  100. identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)

        "π",
        "ρ",
        "σ",
        "τ",
  101. identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)

        "θ",
        "κ",
        "φ",
        "ρ",
  102. identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)

        "φ",
        "ρ",
        "π",
        "ϝ",
  103. identifier `а` contains homoglyph candidates: а (0430)→a (in string/comment) (raw pass, confidence 0.35)

        None,
        "а",
        "б",
        "в",
  104. identifier `е` contains homoglyph candidates: е (0435)→e (in string/comment) (raw pass, confidence 0.35)

        "д",
        "е",
        "ж",
        "з",
  105. identifier `о` contains homoglyph candidates: о (043E)→o (in string/comment) (raw pass, confidence 0.35)

        "м",
        "о",
        "п",
        "р",
  106. identifier `р` contains homoglyph candidates: р (0440)→p (in string/comment) (raw pass, confidence 0.35)

        "п",
        "р",
        "с",
        "т",
  107. identifier `с` contains homoglyph candidates: с (0441)→c (in string/comment) (raw pass, confidence 0.35)

        "р",
        "с",
        "т",
        "у",
  108. identifier `у` contains homoglyph candidates: у (0443)→y (in string/comment) (raw pass, confidence 0.35)

        "т",
        "у",
        "ф",
        "х",
  109. identifier `х` contains homoglyph candidates: х (0445)→x (in string/comment) (raw pass, confidence 0.35)

        "ф",
        "х",
        "ц",
        "ч",
  110. identifier `і` contains homoglyph candidates: і (0456)→i (in string/comment) (raw pass, confidence 0.35)

        "ә",
        "і",
        "ј",
        "ө",
  111. identifier `а` contains homoglyph candidates: а (0430)→a (in string/comment) (raw pass, confidence 0.35)

        "ӏ",
        "а",
        "б",
        "в",
  112. identifier `е` contains homoglyph candidates: е (0435)→e (in string/comment) (raw pass, confidence 0.35)

        "д",
        "е",
        "ж",
        "з",
  113. identifier `о` contains homoglyph candidates: о (043E)→o (in string/comment) (raw pass, confidence 0.35)

        "л",
        "о",
        "п",
        "с",
  114. identifier `с` contains homoglyph candidates: с (0441)→c (in string/comment) (raw pass, confidence 0.35)

        "п",
        "с",
        "у",
        "ф",
  115. identifier `у` contains homoglyph candidates: у (0443)→y (in string/comment) (raw pass, confidence 0.35)

        "с",
        "у",
        "ф",
        "х",
  116. identifier `х` contains homoglyph candidates: х (0445)→x (in string/comment) (raw pass, confidence 0.35)

        "ф",
        "х",
        "ц",
        "ч",
  117. identifier `і` contains homoglyph candidates: і (0456)→i (in string/comment) (raw pass, confidence 0.35)

        "ґ",
        "і",
        "ѕ",
        "џ",
  118. info warn → info by review dynamic-execution src/pip/_vendor/packaging/licenses/__init__.py:144:9

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

        try:
            compile(python_expression, "", "eval")
        except SyntaxError:
            message = f"Invalid license expression: {raw_license_expression!r}"
    likely benign LLM, confidence 0.90 Compiles a license expression to check syntax only, not executing it.
    Reasoning

    compile in eval mode is used to validate a license expression syntax and report SyntaxError; compiling without executing is benign validation.

  119. info critical → info by review dynamic-import src/pip/_vendor/pkg_resources/__init__.py:427:9

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

        except KeyError:
            __import__(moduleOrReq)
            module = sys.modules[moduleOrReq]
        loader = getattr(module, '__loader__', None)
    likely benign LLM, confidence 0.92 Imports a named module dynamically to obtain its loader.
    Reasoning

    Dynamic import of a module or requirement name by string for namespace/loader lookup, standard pkg_resources behavior.

  120. info critical → info by review frame-introspection src/pip/_vendor/pkg_resources/__init__.py:743:14

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

            """Locate distribution for `requires` and run `script_name` script"""
            ns = sys._getframe(1).f_globals
            name = ns['__name__']
            ns.clear()
    likely benign LLM, confidence 0.85 Uses sys._getframe to access the caller namespace when running an entry-point script.
    Reasoning

    pkg_resources' run_script mirrors the script's globals via sys._getframe to execute entry-point scripts; the anti-analysis label is a heuristic false positive in this context, though frame access combined with exec is worth a note.

  121. info warn → info by review dynamic-execution src/pip/_vendor/pkg_resources/__init__.py:1713:20

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

                source = _read_utf8_with_fallback(script_filename)
                code = compile(source, script_filename, 'exec')
                exec(code, namespace, namespace)
            else:
    likely benign LLM, confidence 0.90 Compiles a distribution script file as part of running an entry-point script.
    Reasoning

    Compiles and executes a console/entry-point script file from the distribution's own metadata, the designed behavior of pkg_resources' script runner.

  122. info warn → info by review dynamic-execution src/pip/_vendor/pkg_resources/__init__.py:1714:13

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

                code = compile(source, script_filename, 'exec')
                exec(code, namespace, namespace)
            else:
                from linecache import cache
    likely benign LLM, confidence 0.90 Executes an installed distribution's script in a supplied namespace.
    Reasoning

    exec of compiled distribution script within a controlled namespace, the expected behavior of running installed entry-point scripts.

  123. info warn → info by review dynamic-execution src/pip/_vendor/pkg_resources/__init__.py:1724:27

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

                )
                script_code = compile(script_text, script_filename, 'exec')
                exec(script_code, namespace, namespace)
    likely benign LLM, confidence 0.90 Compiles and executes script text from distribution metadata.
    Reasoning

    Compiles and execs script text from the distribution's metadata for entry-point execution; legitimate runner behavior in pkg_resources.

  124. info warn → info by review dynamic-execution src/pip/_vendor/pkg_resources/__init__.py:1725:13

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

                script_code = compile(script_text, script_filename, 'exec')
                exec(script_code, namespace, namespace)
    
        def _has(self, path) -> bool:
    likely benign LLM, confidence 0.80 pkg_resources executes distribution script code via exec during run_script.
    Reasoning

    exec of compiled script text in pkg_resources' ScriptMetadata/run_script path is the documented mechanism for running entry-point scripts from distributions; it is a legitimate, expected pattern in this vendored library.

  125. info critical → info by review dynamic-import src/pip/_vendor/pkg_resources/__init__.py:2530:17

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

                if parent not in _namespace_packages:
                    __import__(parent)
                try:
                    path = sys.modules[parent].__path__
    likely benign LLM, confidence 0.90 Imports parent namespace package during declare_namespace.
    Reasoning

    __import__ of a parent namespace package name is standard namespace-package handling in pkg_resources; the name comes from the package's own declared namespaces.

  126. info critical → info by review dynamic-import src/pip/_vendor/pkg_resources/__init__.py:2751:18

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

            """
            module = __import__(self.module_name, fromlist=['__name__'], level=0)
            try:
                return functools.reduce(getattr, self.attrs, module)
    likely benign LLM, confidence 0.90 Resolves an entry point by importing its module and getattr chain.
    Reasoning

    EntryPoint.resolve imports the module named by the entry point specification and walks attrs, the normal plugin-loading mechanism.

  127. info critical → info by review frame-introspection src/pip/_vendor/pkg_resources/__init__.py:3411:15

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

            # the pkg_resources module, to use for the warning
            while sys._getframe(level).f_globals is g:
                level += 1
        except ValueError:
    likely benign LLM, confidence 0.90 Uses sys._getframe to compute a warning stacklevel.
    Reasoning

    sys._getframe is used to find the caller's stack level for warnings.warn stacklevel computation; this is benign and the sys.exit/exec co-occurrence is incidental to a large vendored module.

  128. info critical → info by review dynamic-import src/pip/_vendor/pygments/formatters/__init__.py:38:11

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

        """Load a formatter (and all others in the module too)."""
        mod = __import__(module_name, None, None, ['__all__'])
        for formatter_name in mod.__all__:
            cls = getattr(mod, formatter_name)
    likely benign LLM, confidence 0.90 Loads a built-in Pygments formatter module by name.
    Reasoning

    Pygments loads its own built-in formatter modules by name via __import__, a standard plugin-loading pattern with names from internal constants.

  129. info warn → info by review dynamic-execution src/pip/_vendor/pygments/formatters/__init__.py:103:13

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

            with open(filename, 'rb') as f:
                exec(f.read(), custom_namespace)
            # Retrieve the class `formattername` from that namespace
            if formattername not in custom_namespace:
    likely benign LLM, confidence 0.85 Executes a user-specified custom formatter Python file.
    Reasoning

    Pygments' load_formatter_from_file execs a user-supplied custom formatter file, which is an intentional documented feature requiring the user to pass the file explicitly; not hidden or automatic.

  130. info critical → info by review dynamic-import src/pip/_vendor/pygments/lexers/__init__.py:45:11

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

        """Load a lexer (and all others in the module too)."""
        mod = __import__(module_name, None, None, ['__all__'])
        for lexer_name in mod.__all__:
            cls = getattr(mod, lexer_name)
    likely benign LLM, confidence 0.90 Loads a built-in Pygments lexer module by name.
    Reasoning

    Standard Pygments lazy-loading of built-in lexer modules by internal name.

  131. info warn → info by review dynamic-execution src/pip/_vendor/pygments/lexers/__init__.py:154:13

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

            with open(filename, 'rb') as f:
                exec(f.read(), custom_namespace)
            # Retrieve the class `lexername` from that namespace
            if lexername not in custom_namespace:
    likely benign LLM, confidence 0.85 Executes a user-specified custom lexer Python file.
    Reasoning

    Pygments' load_lexer_from_file execs a user-provided custom lexer file, an explicit documented feature rather than hidden behavior.

  132. info critical → info by review dynamic-import src/pip/_vendor/pygments/sphinxext.py:161:19

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

                module = data[0]
                mod = __import__(module, None, None, [classname])
                self.filenames.add(mod.__file__)
                cls = getattr(mod, classname)
    likely benign LLM, confidence 0.90 Imports a lexer class from a module named in Sphinx doc source.
    Reasoning

    Sphinx extension imports lexer classes named in the documentation-configured module path; expected plugin behavior.

  133. info critical → info by review dynamic-import src/pip/_vendor/pygments/sphinxext.py:221:19

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

                module = data[0]
                mod = __import__(module, None, None, [classname])
                self.filenames.add(mod.__file__)
                cls = getattr(mod, classname)
    likely benign LLM, confidence 0.90 Imports a lexer class from a module named in Sphinx doc source.
    Reasoning

    Same pattern as the other sphinxext import: loads lexer classes named in documentation configuration for the Sphinx extension.

  134. info critical → info by review dynamic-import src/pip/_vendor/pygments/styles/__init__.py:45:15

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

        try:
            mod = __import__(mod, None, None, [cls])
        except ImportError:
            raise ClassNotFound(f"Could not find style module {mod!r}" +
    likely benign LLM, confidence 0.90 Imports a Pygments style module by name.
    Reasoning

    Pygments loads style modules by name from its built-in style map with a fallback ImportError to ClassNotFound; ordinary plugin loading.

  135. compression ratio 0.629 is >2σ above file mean 0.384 (raw pass, confidence 0.50)

    
    Sc = '$\xa2-\xa5\u058f\u060b\u07fe-\u07ff\u09f2-\u09f3\u09fb\u0af1\u0bf9\u0e3f\u17db\u20a0-\u20bf\ua838\ufdfc\ufe69\uff04\uffe0-\uffe1\uffe5-\uffe6\U0001ecb0'
  136. info warn → info by review dynamic-attribute src/pip/_vendor/pygments/unistring.py:83:20

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

    def combine(*args):
        return ''.join(globals()[cat] for cat in args)
    likely benign LLM, confidence 0.90 Looks up Unicode category string constants via globals().
    Reasoning

    globals() lookup of Unicode category table names inside a module that defines those tables is a standard, harmless idiom with no external input.

  137. info warn → info by review dynamic-attribute src/pip/_vendor/pygments/unistring.py:90:20

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

            newcats.remove(arg)
        return ''.join(globals()[cat] for cat in newcats)
    likely benign LLM, confidence 0.90 Pygments builds Unicode character-class strings by looking up category tables by name in globals().
    Reasoning

    Joins Unicode category names looked up from globals() in a generator for character-class strings. This is name-based lookup over a fixed set of module-level tables, not payload execution.

  138. info warn → info by review dynamic-execution src/pip/_vendor/pygments/unistring.py:115:10

    `open(__file__)` — file reads its own source, common pattern for extracting payloads hidden in comments (ast pass, confidence 0.85)

    
        with open(__file__, encoding='utf-8') as fp:
            content = fp.read()
    likely benign LLM, confidence 0.85 Pygments' unistring module reads its own source file, part of its table-regeneration tooling.
    Reasoning

    The file reads its own source as part of Pygments' generator logic for regenerating the unistring tables. It does not decode or execute anything from comments.

  139. info warn → info by review dynamic-execution src/pip/_vendor/pygments/unistring.py:139:10

    `open(__file__)` — file reads its own source, common pattern for extracting payloads hidden in comments (ast pass, confidence 0.85)

    
        with open(__file__, 'w', encoding='utf-8') as fp:
            fp.write(header)
    likely benign LLM, confidence 0.80 Pygments' generator rewrites the unistring module with a regenerated header.
    Reasoning

    Writes a generated header back into the module. This is a developer regeneration routine that rewrites its own source, with no network or hidden payload involved.

  140. info warn → info by review dynamic-attribute src/pip/_vendor/pyproject_hooks/_in_process/_in_process.py:367:12

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

    
        hook = globals()[hook_name]
    
        hook_input = read_json(pjoin(control_dir, "input.json"))
    likely benign LLM, confidence 0.90 pyproject_hooks dispatches a named build hook from globals() in its in-process runner.
    Reasoning

    This is the standard dispatch of build-backend hook names (such as build_wheel) to functions in the in-process runner. The hook name comes from a fixed set.

  141. info warn → info by review dynamic-attribute src/pip/_vendor/requests/packages.py:10:5

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

        vendored_package = "pip._vendor." + package
        locals()[package] = __import__(vendored_package)
        # This traversal is apparently necessary such that the identities are
        # preserved (requests.packages.urllib3.* is urllib3.*)
    likely benign LLM, confidence 0.90 Legacy compatibility shim that registers vendored packages into locals() under old names.
    Reasoning

    This is the well-known requests compatibility shim that aliases vendored packages under their legacy names so module identities are preserved. The loop variable comes from a fixed list of package names.

  142. info critical → info by review dynamic-import src/pip/_vendor/requests/packages.py:10:25

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

        vendored_package = "pip._vendor." + package
        locals()[package] = __import__(vendored_package)
        # This traversal is apparently necessary such that the identities are
        # preserved (requests.packages.urllib3.* is urllib3.*)
    likely benign LLM, confidence 0.90 Dynamic __import__ of vendored pip._vendor packages inside the requests compatibility shim.
    Reasoning

    The __import__ target is built from the fixed prefix 'pip._vendor.' plus a known package name from the same compatibility loop. This is ordinary vendored import machinery.

  143. info warn → info by review frame-introspection src/pip/_vendor/rich/console.py:1929:26

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

                # Fallback to the slower stack
                frame_info = inspect.stack()[offset]
                return frame_info.filename, frame_info.lineno, frame_info.frame.f_locals
    likely benign LLM, confidence 0.90 Rich console falls back to inspect.stack() to locate the caller frame for logging.
    Reasoning

    Fallback to inspect.stack() when sys._getframe is unavailable is a common and legitimate way to find the caller's file and line for logging or printing. Nothing in the snippet is exfiltrated or hidden.

  144. info critical → info by review builtins-write src/pip/_vendor/rich/pretty.py:204:13

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

                assert console is not None
                builtins._ = None  # type: ignore[attr-defined]
                console.print(
                    (
    likely benign LLM, confidence 0.75 Rich's pretty printer temporarily sets builtins._ to mirror REPL last-value behavior.
    Reasoning

    Rich's pretty printer temporarily sets builtins._ so that the expression result is available in the REPL, mirroring the sys.displayhook convention. It is a global side effect but a documented-style interactive behavior, not hidden malice.

  145. info critical → info by review builtins-write src/pip/_vendor/rich/pretty.py:221:13

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

                )
                builtins._ = value  # type: ignore[attr-defined]
    
        try:
    likely benign LLM, confidence 0.75 Rich's pretty printer sets builtins._ to the printed value, matching REPL conventions.
    Reasoning

    Restores builtins._ to the printed value after rendering, as part of the same REPL-style display mechanism. The global write is a side effect of a legitimate feature.

  146. info warn → info by review decoder-decompress-payload src/pip/_vendor/urllib3/response.py:65:21

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

            self._unfed_data = b""
            self._obj = zlib.decompressobj()
    
        def decompress(self, data: bytes, max_length: int = -1) -> bytes:
    likely benign LLM, confidence 0.95 urllib3 uses zlib.decompressobj to decode compressed HTTP response bodies.
    Reasoning

    zlib.decompressobj is the standard HTTP Content-Encoding decoder for gzip/deflate responses. Decompressing response bodies is expected behavior, not a hidden payload.

  147. identifier `ˈpjœr` mixes scripts: Other + Latin (in string/comment) (raw pass, confidence 0.40)

            sys.stdout.buffer.write(
                "* Björk Guðmundsdóttir [ˈpjœr̥k ˈkvʏðmʏntsˌtoʊhtɪr]".encode()
            )
        else:
  148. identifier `ˈkvʏðmʏntsˌtoʊhtɪr` mixes scripts: Other + Latin (in string/comment) (raw pass, confidence 0.40)

            sys.stdout.buffer.write(
                "* Björk Guðmundsdóttir [ˈpjœr̥k ˈkvʏðmʏntsˌtoʊhtɪr]".encode()
            )
        else:
  149. info critical → info by review dynamic-execution tests/functional/test_no_color.py:35:16

    `subprocess.Popen` with `shell=True` and a non-literal command — runtime-determined shell invocation (ast pass, confidence 0.85)

            cmd = command.format(option)
            proc = subprocess.Popen(
                cmd,
                shell=True,
    likely benign LLM, confidence 0.80 Functional test helper runs a templated pip command via subprocess with shell=True.
    Reasoning

    This is a functional test helper that runs a pip command built from a fixed template and an option value, with shell=True. The input is test-controlled, not attacker-supplied, so it is a test harness pattern rather than a dropper.

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/pypa/pip pip && cd pip
git checkout 26.2.1
disclude scan --severity info --diff 26.2 .