Ordered by severity, then signals introduced in this release. Hidden characters are shown as ⟨U+…⟩.
-
`execv` called with a non-literal path (ast pass, confidence 0.90)
execv(ptr, (const char * const *)(newargs));
return fail("Could not exec %s", ptr);
}
likely benign
LLM, confidence 0.60
Launcher execs a computed target binary, likely the real application executable.
Reasoning
execv with a runtime-determined path in a launcher is a common pattern for starting a GUI binary; the path is derived from the program's own location, but the snippet alone doesn't show the origin of ptr, so it cannot be fully verified.
-
`os.popen` called on a non-literal command — runtime-determined shell invocation (ast pass, confidence 0.85)
out = os.popen(q_cmd)
try:
binary_rpms = []
likely benign
LLM, confidence 0.85
bdist_rpm runs an rpm query command to find built RPMs.
Reasoning
os.popen on a constructed rpm query command is ordinary packaging tool behavior in setuptools' bdist_rpm; the command is built from rpm query arguments, not untrusted input.
-
`subprocess.getoutput` called with a literal shell command (ast pass, confidence 0.70)
vendor_hook = subprocess.getoutput('rpm --eval %{__os_install_post}')
likely benign
LLM, confidence 0.95
bdist_rpm queries rpm macro for post-install hook detection.
Reasoning
A literal rpm --eval command to detect a vendor hook is a legitimate, well-documented step in bdist_rpm.
-
`eval` called on a non-literal expression (ast pass, confidence 0.70)
expected = '"static", "shared", "dylib", "xcode_stub"'
if lib_type not in eval(expected):
raise ValueError(f"'lib_type' must be {expected}")
fmt = getattr(self, lib_type + "_lib_format")
likely benign
LLM, confidence 0.85
Validates lib_type by evaluating a hardcoded tuple-like string.
Reasoning
eval is applied to a fixed internal string literal assigned just above, listing valid library types; it is not attacker-controlled input.
-
`exec` called on a non-literal expression (ast pass, confidence 0.70)
code = f.read().replace(r'\r\n', r'\n')
exec(code, g) finally:
sys.argv = save_argv
likely benign
LLM, confidence 0.80
run_setup executes the project's setup script as designed.
Reasoning
Executing the setup script is the documented purpose of distutils run_setup; the code is the project's own setup.py, which is inherently executed.
-
`__import__` called on a non-literal expression (ast pass, confidence 0.70)
try:
__import__(module_name)
module = sys.modules[module_name]
except ImportError:
likely benign
LLM, confidence 0.85
Imports a distutils command module by name.
Reasoning
Dynamic __import__ of a command module name is standard plugin/command loading in distutils; the module name comes from known command configuration.
-
identifier `Dεbug` mixes scripts: Latin + Greek (in string/comment) (raw pass, confidence 0.40)
caplog.set_level(logging.DEBUG)
log.debug('Dεbug\tMėssãge')
log.fatal('Fαtal\tÈrrōr')
assert caplog.messages == ['Dεbug\tMėssãge', 'Fαtal\tÈrrōr']
-
identifier `Fαtal` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)
log.debug('Dεbug\tMėssãge')
log.fatal('Fαtal\tÈrrōr')
assert caplog.messages == ['Dεbug\tMėssãge', 'Fαtal\tÈrrōr']
-
identifier `Fαtal` mixes scripts: Latin + Greek (in string/comment) (raw pass, confidence 0.40)
log.debug('Dεbug\tMėssãge')
log.fatal('Fαtal\tÈrrōr')
assert caplog.messages == ['Dεbug\tMėssãge', 'Fαtal\tÈrrōr']
-
identifier `Dεbug` mixes scripts: Latin + Greek (in string/comment) (raw pass, confidence 0.40)
log.fatal('Fαtal\tÈrrōr')
assert caplog.messages == ['Dεbug\tMėssãge', 'Fαtal\tÈrrōr']
-
identifier `Fαtal` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)
log.fatal('Fαtal\tÈrrōr')
assert caplog.messages == ['Dεbug\tMėssãge', 'Fαtal\tÈrrōr']
-
identifier `Fαtal` mixes scripts: Latin + Greek (in string/comment) (raw pass, confidence 0.40)
log.fatal('Fαtal\tÈrrōr')
assert caplog.messages == ['Dεbug\tMėssãge', 'Fαtal\tÈrrōr']
-
`compile` called on a non-literal expression (ast pass, confidence 0.70)
log.info("byte-compiling %s to %s", file, cfile_base)
compile(file, cfile, dfile)
else:
log.debug("skipping byte-compilation of %s to %s", file, cfile_base)
likely benign
LLM, confidence 0.85
Byte-compiles Python files during installation.
Reasoning
compile is used to byte-compile library source files during install, a standard distutils operation.
-
file imports decoder module(s) zlib, bz2, lzma, gzip and calls `.decompress()` — embedded payload decompressed at runtime (ast pass, confidence 0.75)
likely benign
LLM, confidence 0.80
Streaming decompressor for tar archive reading.
Reasoning
Using zlib decompressobj for streaming tar decompression is the normal implementation of the tarfile stream reader, not an embedded payload.
-
`eval` called on a non-literal expression (ast pass, confidence 0.70)
try:
return eval(use)
except TypeError:
return replace
likely benign
LLM, confidence 0.80
Vendored helper evaluates a developer-supplied expression.
Reasoning
eval of a use expression in a vendored utility is a small, known pattern in jaraco.functools for resolving a callable spec; the input is developer-supplied.
-
`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.85
Validates license expression syntax via compile.
Reasoning
compile with mode eval is used only to syntax-check a license expression, with no execution; this is a validation pattern.
-
`exec` called on a non-literal expression (ast pass, confidence 0.70)
try:
exec(code, locals()) except SystemExit as e:
if e.code:
likely benign
LLM, confidence 0.80
Build backend executes setup.py code as intended.
Reasoning
build_meta executes the project's setup script in the build backend, which is the intended design of the PEP 517 backend.
-
`marshal.load` deserializes Python bytecode from bytes — code-object sink (ast pass, confidence 0.75)
f.read(skip)
code = marshal.load(f)
f.close()
safe = True
likely benign
LLM, confidence 0.70
Reads compiled module bytecode to analyze symbol usage.
Reasoning
marshal.load reads bytecode from the build's own compiled stub files to detect symbols; this is standard egg introspection, though marshal is inherently unsafe on untrusted data.
-
`inspect.getouterframes` — call-stack frame introspection (ast pass, confidence 0.70)
frames = inspect.getouterframes(run_frame)
for frame in frames[2:4]:
(caller,) = frame[:1]
likely benign
LLM, confidence 0.85
Inspects call stack to find the calling setup frame.
Reasoning
inspect.getouterframes is used to locate the caller of the install command for setup-related logic; benign introspection.
-
line length 1035 characters (raw pass, confidence 0.50)
raise JsonSchemaValueException("" + (name_prefix or "data") + ".build-system must be object", value=data__buildsystem, name="" + (name_prefix or "data") + ".build-system", definition={'type': 'object', 'description': 'Table used to store build-related data', 'additionalProperties': False, 'properties':
-
line length 792 characters (raw pass, confidence 0.50)
raise JsonSchemaValueException("" + (name_prefix or "data") + ".dependency-groups must be object", value=data__dependencygroups, name="" + (name_prefix or "data") + ".dependency-groups", definition={'type': 'object', 'description': 'Dependency groups following PEP 735', 'additionalProperties': False, 'p
-
line length 891 characters (raw pass, confidence 0.50)
raise JsonSchemaValueException("" + (name_prefix or "data") + ".package-dir must be object", value=data__packagedir, name="" + (name_prefix or "data") + ".package-dir", definition={'$$description': [':class:`dict`-like structure mapping from package names to directories where their', 'code can be found.
-
line length 968 characters (raw pass, confidence 0.50)
raise JsonSchemaValueException("" + (name_prefix or "data") + ".package-data must be object", value=data__packagedata, name="" + (name_prefix or "data") + ".package-data", definition={'$$description': ['Mapping from package names to lists of glob patterns.', 'Usually this option is not needed when using
-
line length 934 characters (raw pass, confidence 0.50)
raise JsonSchemaValueException("" + (name_prefix or "data") + ".exclude-package-data must be object", value=data__excludepackagedata, name="" + (name_prefix or "data") + ".exclude-package-data", definition={'$$description': ['Mapping from package names to lists of glob patterns that should be excluded',
-
line length 1720 characters (raw pass, confidence 0.50)
raise JsonSchemaValueException("" + (name_prefix or "data") + ".ext-modules must be array", value=data__extmodules, name="" + (name_prefix or "data") + ".ext-modules", definition={'description': 'Extension modules to be compiled by setuptools', 'type': 'array', 'items': {'$id': '#/definitions/ext-module
-
line length 791 characters (raw pass, confidence 0.50)
raise JsonSchemaValueException("" + (name_prefix or "data") + ".data-files must be object", value=data__datafiles, name="" + (name_prefix or "data") + ".data-files", definition={'$$description': ['``dict``-like structure where each key represents a directory and', 'the value is a list of glob patterns t
-
line length 1584 characters (raw pass, confidence 0.50)
raise JsonSchemaValueException("" + (name_prefix or "data") + " must be object", value=data, name="" + (name_prefix or "data") + "", definition={'$id': '#/definitions/ext-module', 'title': 'Extension module', 'description': 'Parameters to construct a :class:`setuptools.Extension` object', 'type': 'object', 'req
-
line length 1643 characters (raw pass, confidence 0.50)
raise JsonSchemaValueException("" + (name_prefix or "data") + " must contain " + (str(sorted(data__missing_keys)) + " properties"), value=data, name="" + (name_prefix or "data") + "", definition={'$id': '#/definitions/ext-module', 'title': 'Extension module', 'description': 'Parameters to construct a :class
-
line length 1636 characters (raw pass, confidence 0.50)
raise JsonSchemaValueException("" + (name_prefix or "data") + " must not contain "+str(data_keys)+" properties", value=data, name="" + (name_prefix or "data") + "", definition={'$id': '#/definitions/ext-module', 'title': 'Extension module', 'description': 'Parameters to construct a :class:`setuptools.Extens
-
line length 1230 characters (raw pass, confidence 0.50)
raise JsonSchemaValueException("" + (name_prefix or "data") + " must be object", value=data, name="" + (name_prefix or "data") + "", definition={'$id': '#/definitions/find-directive', 'title': "'find:' directive", 'type': 'object', 'additionalProperties': False, 'properties': {'find': {'type': 'object', '$$desc
-
line length 1110 characters (raw pass, confidence 0.50)
raise JsonSchemaValueException("" + (name_prefix or "data") + ".find must be object", value=data__find, name="" + (name_prefix or "data") + ".find", definition={'type': 'object', '$$description': ['Dynamic `package discovery', '<https://setuptools.pypa.io/en/latest/userguide/package_discovery.html>`_.']
-
line length 1282 characters (raw pass, confidence 0.50)
raise JsonSchemaValueException("" + (name_prefix or "data") + " must not contain "+str(data_keys)+" properties", value=data, name="" + (name_prefix or "data") + "", definition={'$id': '#/definitions/find-directive', 'title': "'find:' directive", 'type': 'object', 'additionalProperties': False, 'properties':
-
line length 1502 characters (raw pass, confidence 0.50)
raise JsonSchemaValueException("" + (name_prefix or "data") + ".readme must be valid exactly by one definition" + (" (" + str(data__readme_one_of_count12) + " matches found)"), value=data__readme, name="" + (name_prefix or "data") + ".readme", definition={'$$description': ['`Full/detailed description of
-
line length 935 characters (raw pass, confidence 0.50)
raise JsonSchemaValueException("" + (name_prefix or "data") + ".license must be valid exactly by one definition" + (" (" + str(data__license_one_of_count14) + " matches found)"), value=data__license, name="" + (name_prefix or "data") + ".license", definition={'description': '`Project license <https://pe
-
line length 963 characters (raw pass, confidence 0.50)
raise JsonSchemaValueException("" + (name_prefix or "data") + ".authors must be array", value=data__authors, name="" + (name_prefix or "data") + ".authors", definition={'type': 'array', 'items': {'$id': '#/definitions/author', 'title': 'Author or Maintainer', '$comment': 'https://peps.python.org/pep-062
-
line length 920 characters (raw pass, confidence 0.50)
raise JsonSchemaValueException("" + (name_prefix or "data") + ".maintainers must be array", value=data__maintainers, name="" + (name_prefix or "data") + ".maintainers", definition={'type': 'array', 'items': {'$id': '#/definitions/author', 'title': 'Author or Maintainer', '$comment': 'https://peps.python
-
line length 837 characters (raw pass, confidence 0.50)
raise JsonSchemaValueException("" + (name_prefix or "data") + ".dynamic[{data__dynamic_x}]".format(**locals()) + " must be one of ['version', 'description', 'readme', 'requires-python', 'license', 'license-files', 'authors', 'maintainers', 'keywords', 'classifiers', 'urls', 'scripts', 'gui-scrip
-
line length 968 characters (raw pass, confidence 0.50)
raise JsonSchemaValueException("" + (name_prefix or "data") + " must be object", value=data, name="" + (name_prefix or "data") + "", definition={'$id': '#/definitions/entry-point-group', 'title': 'Entry-points', 'type': 'object', '$$description': ['Entry-points are grouped together to indicate what sort of capa
-
line length 1020 characters (raw pass, confidence 0.50)
raise JsonSchemaValueException("" + (name_prefix or "data") + " must not contain "+str(data_keys)+" properties", value=data, name="" + (name_prefix or "data") + "", definition={'$id': '#/definitions/entry-point-group', 'title': 'Entry-points', 'type': 'object', '$$description': ['Entry-points are grouped to
-
line length 1011 characters (raw pass, confidence 0.50)
raise JsonSchemaValueException("" + (name_prefix or "data") + " must be named by propertyName definition", value=data, name="" + (name_prefix or "data") + "", definition={'$id': '#/definitions/entry-point-group', 'title': 'Entry-points', 'type': 'object', '$$description': ['Entry-points are grouped toge
-
`marshal.load` deserializes Python bytecode from bytes — code-object sink (ast pass, confidence 0.75)
f.read(8) code = marshal.load(f)
elif kind == PY_FROZEN:
code = _imp.get_frozen_object(module, paths)
likely benign
LLM, confidence 0.75
Loads compiled module code to read version information.
Reasoning
marshal.load reads bytecode from a module file being inspected for version constants, a standard pattern in depends.py.
-
file imports decoder module(s) marshal and calls `exec`/`eval`/`compile` — multi-stage payload shape (ast pass, confidence 0.80)
elif kind == PY_SOURCE:
code = compile(f.read(), path, 'exec')
else:
likely benign
LLM, confidence 0.85
Setuptools dependency helper compiles module source or reads marshaled bytecode to inspect a module.
Reasoning
The compile call is the standard bytecode/source handling in setuptools' depends module, used to parse module source for version detection. The marshal import is for reading .pyc bytecode, a legitimate use. The shape matches the signal but this is a known, benign library pattern.
-
`compile` called on a non-literal expression (ast pass, confidence 0.70)
elif kind == PY_SOURCE:
code = compile(f.read(), path, 'exec')
else:
likely benign
LLM, confidence 0.85
compile() applied to source read from a local module file during dependency detection.
Reasoning
compile() on file content read from a discovered module path is ordinary parsing of Python source for dependency inspection; the input is not attacker-controlled network data.
-
`__import__` called on a non-literal expression (ast pass, confidence 0.70)
__import__(cython_impl, fromlist=['build_ext']).build_ext except Exception: return False
likely benign
LLM, confidence 0.80
Feature-detection probe that tries importing Cython's build_ext and returns False on failure.
Reasoning
The __import__ with fromlist is used to probe whether Cython build_ext is available, inside a try/except returning False. It is a feature-detection pattern in setuptools, with a noqa comment explaining intent. Critical severity is overstated for this context.
-
`compile` called on a non-literal expression (ast pass, confidence 0.70)
norm_script = script.replace('\\r\\n', '\\n')
code = compile(norm_script, script_name, 'exec')
exec(code, namespace)
likely benign
LLM, confidence 0.85
Launcher compiles and executes a setup script within a provided namespace, by design.
Reasoning
This is the setuptools launcher that executes a script's source in a namespace, a deliberate and documented function emulating running a setup script. The exec is intended behavior, not hidden obfuscation.
-
`exec` called on a non-literal expression (ast pass, confidence 0.70)
code = compile(norm_script, script_name, 'exec')
exec(code, namespace)
likely benign
LLM, confidence 0.85
Launcher executes compiled setup script code in a namespace, intentionally.
Reasoning
Same launcher: exec of the compiled script code with an explicit noqa stating intent. This is the expected behavior of the setuptools launch utility.
-
identifier `Γαμα` contains homoglyph candidates: α (03B1)→a, α (03B1)→a (in string/comment) (raw pass, confidence 0.35)
{name = "John X. Ãørçeč", email = "john@utf8.org"},
{name = "Γαμα קּ 東", email = "gama@utf8.org"},
]
classifiers = [
-
identifier `Γαμα` mixes scripts: Greek + Latin (in string/comment) (raw pass, confidence 0.40)
{name = "John X. Ãørçeč", email = "john@utf8.org"},
{name = "Γαμα קּ 東", email = "gama@utf8.org"},
]
classifiers = [
-
identifier `Γαμα` contains homoglyph candidates: α (03B1)→a, α (03B1)→a (in string/comment) (raw pass, confidence 0.35)
'Brett Cannon <brett@python.org>, "John X. Ãørçeč" <john@utf8.org>, '
'Γαμα קּ 東 <gama@utf8.org>'
),
id='non-international-emails',
-
identifier `Γαμα` mixes scripts: Greek + Latin (in string/comment) (raw pass, confidence 0.40)
'Brett Cannon <brett@python.org>, "John X. Ãørçeč" <john@utf8.org>, '
'Γαμα קּ 東 <gama@utf8.org>'
),
id='non-international-emails',
-
identifier `Γαμα` contains homoglyph candidates: α (03B1)→a, α (03B1)→a (in string/comment) (raw pass, confidence 0.35)
version = 42
author_email = "John X. Ãørçeč" <john@utf8.org>, Γαμα קּ 東 <gama@utf8.org>
long_description = file: README.rst
-
identifier `Γαμα` mixes scripts: Greek + Latin (in string/comment) (raw pass, confidence 0.40)
version = 42
author_email = "John X. Ãørçeč" <john@utf8.org>, Γαμα קּ 東 <gama@utf8.org>
long_description = file: README.rst
-
identifier `Γαμα` contains homoglyph candidates: α (03B1)→a, α (03B1)→a (in string/comment) (raw pass, confidence 0.35)
Version: 42
Author-email: "John X. Ãørçeč" <john@utf8.org>, Γαμα קּ 東 <gama@utf8.org>
-
identifier `Γαμα` mixes scripts: Greek + Latin (in string/comment) (raw pass, confidence 0.40)
Version: 42
Author-email: "John X. Ãørçeč" <john@utf8.org>, Γαμα קּ 東 <gama@utf8.org>
-
identifier `Γαμα` contains homoglyph candidates: α (03B1)→a, α (03B1)→a (in string/comment) (raw pass, confidence 0.35)
assert 'Author-email: "John X. Ãørçeč"' in metadata
assert "Γαμα קּ 東 " in metadata
assert "UTF-8 描述 説明" in metadata
-
identifier `Γαμα` mixes scripts: Greek + Latin (in string/comment) (raw pass, confidence 0.40)
assert 'Author-email: "John X. Ãørçeč"' in metadata
assert "Γαμα קּ 東 " in metadata
assert "UTF-8 描述 説明" in metadata
-
`__import__` called on a non-literal expression (ast pass, confidence 0.70)
return importlib.__import__(name, *args, **kwargs)
with suppress(KeyError):
likely benign
LLM, confidence 0.85
Test helper that wraps importlib.__import__ to mock or intercept imports during testing.
Reasoning
This is a test helper wrapping importlib.__import__ to simulate import behavior, typical in test fixtures for mocking imports. Not a payload or obfuscation.
-
`exec` called on a non-literal expression (ast pass, confidence 0.70)
loc = {}
exec(finder, loc, loc) loc["install"]()
likely benign
LLM, confidence 0.85
Test executes a generated editable finder snippet in a local namespace to verify install behavior.
Reasoning
Test code executing a generated editable-install finder in a local dict with an explicit noqa. It is test scaffolding for editable installs, not malicious.
-
`eval` called on a non-literal expression (ast pass, confidence 0.70)
raw_req,
(req for req in reqs if for_extra(req) and eval(req, extra=extra)),
)
)
likely benign
LLM, confidence 0.80
Evaluates requirement environment markers for extras when building wheel metadata.
Reasoning
eval is applied to requirement marker strings with an extra context, which is the standard evaluation of environment markers for extras in wheel metadata. Expected library behavior on trusted metadata, though eval on strings is worth noting.
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.