Ordered by severity, then signals introduced in this release. Hidden characters are shown as ⟨U+…⟩.
-
`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
exec of a project's setup script inside run_setup, by design.
Reasoning
This executes a setup.py script inside run_setup, which is the documented purpose of the function. The exec is intentional and the noqa comment acknowledges it.
-
`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.90
exec of the setup script in the PEP 517 build backend, by design.
Reasoning
exec runs the project's setup script in the PEP 517 build backend, which is the intended behaviour. The code is marked noqa with an explicit comment that the exec is intentional.
-
`__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
Dynamically imports the Cython build_ext module to test whether Cython support is available.
Reasoning
The __import__ call is wrapped in a broad try/except and deliberately evaluated to check whether the Cython build integration is usable. The comment explains the intent, and the target is a fixed internal module name rather than attacker-controlled input.
-
`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.90
Executes the compiled setup script within a provided namespace as the launcher's core function.
Reasoning
The exec runs the compiled setup script in a namespace the launcher controls, which is the documented behavior of setuptools' launch helper that mimics running setup.py. The code is annotated as intentional and nothing in the snippet is obfuscated or remote.
-
`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-install finder and calls its install function.
Reasoning
This test execs a generated finder module in a local dict and then calls its install hook, which verifies editable-install behavior. The code is in a test file, and the finder content is generated by the test itself, so the risk is low.
-
`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
execv in a C launcher that starts a runtime-determined executable.
Reasoning
execv with a computed path is the standard pattern for a Windows GUI launcher that starts a configured interpreter or script. The snippet shows no obfuscation, encoded payload, or hidden trigger, though the path source is not visible.
-
`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
os.popen on a constructed rpm query command during RPM packaging.
Reasoning
os.popen runs a query command built from RPM tooling arguments inside distutils' bdist_rpm command. This is ordinary build-tool shell use with no encoding or concealment.
-
`subprocess.getoutput` called with a literal shell command (ast pass, confidence 0.70)
vendor_hook = subprocess.getoutput('rpm --eval %{__os_install_post}')
dismissed
LLM, confidence 0.90
Fixed rpm --eval shell call to detect a vendor-specific hook.
Reasoning
The command is a fixed literal rpm --eval call, used to detect the vendor's install post hook. It is a known, harmless distutils idiom.
-
`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.90
eval of a constant string to build a set of valid library types.
Reasoning
eval is applied to a hardcoded local string literal listing valid library types. The input is not attacker-controlled, so this is a trivial validation idiom.
-
`__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
Dynamic import of a command module by name in distutils.
Reasoning
__import__ on a module name is used to load distutils command modules dynamically. This is the standard plugin mechanism and the import is wrapped in a normal ImportError handler.
-
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-compilation of Python files during install.
Reasoning
compile is py_compile-style byte-compilation of installed Python files, which is normal install behaviour, and it is logged alongside the call.
-
file imports decoder module(s) zlib, bz2, lzma, gzip and calls `.decompress()` — embedded payload decompressed at runtime (ast pass, confidence 0.75)
dismissed
LLM, confidence 0.90
Streaming decompression of tar archive data in the tarfile backport.
Reasoning
zlib decompressobj is used to stream-decompress tar archive data in the tarfile backport. Decompression of input archives is the library's core function, not a hidden 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.70
eval of a configured expression with a fallback on TypeError in jaraco.functools.
Reasoning
eval is applied to a variable named use, which likely holds a configured expression or name. The snippet does not show where it comes from, so an untrusted source cannot be ruled out, but the context looks like a benign fallback helper.
-
`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
compile-only syntax validation of a license expression string.
Reasoning
compile with mode eval is used only as a syntax check on a license expression, and the SyntaxError is caught to report an invalid expression. Nothing is executed.
-
`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.90
marshal.load of a .pyc to inspect module bytecode for zip safety.
Reasoning
marshal.load reads a code object from a .pyc file in order to scan a module for zip-safety, which is the purpose of this function. It is a standard inspection step, not a payload launch.
-
`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
Walks the call stack with inspect.getouterframes to inspect caller frames during install.
Reasoning
inspect.getouterframes is used to walk the call stack to find a caller frame, a known pattern for detecting how the install command was invoked. The snippet shows no network, decoding, or payload activity, and setuptools is a well-known build tool, so this reads as legitimate.
-
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.85
Loads a .pyc code object with marshal.load to inspect a module without importing it.
Reasoning
marshal.load here reads cached Python bytecode from a module file after skipping the magic and date header. This is how setuptools inspects module constants for version detection, a documented and expected use inside a packaging library, not an injected payload.
-
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
Compiles module source or loads bytecode to analyze a module's contents, branching on file kind.
Reasoning
The compile and marshal pairing is the usual module-inspection logic: source files are compiled and bytecode files are unmarshalled, depending on module kind, so the decoder-plus-exec shape is expected. There is no encoded blob or remote fetch in the snippet.
-
`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
Compiles module source read from disk during module introspection.
Reasoning
compile is applied to the contents of a file the package is already analyzing, in a branch selected by module kind. The argument is data read from the project's own file, which is normal for a module-inspection helper.
-
`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.90
Compiles a setup script's source so the launcher can execute it.
Reasoning
launch.py is setuptools' script runner: it reads a setup script, normalizes line endings, and compiles it so it can run under a controlled namespace. Compiling the setup script is the purpose of the module, and the code carries an explicit noqa comment stating the exec is intentional.
-
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 shim that delegates to importlib.__import__ to intercept imports during a test.
Reasoning
This is a test helper that wraps importlib.__import__ to inject behavior or record imports during a test. The file is in tests, and the call is a standard mocking pattern for import behavior, not a production dropper.
-
`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 environment marker expressions to filter requirements for a given extra.
Reasoning
eval is applied to requirement marker strings with an extra parameter, which matches the environment-marker evaluation used when filtering requirements for extras. The eval is on package metadata from the project's own requirements rather than a fetched payload, though the non-literal eval 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.