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.80
Launcher execv's a computed target path to start a GUI executable.
Reasoning
execv in a launcher after building newargs for a GUI program is a standard exec pattern; the path is runtime-determined but this is the program's own launch logic, with an error fallback. Not obfuscation by itself, though the non-literal path warrants a glance at its origin.
-
`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 via os.popen to list built binary RPMs.
Reasoning
os.popen on a constructed rpm query command is ordinary build tooling in distutils' bdist_rpm, used to query built RPM files. Known legitimate setuptools code.
-
`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.90
Runs a hardcoded rpm --eval command to read the __os_install_post macro.
Reasoning
A fixed literal rpm --eval command for detecting the RHEL install hook is benign build logic with no external input.
-
`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
eval of a constant tuple string to validate lib_type.
Reasoning
eval on a fixed string literal defined a line above, listing valid library types. Unusual style but no external input reaches it.
-
`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.90
run_setup executes the user's setup.py script by design.
Reasoning
exec of the setup script is the documented purpose of distutils run_setup; the code comes from the project being built, which is expected.
-
`__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.90
Imports a command module by name for distutils command resolution.
Reasoning
Dynamic __import__ of a command module name inside a try/except ImportError is standard plugin loading in distutils.
-
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.90
Byte-compiles Python files during install, a standard distutils routine.
Reasoning
compile of a source file during byte-compilation is the normal distutils byte-compile utility 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.85
Streaming decompression for reading compressed tar archives.
Reasoning
zlib decompressobj in a streaming tar reader is the normal implementation of decompressing tar data for reading archives.
-
`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.85
Vendored jaraco helper evaluates an expression string.
Reasoning
eval of a 'use' expression in a jaraco helper is a known pattern for evaluating a type-ish or expression argument; it is a vendored utility and not reached from untrusted input in this snippet.
-
`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
Syntax-checks a license expression string via compile.
Reasoning
compile with mode eval is used only to syntax-check a license expression for validation; it does not execute the code.
-
`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.85
PEP 517 backend executes the project's setup script.
Reasoning
build_meta executes the project's setup.py in a locals namespace as part of the PEP 517 build backend; that is its purpose.
-
`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.80
Reads compiled bytecode from a module file to check zip safety.
Reasoning
marshal.load of bytecode from a .pyc during egg scanning for zip-safety analysis is ordinary setuptools behavior, though marshal is a code-object sink in general.
-
`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.90
Inspects the call stack to find the caller of the install run.
Reasoning
getouterframes is used to locate the caller of a setup run for install behavior; standard introspection in setuptools.
-
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.90
Reads a module's compiled code object to extract constants.
Reasoning
marshal.load of a module's bytecode is the standard way depends.py extracts constants from compiled modules for version detection.
-
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.90
Setuptools dependency helper compiles Python source it reads from disk.
Reasoning
compile of source read from a file in a module-introspection helper for setuptools; the 'marshal' import is part of standard bytecode handling. Legitimate code for inspecting dependency modules, not a dropper.
-
`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.90
compile call on file contents inside setuptools' module inspection code.
Reasoning
compile(f.read(), path, 'exec') on a source file in setuptools' depends module is a standard way to analyze a module's code object; the non-literal argument is expected here.
-
`__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.90
Setuptools extension code dynamically imports the Cython build_ext module to validate availability.
Reasoning
This is a deliberate import used to trigger Cython validation within a try/except returning False; the broad fallback is documented and the import target is an internal module name. Dynamic import is common and not payload-like here.
-
`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.92
Setuptools launch helper compiles and executes a user setup script.
Reasoning
setuptools' launcher compiles and executes a setup script in a namespace, which is its documented purpose (running setup.py under setuptools control). The exec is explicit and commented as intentional.
-
`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.92
Setuptools launch helper executes the compiled setup script.
Reasoning
exec of the compiled setup script is the core intended behavior of setuptools' launch module; the code is transparent and not encoded or hidden.
-
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.90
Test code wraps importlib.__import__ for mocking.
Reasoning
A test helper wrapping importlib.__import__ to simulate import behavior, typical of test mocking. No malicious indicators in the snippet.
-
`exec` called on a non-literal expression (ast pass, confidence 0.70)
loc = {}
exec(finder, loc, loc) loc["install"]()
likely benign
LLM, confidence 0.90
Editable-install test execs generated finder code in a local namespace.
Reasoning
Test for editable installs execs a generated finder code with a local namespace, a standard pattern in the test suite; the exec is marked intentional.
-
`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.88
Wheel metadata code evaluates requirement markers with eval.
Reasoning
eval evaluates requirement environment markers for extras in wheel metadata handling; this is the expected marker-evaluation mechanism in setuptools, operating on requirement strings rather than hidden payloads.
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.