Ordered by severity, then signals introduced in this release. Hidden characters are shown as ⟨U+…⟩.
-
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.85
Stray U+200B zero-width space inside a contributor name in the AUTHORS text file.
Reasoning
A zero-width space appears inside a contributor name in the AUTHORS file (Sage Abdullah). In a plain-text credits list this is most likely a stray character from copy-paste or an editor, though it is a minor oddity. It has no code effect. Low risk, but the character is unexpected in a licence/authors file.
-
`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.85
Launches the user's editor on the pip config file through a shell command.
Reasoning
The shell=True call runs the user's configured editor with the file name in an f-string. The editor comes from the user's own environment or config, not from attacker-controlled input, and this is the standard pattern for launching an editor from pip config edit.
-
`__import__` called on a non-literal expression (ast pass, confidence 0.70)
try:
__import__(module)
except ImportError:
likely benign
LLM, confidence 0.85
Dynamic __import__ inside a hook that records missing modules during install.
Reasoning
This is the import-blocking hook used by pip's install flow. It imports a module name, records it as missing on ImportError, and re-raises. This is a legitimate way to simulate missing modules and does not hide execution.
-
U+200B ZERO WIDTH SPACE in source (in string/comment) (raw pass, confidence 0.45)
-
`__import__` called on a non-literal expression (ast pass, confidence 0.70)
try:
__import__(modulename, globals(), locals(), level=0)
except ImportError:
likely benign
LLM, confidence 0.85
Dynamic import of vendored modules to alias them under the pip._vendor namespace.
Reasoning
This is the vendoring alias mechanism, which imports a vendored module by name and silently ignores ImportError. It is a well-known compatibility pattern in pip's vendor package.
-
`__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.85
Imports a package by name to locate its resource path.
Reasoning
The function imports a package by name only when it is not already in sys.modules, then reads its __path__ to locate resources. This is standard resource-finder code in distlib.
-
`__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.85
Dynamic import of a module from a dotted path for entry-point resolution.
Reasoning
This is the resolve-by-dotted-name helper that imports a module and then walks attributes. Its input is a configured entry-point or module string, and it is a normal utility for that purpose.
-
identifier `ʼn` mixes scripts: Other + Latin (in string/comment) (raw pass, confidence 0.40)
None,
"ʼn",
"ŋ",
None,
-
identifier `α` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)
None,
"α",
"β",
"γ",
-
identifier `η` contains homoglyph candidates: η (03B7)→n (in string/comment) (raw pass, confidence 0.35)
"ζ",
"η",
"θ",
"ι",
-
identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)
"ι",
"κ",
"λ",
"μ",
-
identifier `ν` contains homoglyph candidates: ν (03BD)→v (in string/comment) (raw pass, confidence 0.35)
"μ",
"ν",
"ξ",
"ο",
-
identifier `ο` contains homoglyph candidates: ο (03BF)→o (in string/comment) (raw pass, confidence 0.35)
"ξ",
"ο",
"π",
"ρ",
-
identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)
"π",
"ρ",
None,
"σ",
-
identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)
None,
"κ",
"ρ",
"σ",
-
identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)
"κ",
"ρ",
"σ",
None,
-
identifier `і` contains homoglyph candidates: і (0456)→i (in string/comment) (raw pass, confidence 0.35)
"ѕ",
"і",
"ї",
"ј",
-
identifier `а` contains homoglyph candidates: а (0430)→a (in string/comment) (raw pass, confidence 0.35)
"џ",
"а",
"б",
"в",
-
identifier `е` contains homoglyph candidates: е (0435)→e (in string/comment) (raw pass, confidence 0.35)
"д",
"е",
"ж",
"з",
-
identifier `о` contains homoglyph candidates: о (043E)→o (in string/comment) (raw pass, confidence 0.35)
"н",
"о",
"п",
"р",
-
identifier `р` contains homoglyph candidates: р (0440)→p (in string/comment) (raw pass, confidence 0.35)
"п",
"р",
"с",
"т",
-
identifier `с` contains homoglyph candidates: с (0441)→c (in string/comment) (raw pass, confidence 0.35)
"р",
"с",
"т",
"у",
-
identifier `у` contains homoglyph candidates: у (0443)→y (in string/comment) (raw pass, confidence 0.35)
"т",
"у",
"ф",
"х",
-
identifier `х` contains homoglyph candidates: х (0445)→x (in string/comment) (raw pass, confidence 0.35)
"ф",
"х",
"ц",
"ч",
-
identifier `о` contains homoglyph candidates: о (043E)→o (in string/comment) (raw pass, confidence 0.35)
"д",
"о",
"с",
"т",
-
identifier `с` contains homoglyph candidates: с (0441)→c (in string/comment) (raw pass, confidence 0.35)
"о",
"с",
"т",
"ъ",
-
identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)
"γ",
"ρ",
"φ",
"χ",
-
identifier `aʾ` mixes scripts: Latin + Other (in string/comment) (raw pass, confidence 0.40)
None,
"aʾ",
"ṡ",
None,
-
identifier `kω` mixes scripts: Latin + Greek (in string/comment) (raw pass, confidence 0.40)
"mw",
"kω",
"mω",
None,
-
identifier `mω` mixes scripts: Latin + Greek (in string/comment) (raw pass, confidence 0.40)
"kω",
"mω",
None,
"bq",
-
identifier `α` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)
None,
"α",
"β",
"γ",
-
identifier `η` contains homoglyph candidates: η (03B7)→n (in string/comment) (raw pass, confidence 0.35)
"ζ",
"η",
"θ",
"ι",
-
identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)
"ι",
"κ",
"λ",
"μ",
-
identifier `ν` contains homoglyph candidates: ν (03BD)→v (in string/comment) (raw pass, confidence 0.35)
"μ",
"ν",
"ξ",
"ο",
-
identifier `ο` contains homoglyph candidates: ο (03BF)→o (in string/comment) (raw pass, confidence 0.35)
"ξ",
"ο",
"π",
"ρ",
-
identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)
"π",
"ρ",
"θ",
"σ",
-
identifier `α` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)
"∇",
"α",
"β",
"γ",
-
identifier `η` contains homoglyph candidates: η (03B7)→n (in string/comment) (raw pass, confidence 0.35)
"ζ",
"η",
"θ",
"ι",
-
identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)
"ι",
"κ",
"λ",
"μ",
-
identifier `ν` contains homoglyph candidates: ν (03BD)→v (in string/comment) (raw pass, confidence 0.35)
"μ",
"ν",
"ξ",
"ο",
-
identifier `ο` contains homoglyph candidates: ο (03BF)→o (in string/comment) (raw pass, confidence 0.35)
"ξ",
"ο",
"π",
"ρ",
-
identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)
"π",
"ρ",
"σ",
"τ",
-
identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)
"θ",
"κ",
"φ",
"ρ",
-
identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)
"φ",
"ρ",
"π",
"α",
-
identifier `α` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)
"π",
"α",
"β",
"γ",
-
identifier `η` contains homoglyph candidates: η (03B7)→n (in string/comment) (raw pass, confidence 0.35)
"ζ",
"η",
"θ",
"ι",
-
identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)
"ι",
"κ",
"λ",
"μ",
-
identifier `ν` contains homoglyph candidates: ν (03BD)→v (in string/comment) (raw pass, confidence 0.35)
"μ",
"ν",
"ξ",
"ο",
-
identifier `ο` contains homoglyph candidates: ο (03BF)→o (in string/comment) (raw pass, confidence 0.35)
"ξ",
"ο",
"π",
"ρ",
-
identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)
"π",
"ρ",
"θ",
"σ",
-
identifier `α` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)
"∇",
"α",
"β",
"γ",
-
identifier `η` contains homoglyph candidates: η (03B7)→n (in string/comment) (raw pass, confidence 0.35)
"ζ",
"η",
"θ",
"ι",
-
identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)
"ι",
"κ",
"λ",
"μ",
-
identifier `ν` contains homoglyph candidates: ν (03BD)→v (in string/comment) (raw pass, confidence 0.35)
"μ",
"ν",
"ξ",
"ο",
-
identifier `ο` contains homoglyph candidates: ο (03BF)→o (in string/comment) (raw pass, confidence 0.35)
"ξ",
"ο",
"π",
"ρ",
-
identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)
"π",
"ρ",
"σ",
"τ",
-
identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)
"θ",
"κ",
"φ",
"ρ",
-
identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)
"φ",
"ρ",
"π",
"α",
-
identifier `α` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)
"π",
"α",
"β",
"γ",
-
identifier `η` contains homoglyph candidates: η (03B7)→n (in string/comment) (raw pass, confidence 0.35)
"ζ",
"η",
"θ",
"ι",
-
identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)
"ι",
"κ",
"λ",
"μ",
-
identifier `ν` contains homoglyph candidates: ν (03BD)→v (in string/comment) (raw pass, confidence 0.35)
"μ",
"ν",
"ξ",
"ο",
-
identifier `ο` contains homoglyph candidates: ο (03BF)→o (in string/comment) (raw pass, confidence 0.35)
"ξ",
"ο",
"π",
"ρ",
-
identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)
"π",
"ρ",
"θ",
"σ",
-
identifier `α` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)
"∇",
"α",
"β",
"γ",
-
identifier `η` contains homoglyph candidates: η (03B7)→n (in string/comment) (raw pass, confidence 0.35)
"ζ",
"η",
"θ",
"ι",
-
identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)
"ι",
"κ",
"λ",
"μ",
-
identifier `ν` contains homoglyph candidates: ν (03BD)→v (in string/comment) (raw pass, confidence 0.35)
"μ",
"ν",
"ξ",
"ο",
-
identifier `ο` contains homoglyph candidates: ο (03BF)→o (in string/comment) (raw pass, confidence 0.35)
"ξ",
"ο",
"π",
"ρ",
-
identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)
"π",
"ρ",
"σ",
"τ",
-
identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)
"θ",
"κ",
"φ",
"ρ",
-
identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)
"φ",
"ρ",
"π",
"α",
-
identifier `α` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)
"π",
"α",
"β",
"γ",
-
identifier `η` contains homoglyph candidates: η (03B7)→n (in string/comment) (raw pass, confidence 0.35)
"ζ",
"η",
"θ",
"ι",
-
identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)
"ι",
"κ",
"λ",
"μ",
-
identifier `ν` contains homoglyph candidates: ν (03BD)→v (in string/comment) (raw pass, confidence 0.35)
"μ",
"ν",
"ξ",
"ο",
-
identifier `ο` contains homoglyph candidates: ο (03BF)→o (in string/comment) (raw pass, confidence 0.35)
"ξ",
"ο",
"π",
"ρ",
-
identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)
"π",
"ρ",
"θ",
"σ",
-
identifier `α` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)
"∇",
"α",
"β",
"γ",
-
identifier `η` contains homoglyph candidates: η (03B7)→n (in string/comment) (raw pass, confidence 0.35)
"ζ",
"η",
"θ",
"ι",
-
identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)
"ι",
"κ",
"λ",
"μ",
-
identifier `ν` contains homoglyph candidates: ν (03BD)→v (in string/comment) (raw pass, confidence 0.35)
"μ",
"ν",
"ξ",
"ο",
-
identifier `ο` contains homoglyph candidates: ο (03BF)→o (in string/comment) (raw pass, confidence 0.35)
"ξ",
"ο",
"π",
"ρ",
-
identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)
"π",
"ρ",
"σ",
"τ",
-
identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)
"θ",
"κ",
"φ",
"ρ",
-
identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)
"φ",
"ρ",
"π",
"α",
-
identifier `α` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)
"π",
"α",
"β",
"γ",
-
identifier `η` contains homoglyph candidates: η (03B7)→n (in string/comment) (raw pass, confidence 0.35)
"ζ",
"η",
"θ",
"ι",
-
identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)
"ι",
"κ",
"λ",
"μ",
-
identifier `ν` contains homoglyph candidates: ν (03BD)→v (in string/comment) (raw pass, confidence 0.35)
"μ",
"ν",
"ξ",
"ο",
-
identifier `ο` contains homoglyph candidates: ο (03BF)→o (in string/comment) (raw pass, confidence 0.35)
"ξ",
"ο",
"π",
"ρ",
-
identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)
"π",
"ρ",
"θ",
"σ",
-
identifier `α` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)
"∇",
"α",
"β",
"γ",
-
identifier `η` contains homoglyph candidates: η (03B7)→n (in string/comment) (raw pass, confidence 0.35)
"ζ",
"η",
"θ",
"ι",
-
identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)
"ι",
"κ",
"λ",
"μ",
-
identifier `ν` contains homoglyph candidates: ν (03BD)→v (in string/comment) (raw pass, confidence 0.35)
"μ",
"ν",
"ξ",
"ο",
-
identifier `ο` contains homoglyph candidates: ο (03BF)→o (in string/comment) (raw pass, confidence 0.35)
"ξ",
"ο",
"π",
"ρ",
-
identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)
"π",
"ρ",
"σ",
"τ",
-
identifier `κ` contains homoglyph candidates: κ (03BA)→k (in string/comment) (raw pass, confidence 0.35)
"θ",
"κ",
"φ",
"ρ",
-
identifier `ρ` contains homoglyph candidates: ρ (03C1)→p (in string/comment) (raw pass, confidence 0.35)
"φ",
"ρ",
"π",
"ϝ",
-
identifier `а` contains homoglyph candidates: а (0430)→a (in string/comment) (raw pass, confidence 0.35)
None,
"а",
"б",
"в",
-
identifier `е` contains homoglyph candidates: е (0435)→e (in string/comment) (raw pass, confidence 0.35)
"д",
"е",
"ж",
"з",
-
identifier `о` contains homoglyph candidates: о (043E)→o (in string/comment) (raw pass, confidence 0.35)
"м",
"о",
"п",
"р",
-
identifier `р` contains homoglyph candidates: р (0440)→p (in string/comment) (raw pass, confidence 0.35)
"п",
"р",
"с",
"т",
-
identifier `с` contains homoglyph candidates: с (0441)→c (in string/comment) (raw pass, confidence 0.35)
"р",
"с",
"т",
"у",
-
identifier `у` contains homoglyph candidates: у (0443)→y (in string/comment) (raw pass, confidence 0.35)
"т",
"у",
"ф",
"х",
-
identifier `х` contains homoglyph candidates: х (0445)→x (in string/comment) (raw pass, confidence 0.35)
"ф",
"х",
"ц",
"ч",
-
identifier `і` contains homoglyph candidates: і (0456)→i (in string/comment) (raw pass, confidence 0.35)
"ә",
"і",
"ј",
"ө",
-
identifier `а` contains homoglyph candidates: а (0430)→a (in string/comment) (raw pass, confidence 0.35)
"ӏ",
"а",
"б",
"в",
-
identifier `е` contains homoglyph candidates: е (0435)→e (in string/comment) (raw pass, confidence 0.35)
"д",
"е",
"ж",
"з",
-
identifier `о` contains homoglyph candidates: о (043E)→o (in string/comment) (raw pass, confidence 0.35)
"л",
"о",
"п",
"с",
-
identifier `с` contains homoglyph candidates: с (0441)→c (in string/comment) (raw pass, confidence 0.35)
"п",
"с",
"у",
"ф",
-
identifier `у` contains homoglyph candidates: у (0443)→y (in string/comment) (raw pass, confidence 0.35)
"с",
"у",
"ф",
"х",
-
identifier `х` contains homoglyph candidates: х (0445)→x (in string/comment) (raw pass, confidence 0.35)
"ф",
"х",
"ц",
"ч",
-
identifier `і` contains homoglyph candidates: і (0456)→i (in string/comment) (raw pass, confidence 0.35)
"ґ",
"і",
"ѕ",
"џ",
-
`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 in eval mode solely to validate its syntax.
Reasoning
compile is called with mode 'eval' only to check that a license expression is syntactically valid. It produces a code object and never executes it, and the SyntaxError is caught to report an invalid expression.
-
`__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.85
Dynamic import of a named module to obtain its loader.
Reasoning
This is the module-loading helper for entry points or requirements. It imports a named module only after a sys.modules lookup misses, which is standard pkg_resources behavior.
-
`sys._getframe` — call-stack frame introspection — file also calls `sys.exit`/`exec`/`eval` (anti-analysis shape) (ast pass, confidence 0.85)
ns = sys._getframe(1).f_globals
name = ns['__name__']
ns.clear()
likely benign
LLM, confidence 0.80
Reads the caller's globals via sys._getframe to run a distribution script.
Reasoning
This is setuptools' run_script, which runs a distribution's script in the caller's namespace. Frame introspection to get f_globals is how it sets up that namespace. The sys.exit and exec co-occurrence matches the legitimate script runner rather than an anti-analysis shape.
-
`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.85
Compiles a distribution script file before executing it in a namespace.
Reasoning
This is part of the script runner, which compiles and runs a distribution's own script file in a namespace. That is its documented purpose, and the source comes from the installed distribution's metadata.
-
`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.85
Executes a distribution script's compiled code in a namespace.
Reasoning
This exec runs the script compiled just above, as part of the same legitimate run_script or entry-point mechanism that executes a distribution's declared script.
-
`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.85
Compiles script text from a distribution's loader for execution.
Reasoning
This is the linecache-based fallback in the same script runner, compiling a distribution's script text. It does not fetch anything from elsewhere.
-
`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.85
Executes a distribution's script text in a namespace.
Reasoning
This exec runs the script text compiled in the same fallback branch of the legitimate script runner, consistent with setuptools' documented behavior.
-
`__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.85
Imports a parent namespace package to read its __path__.
Reasoning
This is the namespace-package fixup, which imports the parent package before reading its __path__. It is the standard mechanism for declared namespace packages.
-
`__import__` called on a non-literal expression (ast pass, confidence 0.70)
likely benign
LLM, confidence 0.85
Imports an entry point's module by its configured name.
Reasoning
This is EntryPoint.resolve, which imports the entry point's module by its configured name and then walks its attributes. This is the normal entry-point loading path.
-
`sys._getframe` — call-stack frame introspection — file also calls `sys.exit`/`exec`/`eval` (anti-analysis shape) (ast pass, confidence 0.85)
while sys._getframe(level).f_globals is g:
level += 1
except ValueError:
likely benign
LLM, confidence 0.90
Stack walk in pkg_resources to find the caller for a deprecation warning.
Reasoning
sys._getframe is used to walk outward until the caller's globals differ from the module's, so the warning gets the correct stacklevel. This is a standard, well-known idiom in packaging code. The nearby sys.exit/exec/eval mention is only a file-level co-occurrence and does not make this frame walk anti-analysis.
-
`__import__` called on a non-literal expression (ast pass, confidence 0.70)
mod = __import__(module_name, None, None, ['__all__'])
for formatter_name in mod.__all__:
cls = getattr(mod, formatter_name)
likely benign
LLM, confidence 0.93
Dynamic import of a built-in Pygments formatter module by name.
Reasoning
__import__ loads a formatter module by name from the package's own built-in formatter list. The name comes from the library's internal mapping, not untrusted input, which is the normal plugin-loading pattern in Pygments.
-
`exec` called on a non-literal expression (ast pass, confidence 0.70)
with open(filename, 'rb') as f:
exec(f.read(), custom_namespace)
if formattername not in custom_namespace:
likely benign
LLM, confidence 0.85
exec of a user-specified custom formatter source file.
Reasoning
exec runs a user-supplied custom formatter file in a namespace, which is a documented Pygments feature for loading custom formatters from a file path the caller provides. It is not a hidden payload, and the caller already controls the file.
-
`__import__` called on a non-literal expression (ast pass, confidence 0.70)
mod = __import__(module_name, None, None, ['__all__'])
for lexer_name in mod.__all__:
cls = getattr(mod, lexer_name)
likely benign
LLM, confidence 0.93
Dynamic import of a built-in Pygments lexer module by name.
Reasoning
Same built-in lexer-module loading pattern: __import__ on an internal module name, followed by iterating __all__ to fetch lexer classes.
-
`exec` called on a non-literal expression (ast pass, confidence 0.70)
with open(filename, 'rb') as f:
exec(f.read(), custom_namespace)
if lexername not in custom_namespace:
likely benign
LLM, confidence 0.85
exec of a user-specified custom lexer source file.
Reasoning
exec of a user-supplied custom lexer file in a namespace, a documented Pygments mechanism for loading custom lexers from a file the caller specifies.
-
`__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.92
Sphinx extension dynamically imports a lexer module from its registry.
Reasoning
Sphinx extension imports a module named in the documentation's lexer registry to read its __file__ and class. This is ordinary doc-tool plugin loading.
-
`__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.92
Sphinx extension dynamically imports a lexer module from its registry.
Reasoning
Same Sphinx lexer-registry import pattern as the other occurrence in this file.
-
`__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.93
Dynamic import of a Pygments style module by name.
Reasoning
Loads a Pygments style module by name, with ImportError converted to ClassNotFound. This is standard style lookup logic.
-
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'
-
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
Joins Unicode category strings looked up by name from module globals.
Reasoning
globals() is used to look up Unicode character-class strings by category name in the module's own constants. The lookup is internal and the inputs are not attacker-controlled.
-
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
Builds Unicode character class strings from module globals by name.
Reasoning
Same internal globals() lookup of Unicode category constants, used to build regex character classes.
-
`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.80
Reads the module's own source file to process Unicode table content.
Reasoning
The module reads its own source to parse the Unicode data tables. This is a generator or maintenance-style routine for character tables, not a payload extractor. Reading __file__ is unusual for runtime code, but nothing here decodes or executes content.
-
`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
Writes a generated header into the module's own source file.
Reasoning
The module rewrites its own source with a generated header. That is self-modifying-looking, but it is consistent with a table-regeneration script that writes Unicode data back into the source, and the snippet shows only a plain text write of a header, with no payload or execution.
-
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
Dispatches a PEP 517 build hook by name from module globals.
Reasoning
The build-hook name is looked up in globals and called as the PEP 517 hook dispatcher. The names come from a fixed set of hook functions defined in this module, which is the expected design.
-
reach-by-name through `locals` (ast pass, confidence 0.60)
vendored_package = "pip._vendor." + package
locals()[package] = __import__(vendored_package)
likely benign
LLM, confidence 0.90
Aliases vendored pip._vendor packages into the requests namespace.
Reasoning
requests aliases vendored packages such as urllib3 and chardet into its own namespace via locals() and __import__, a documented compatibility shim. The package name comes from a fixed list.
-
`__import__` called on a non-literal expression (ast pass, confidence 0.70)
vendored_package = "pip._vendor." + package
locals()[package] = __import__(vendored_package)
likely benign
LLM, confidence 0.93
Vendored-package alias shim in requests.packages that dynamically imports pip._vendor submodules.
Reasoning
This is the well-known requests.packages shim that aliases vendored modules (urllib3, chardet, idna) under the historical top-level names. The dynamic __import__ takes a name built from a fixed list of package names, not attacker input, and the locals() assignment is the documented mechanism to preserve module identity. Benign.
-
`inspect.stack` — call-stack frame introspection (ast pass, confidence 0.70)
frame_info = inspect.stack()[offset]
return frame_info.filename, frame_info.lineno, frame_info.frame.f_locals
dismissed
LLM, confidence 0.95
Fallback caller-frame lookup in rich's Console for locating the calling file and line.
Reasoning
rich uses inspect.stack() as a slower fallback to locate the caller's filename and line for logging/printing. Frame introspection like this is common in logging and output libraries and does nothing malicious here.
-
`builtins._ = ...` — patches a built-in for every importer of this module (ast pass, confidence 0.95)
assert console is not None
builtins._ = None console.print(
(
likely benign
LLM, confidence 0.90
Temporary assignment to builtins._ mirroring the REPL last-value convention during pretty printing.
Reasoning
rich's pretty printer temporarily sets builtins._ to None and then to the value, mirroring the interactive REPL's last-result convention so that `_` works in the pretty-print context. It is a known, deliberate pattern in rich's pretty module, restored/managed within the function, not a persistent backdoor.
-
`builtins._ = ...` — patches a built-in for every importer of this module (ast pass, confidence 0.95)
)
builtins._ = value
try:
likely benign
LLM, confidence 0.90
Sets builtins._ to the pretty-printed value, matching REPL last-result behavior.
Reasoning
Same pattern as the companion finding: rich sets builtins._ to the printed value so the REPL-style underscore refers to the last displayed object. Deliberate library behavior with a clear purpose, not malicious persistence.
-
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.80
Streaming zlib decompressor used by urllib3 to decode HTTP response content encodings.
Reasoning
zlib.decompressobj is the standard streaming decompressor used by urllib3 to decode gzip/deflate HTTP response bodies. The decompressed data is network content being decoded per HTTP content-encoding, not an embedded payload executed at runtime. Benign library code.
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.