🔧 pyinfra turns Python code into shell commands and runs them on your servers. Execute ad-hoc commands and write declarative operations. Target SSH servers, local machine and Docker containers. Fast and scales from one server to thousands.
This report presents the forensic synthetic code analysis of pyinfra-dev/pyinfra, a Python project with 5,923 GitHub stars. SynthScan v2.0 examined 82,164 lines of code across 1791 source files, recording 807 pattern matches distributed across 15 syntactic categories. The overall adjusted score of 13.9 places this repository in the Low AI signal band.
The scanner applied 160+ deterministic lexical heuristics, multi-line block detectors, abstract syntax tree depth profilers, and a cross-file Jaccard similarity matrix to construct a statistically normalised synthetic code estimate. All matches are individually weighted by severity coefficient and contextual multiplier before summation, and the resulting headline score is temporally discounted to account for the repository's development history relative to the commercial emergence of large language model coding tooling (November 2022 onward).
Longitudinal tracking requires multiple scan runs. Once this repository is re-scanned after new commits land, this chart will visualise how the synthetic code signal evolves over time — enabling you to detect whether AI authorship is growing, stabilising, or being actively corrected by human engineers.
Classifies detected patterns by their diagnostic confidence and structural impact. CRITICAL patterns (coefficient 10) represent definitive synthetic signatures — hallucinated imports, explicit LLM attribution metadata — virtually never produced by human authors. HIGH (5) indicates strong structural tells such as cross-file repetition or cross-linguistic idioms. MEDIUM (2) covers recognisable conversational padding and AI-specific vocabulary. LOW (1) captures subtle indicators like tautological comments and generic boilerplate that require density to carry independent signal.
This horizontal bar chart decomposes the repository's raw synthetic code score by top-level directory, allowing you to pinpoint precisely which modules or components carry the highest AI authorship density. Directories with disproportionately high scores relative to their size warrant targeted manual review: concentrated AI signatures often trace back to mass-generated configuration layers, auto-ported test suites, LLM-scaffolded boilerplate classes, or entire subsystems authored under heavy copilot assistance. Use this view to prioritise your human code-review effort.
The scanner identified 807 distinct pattern matches across 15 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a statistically significant AI authorship indicator. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the diagnostic confidence level (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — comment-context matches receive a ×1.5 weight because LLMs systematically over-annotate. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier as dense clusters constitute far stronger evidence of synthetic authorship than isolated hits.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/test_facts_documentation.py | 4 | def test_deb_package_documents_package_resolution(): | CODE |
| LOW⚡ | tests/test_facts_packages.py | 12 | def test_numeric_run_compares_as_int_not_lexicographic(self): | CODE |
| LOW⚡ | tests/test_facts_packages.py | 18 | def test_trailing_revision_sorts_after_base(self): | CODE |
| LOW⚡ | tests/test_facts_packages.py | 21 | def test_equal_versions_have_equal_keys(self): | CODE |
| LOW⚡ | tests/test_facts_packages.py | 24 | def test_shorter_version_sorts_before_its_extension(self): | CODE |
| LOW⚡ | tests/test_facts_packages.py | 33 | def test_defaults_to_installed_status(self): | CODE |
| LOW⚡ | tests/test_facts_packages.py | 43 | def test_installed_version_returns_highest(self): | CODE |
| LOW⚡ | tests/test_facts_packages.py | 47 | def test_installed_version_none_when_no_versions(self): | CODE |
| LOW⚡ | tests/test_facts_packages.py | 81 | def test_held_takes_precedence_over_upgradeable(self): | CODE |
| LOW⚡ | tests/test_facts_packages.py | 90 | def test_handles_empty_versions(self): | CODE |
| LOW⚡ | tests/test_facts_packages.py | 95 | def test_multiple_versions_sorted_natural_order(self): | CODE |
| LOW | tests/test_facts_packages.py | 107 | def test_multiple_versions_natural_order_beats_lexicographic(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 33 | def test_zero_prefixed_string(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 36 | def test_octal_prefixed_string(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 39 | def test_uppercase_octal_prefixed_string(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 45 | def test_symbolic_mode_passes_through(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 51 | def test_non_octal_int_raises(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 55 | def test_non_octal_string_raises(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 79 | def test_ip_address_with_port(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 85 | def test_invalid_port_raises_error(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 90 | def test_empty_port_raises_error(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 95 | def test_negative_port_raises_error(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 100 | def test_port_too_large_raises_error(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 105 | def test_float_port_raises_error(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 132 | def test_repository_with_digest(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 142 | def test_repository_with_tag_and_digest(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 152 | def test_namespace_repository(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 162 | def test_namespace_repository_with_tag(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 182 | def test_registry_with_port_repository(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 192 | def test_registry_namespace_repository(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 202 | def test_registry_with_port_namespace_repository(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 296 | def test_empty_image_raises_error(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 301 | def test_whitespace_only_image_raises_error(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 306 | def test_none_image_raises_error(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 311 | def test_invalid_registry_port_raises_error(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 355 | def test_old_format_installed_no_latest(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 360 | def test_old_format_multiple_versions_noop_is_sorted(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 366 | def test_old_format_latest_blindly_upgrades(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 370 | def test_old_format_missing_installs(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 374 | def test_new_format_installed_uses_status(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 384 | def test_new_format_latest_only_upgrades_upgradeable(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 488 | def test_new_format_uninstall_removes_installed_package(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 497 | def test_new_format_uninstall_held_package_proceeds(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 505 | def test_new_format_uninstall_missing_package_is_noop(self): | CODE |
| LOW⚡ | tests/test_operations_utils.py | 510 | def test_new_format_multi_version_noop_lists_all_versions(self): | CODE |
| LOW | tests/test_operations_utils.py | 67 | def test_registry_without_port(self): | CODE |
| LOW | tests/test_operations_utils.py | 242 | def test_complex_tag_with_colon_in_registry(self): | CODE |
| LOW | tests/test_operations_utils.py | 274 | def test_property_registry_without_port(self): | CODE |
| LOW | tests/test_operations_utils.py | 285 | def test_property_full_reference(self): | CODE |
| LOW | tests/test_operations_utils.py | 326 | def test_github_container_registry_image(self): | CODE |
| LOW | tests/test_operations_utils.py | 400 | def test_new_format_held_is_noop_even_when_latest(self): | CODE |
| LOW | tests/test_operations_utils.py | 413 | def test_new_format_missing_installs(self): | CODE |
| LOW | tests/test_operations_utils.py | 417 | def test_new_format_versioned_match_is_noop(self): | CODE |
| LOW | tests/test_operations_utils.py | 440 | def test_new_format_versioned_mismatch_installs_pinned(self): | CODE |
| LOW | tests/test_operations_utils.py | 462 | def test_new_format_upgradeable_with_pinned_version_installs_not_upgrades(self): | CODE |
| LOW | tests/test_operations_utils.py | 523 | def test_new_format_multi_version_pinned_match_against_any_version(self): | CODE |
| LOW | tests/test_units.py | 4 | def test_parse_human_readable_size(): | CODE |
| LOW | tests/paramiko_util.py | 31 | class FakeAgentRequestHandler: | CODE |
| LOW | tests/paramiko_util.py | 69 | def set_missing_host_key_policy(self, _): | CODE |
| LOW | tests/test_global_arguments.py | 41 | def test_operations_do_not_use_global_arguments(self): | CODE |
| 282 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH⚡ | tests/test_connectors/test_util.py | 134 | "sh -c 'export key=value anotherkey=anothervalue && uptime'", | CODE |
| HIGH⚡ | tests/test_connectors/test_util.py | 135 | "sh -c 'export anotherkey=anothervalue key=value && uptime'", | CODE |
| HIGH⚡ | tests/test_connectors/test_util.py | 186 | assert command.get_raw_value() == "sh -c 'cd /opt/somedir && uptime'" | CODE |
| HIGH | tests/test_connectors/test_util.py | 210 | "'bash -c '\"'\"'cd /opt/somedir && export key=value " # shell and export bit | CODE |
| HIGH | tests/test_connectors/test_ssh.py | 1176 | "/tmp/pyinfra-e9c0d3c8ffca943daa0e75511b0a09c84b59c508 && chmod +r /tmp/pyinfra-e9c0d3c8ffca943d | CODE |
| HIGH | tests/test_connectors/test_ssh.py | 1227 | "/tmp/pyinfra-e9c0d3c8ffca943daa0e75511b0a09c84b59c508 && chmod +r /tmp/pyinfra-e9c0d3c8ffca943d | CODE |
| HIGH | tests/test_connectors/test_ssh.py | 1268 | "/tmp/pyinfra-e9c0d3c8ffca943daa0e75511b0a09c84b59c508 && chmod +r /tmp/pyinfra-e9c0d3c8ffca943d | CODE |
| HIGH | tests/test_connectors/test_ssh.py | 1321 | "/tmp/pyinfra-e9c0d3c8ffca943daa0e75511b0a09c84b59c508 && chmod +r " | CODE |
| HIGH | tests/test_api/test_api_operations.py | 391 | hosts=(("somehost", {"ssh_config_file": "/home/me/ssh_test_config && echo hi"}),) | CODE |
| HIGH | tests/test_api/test_api_operations.py | 409 | "-F '/home/me/ssh_test_config && echo hi'\"" | CODE |
| HIGH⚡ | src/pyinfra/operations/files.py | 2043 | "2>/dev/null || stat -f %Lp", | CODE |
| HIGH⚡ | src/pyinfra/operations/files.py | 2045 | '2>/dev/null)" &&', | CODE |
| HIGH⚡ | src/pyinfra/operations/files.py | 2053 | '2>/dev/null || stat -f "%u:%g"', | CODE |
| HIGH⚡ | src/pyinfra/operations/files.py | 2055 | '2>/dev/null || echo $(id -un):$(id -gn))" &&', | CODE |
| HIGH | src/pyinfra/operations/files.py | 251 | "(( sha1sum {0} 2> /dev/null || shasum {0} || sha1 {0} ) | grep {1} ) " | CODE |
| HIGH | src/pyinfra/operations/files.py | 262 | "(( sha256sum {0} 2> /dev/null || shasum -a 256 {0} || sha256 {0} ) " | CODE |
| HIGH | src/pyinfra/operations/files.py | 273 | "(( sha384sum {0} 2> /dev/null || shasum -a 384 {0} ) " | CODE |
| HIGH | src/pyinfra/operations/files.py | 283 | ("(( md5sum {0} 2> /dev/null || md5 {0} ) | grep {1} ) || ( echo {2} && exit 1 )"), | CODE |
| HIGH | src/pyinfra/operations/server.py | 104 | "( sleep 1 && reboot ) </dev/null >/dev/null 2>&1 &", | CODE |
| HIGH | src/pyinfra/operations/runit.py | 158 | f" sv status {service} > /dev/null && exit 0\n" | CODE |
| HIGH | src/pyinfra/operations/apt.py | 448 | "2> /dev/null || true", | CODE |
| HIGH | src/pyinfra/operations/util/packaging.py | 335 | yield f"rpm -q `rpm -qp {source}` 2> /dev/null || rpm -i {source}" | CODE |
| HIGH | src/pyinfra/facts/files.py | 456 | ("{3} -e {0} {1} 2> /dev/null || ( find {1} -type f > /dev/null && echo {2} || true )"), | CODE |
| HIGH | src/pyinfra/facts/files.py | 666 | "(find {0} -type f > /dev/null && echo {1} || echo {2} )", | CODE |
| HIGH | src/pyinfra/facts/git.py | 43 | return f"git config {level} -l || true" | CODE |
| HIGH | src/pyinfra/facts/git.py | 86 | return f"! test -d {repo} || (cd {repo} && git rev-parse {ref} 2>/dev/null) || true" | CODE |
| HIGH⚡ | src/pyinfra/facts/server.py | 838 | LASTLOG=`(((lastlog -u $i || lastlogin $i) 2> /dev/null) | grep ^$i | tr -s ' ')`; | CODE |
| HIGH⚡ | src/pyinfra/facts/server.py | 838 | LASTLOG=`(((lastlog -u $i || lastlogin $i) 2> /dev/null) | grep ^$i | tr -s ' ')`; | CODE |
| HIGH⚡ | src/pyinfra/facts/server.py | 839 | PASSWORD=`(grep ^$i: /etc/shadow || grep ^$i: /etc/master.passwd) 2> /dev/null | cut -d: -f2`; | CODE |
| HIGH | src/pyinfra/facts/server.py | 484 | return "ss -lpuntn || true" | STRING |
| HIGH | src/pyinfra/facts/server.py | 487 | return "netstat -tunp 2>/dev/null || true" | STRING |
| HIGH | src/pyinfra/facts/server.py | 613 | return "! test -f /proc/modules || cat /proc/modules" | STRING |
| HIGH | src/pyinfra/facts/server.py | 749 | return StringCommand("sysctl -a 2>/dev/null || true") | STRING |
| HIGH | src/pyinfra/facts/server.py | 750 | return StringCommand("sysctl", *[QuoteString(key) for key in keys], "2>/dev/null || true") | STRING |
| HIGH | src/pyinfra/facts/server.py | 910 | return StringCommand("cat", QuoteString(path), "2>/dev/null || true") | STRING |
| HIGH | src/pyinfra/facts/server.py | 914 | return StringCommand("cat", f"~{user}/.ssh/authorized_keys", "2>/dev/null || true") | STRING |
| HIGH | src/pyinfra/facts/server.py | 1109 | return "ls /usr/bin/*session || true" | STRING |
| HIGH | src/pyinfra/facts/server.py | 1231 | return "! test -e /etc/security/limits.conf || cat /etc/security/limits.conf" | STRING |
| HIGH | src/pyinfra/facts/server.py | 1431 | return make_formatted_string_command("cat {0} 2>/dev/null || true", QuoteString(path)) | STRING |
| HIGH | src/pyinfra/facts/server.py | 1497 | return "last -Fwi 2>/dev/null || last -w 2>/dev/null || last 2>/dev/null || true" | STRING |
| HIGH | src/pyinfra/facts/server.py | 1568 | return "cat /proc/loadavg 2>/dev/null || uptime" | STRING |
| HIGH | src/pyinfra/facts/server.py | 1616 | return "lastb -Fwi 2>/dev/null || lastb 2>/dev/null || true" | STRING |
| HIGH | src/pyinfra/facts/selinux.py | 83 | return f"set -o pipefail && semanage fcontext -n -l | (grep '^{target}' || true)" | CODE |
| HIGH | src/pyinfra/facts/selinux.py | 156 | return f"(sepolicy network -p {port} 2>/dev/null || true) | grep {protocol}" | CODE |
| HIGH | src/pyinfra/facts/deb.py | 90 | "test -f {0} && case {0} in *.deb) dpkg -I {0} ;; *) dpkg -s {0} 2>/dev/null || true ;; esac || dpkg -s {0} | CODE |
| HIGH | src/pyinfra/facts/efibootmgr.py | 49 | return "efibootmgr || true" | CODE |
| HIGH | src/pyinfra/facts/crontab.py | 168 | return StringCommand("crontab -l || true") | STRING |
| HIGH | src/pyinfra/facts/freebsd.py | 61 | ("pkg info -E -- {0} 2> /dev/null || true"), QuoteString(package) | CODE |
| HIGH | src/pyinfra/facts/freebsd.py | 65 | ("pkg -j {0} info -E -- {1} 2> /dev/null || true"), | CODE |
| HIGH | src/pyinfra/facts/docker.py | 83 | ids=$(docker ps -qa) && [ -n "$ids" ] && docker container inspect $ids || echo "[]" | CODE |
| HIGH | src/pyinfra/facts/docker.py | 95 | ids=$(docker images -q) && [ -n "$ids" ] && docker image inspect $ids || echo "[]" | CODE |
| HIGH | src/pyinfra/facts/docker.py | 127 | ids=$(docker plugin ls -q) && [ -n "$ids" ] && docker plugin inspect $ids || echo "[]" | CODE |
| HIGH | src/pyinfra/facts/gpg.py | 178 | f' gpg --list-keys --with-colons --keyring "$1" --no-default-keyring 2>/dev/null || true\' _ {{}} \\; ;' | CODE |
| HIGH | src/pyinfra/facts/gpg.py | 180 | f' -exec sh -c \'echo "KEYRING:$1"; gpg --with-colons "$1" 2>/dev/null || true\' _ {{}} \\;' | CODE |
| HIGH | src/pyinfra/facts/hardware.py | 142 | return "getconf NPROCESSORS_ONLN 2> /dev/null || getconf _NPROCESSORS_ONLN" | CODE |
| HIGH | src/pyinfra/facts/hardware.py | 352 | return "ip -j addr show 2> /dev/null || ip addr show 2> /dev/null || ifconfig -a" | CODE |
| HIGH | src/pyinfra/facts/pkg.py | 26 | return "pkg info || pkg_info || true" | CODE |
| HIGH | src/pyinfra/facts/brew.py | 119 | r'if brew --version | grep -q -e "Homebrew\ +(1\.|2\.[0-5]).*" 1>/dev/null;' | CODE |
| HIGH | src/pyinfra/facts/util/__init__.py | 30 | "done || true" | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/__init__.py | 6 | CODE | |
| LOW | tests/test_connectors/conftest.py | 1 | CODE | |
| LOW | tests/test_connectors/test_ssh_util.py | 1 | CODE | |
| LOW | tests/test_cli/deploy/group_data/imports_leak.py | 5 | CODE | |
| LOW | tests/test_cli/deploy/group_data/imports_leak.py | 7 | CODE | |
| LOW | scripts/generate_llms_txt.py | 11 | CODE | |
| LOW | src/pyinfra_cli/util.py | 1 | CODE | |
| LOW | src/pyinfra_cli/prints.py | 1 | CODE | |
| LOW | src/pyinfra_cli/commands.py | 1 | CODE | |
| LOW | src/pyinfra/__init__.py | 14 | CODE | |
| LOW | src/pyinfra/__init__.py | 14 | CODE | |
| LOW | src/pyinfra/__init__.py | 14 | CODE | |
| LOW | src/pyinfra/__init__.py | 14 | CODE | |
| LOW | src/pyinfra/__init__.py | 17 | CODE | |
| LOW | src/pyinfra/connectors/ssh_util.py | 18 | CODE | |
| LOW | src/pyinfra/connectors/ssh_util.py | 19 | CODE | |
| LOW | src/pyinfra/connectors/fake.py | 11 | CODE | |
| LOW | src/pyinfra/connectors/util.py | 1 | CODE | |
| LOW | src/pyinfra/connectors/local.py | 23 | CODE | |
| LOW | src/pyinfra/connectors/chroot.py | 20 | CODE | |
| LOW | src/pyinfra/connectors/chroot.py | 21 | CODE | |
| LOW | src/pyinfra/connectors/chroot.py | 22 | CODE | |
| LOW | src/pyinfra/connectors/docker.py | 1 | CODE | |
| LOW | src/pyinfra/connectors/ssh.py | 1 | CODE | |
| LOW | src/pyinfra/connectors/base.py | 1 | CODE | |
| LOW | src/pyinfra/connectors/dockerssh.py | 19 | CODE | |
| LOW | src/pyinfra/connectors/dockerssh.py | 20 | CODE | |
| LOW | src/pyinfra/connectors/dockerssh.py | 21 | CODE | |
| LOW | src/pyinfra/connectors/sshuserclient/__init__.py | 1 | CODE | |
| LOW | src/pyinfra/connectors/scp/client.py | 1 | CODE | |
| LOW | src/pyinfra/connectors/scp/__init__.py | 1 | CODE | |
| LOW | src/pyinfra/operations/xbps.py | 5 | CODE | |
| LOW | src/pyinfra/operations/postgresql.py | 1 | CODE | |
| LOW | src/pyinfra/operations/pacman.py | 5 | CODE | |
| LOW | src/pyinfra/operations/files.py | 5 | CODE | |
| LOW | src/pyinfra/operations/git.py | 5 | CODE | |
| LOW | src/pyinfra/operations/server.py | 6 | CODE | |
| LOW | src/pyinfra/operations/zypper.py | 1 | CODE | |
| LOW | src/pyinfra/operations/selinux.py | 5 | CODE | |
| LOW | src/pyinfra/operations/systemd.py | 5 | CODE | |
| LOW | src/pyinfra/operations/cargo.py | 5 | CODE | |
| LOW | src/pyinfra/operations/crontab.py | 1 | CODE | |
| LOW | src/pyinfra/operations/apk.py | 5 | CODE | |
| LOW | src/pyinfra/operations/snap.py | 5 | CODE | |
| LOW | src/pyinfra/operations/docker.py | 7 | CODE | |
| LOW | src/pyinfra/operations/npm.py | 5 | CODE | |
| LOW | src/pyinfra/operations/choco.py | 5 | CODE | |
| LOW | src/pyinfra/operations/yum.py | 5 | CODE | |
| LOW | src/pyinfra/operations/sysvinit.py | 5 | CODE | |
| LOW | src/pyinfra/operations/dnf.py | 5 | CODE | |
| LOW | src/pyinfra/operations/vzctl.py | 5 | CODE | |
| LOW | src/pyinfra/operations/pkgin.py | 5 | CODE | |
| LOW | src/pyinfra/operations/puppet.py | 1 | CODE | |
| LOW | src/pyinfra/operations/runit.py | 5 | CODE | |
| LOW | src/pyinfra/operations/apt.py | 5 | CODE | |
| LOW | src/pyinfra/operations/flatpak.py | 5 | CODE | |
| LOW | src/pyinfra/operations/bsdinit.py | 5 | CODE | |
| LOW | src/pyinfra/operations/postgres.py | 17 | CODE | |
| LOW | src/pyinfra/operations/python.py | 5 | CODE | |
| LOW | src/pyinfra/operations/go.py | 5 | CODE | |
| 106 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | docs/api/connectors.md | 0 | execute a command. args: command (stringcommand): actual command to execute print_output (bool): whether to print comman | STRING |
| HIGH | src/pyinfra/connectors/local.py | 0 | execute a command. args: command (stringcommand): actual command to execute print_output (bool): whether to print comman | STRING |
| HIGH | src/pyinfra/connectors/base.py | 0 | execute a command. args: command (stringcommand): actual command to execute print_output (bool): whether to print comman | STRING |
| HIGH | docs/api/connectors.md | 0 | upload a local file or io object by copying it to a temporary directory and then writing it to the upload location. retu | STRING |
| HIGH | src/pyinfra/connectors/base.py | 0 | upload a local file or io object by copying it to a temporary directory and then writing it to the upload location. retu | STRING |
| HIGH | src/pyinfra/connectors/local.py | 0 | upload a local file or io object by copying it to a temporary directory and then writing it to the upload location. retu | STRING |
| HIGH | docs/api/connectors.md | 0 | download a local file by copying it to a temporary location and then writing it to our filename or io object. returns: b | STRING |
| HIGH | src/pyinfra/connectors/base.py | 0 | download a local file by copying it to a temporary location and then writing it to our filename or io object. returns: b | STRING |
| HIGH | src/pyinfra/connectors/local.py | 0 | download a local file by copying it to a temporary location and then writing it to our filename or io object. returns: b | STRING |
| HIGH | src/pyinfra/facts/xbps.py | 0 | returns a dict of installed brew casks: .. code:: python { "package_name": ["version"], } | STRING |
| HIGH | src/pyinfra/facts/pacman.py | 0 | returns a dict of installed brew casks: .. code:: python { "package_name": ["version"], } | STRING |
| HIGH | src/pyinfra/facts/deb.py | 0 | returns a dict of installed brew casks: .. code:: python { "package_name": ["version"], } | STRING |
| HIGH | src/pyinfra/facts/apk.py | 0 | returns a dict of installed brew casks: .. code:: python { "package_name": ["version"], } | STRING |
| HIGH | src/pyinfra/facts/pkgin.py | 0 | returns a dict of installed brew casks: .. code:: python { "package_name": ["version"], } | STRING |
| HIGH | src/pyinfra/facts/pkg.py | 0 | returns a dict of installed brew casks: .. code:: python { "package_name": ["version"], } | STRING |
| HIGH | src/pyinfra/facts/rpm.py | 0 | returns a dict of installed brew casks: .. code:: python { "package_name": ["version"], } | STRING |
| HIGH | src/pyinfra/facts/pip.py | 0 | returns a dict of installed brew casks: .. code:: python { "package_name": ["version"], } | STRING |
| HIGH | src/pyinfra/facts/pipx.py | 0 | returns a dict of installed brew casks: .. code:: python { "package_name": ["version"], } | STRING |
| HIGH | src/pyinfra/facts/brew.py | 0 | returns a dict of installed brew casks: .. code:: python { "package_name": ["version"], } | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/test_connectors/test_sshuserclient.py | 421 | CODE | |
| LOW | scripts/generate_facts_docs.py | 87 | CODE | |
| LOW | scripts/docs_utils.py | 29 | CODE | |
| LOW | scripts/lint_arguments_sync.py | 25 | CODE | |
| LOW | scripts/lint_arguments_sync.py | 40 | CODE | |
| LOW | scripts/lint_arguments_sync.py | 56 | CODE | |
| LOW | scripts/lint_arguments_sync.py | 116 | CODE | |
| LOW | scripts/generate_operations_docs.py | 92 | CODE | |
| LOW | src/pyinfra_cli/cli.py | 552 | CODE | |
| LOW | src/pyinfra_cli/exceptions.py | 42 | CODE | |
| LOW | src/pyinfra_cli/prints.py | 133 | CODE | |
| LOW | src/pyinfra_cli/prints.py | 362 | CODE | |
| LOW | src/pyinfra_cli/prints.py | 401 | CODE | |
| LOW | src/pyinfra_cli/inventory.py | 61 | CODE | |
| LOW | src/pyinfra_cli/inventory.py | 298 | CODE | |
| LOW | src/pyinfra/connectors/ssh_util.py | 63 | CODE | |
| LOW | src/pyinfra/connectors/terraform.py | 83 | CODE | |
| LOW | src/pyinfra/connectors/local.py | 107 | CODE | |
| LOW | src/pyinfra/connectors/local.py | 159 | CODE | |
| LOW | src/pyinfra/connectors/chroot.py | 109 | CODE | |
| LOW | src/pyinfra/connectors/chroot.py | 158 | CODE | |
| LOW | src/pyinfra/connectors/docker.py | 224 | CODE | |
| LOW | src/pyinfra/connectors/ssh.py | 218 | CODE | |
| LOW | src/pyinfra/connectors/sshuserclient/config.py | 48 | CODE | |
| LOW | src/pyinfra/connectors/sshuserclient/config.py | 64 | CODE | |
| LOW | src/pyinfra/connectors/sshuserclient/client.py | 276 | CODE | |
| LOW | src/pyinfra/connectors/scp/client.py | 132 | CODE | |
| LOW | src/pyinfra/operations/files.py | 308 | CODE | |
| LOW | src/pyinfra/operations/files.py | 957 | CODE | |
| LOW | src/pyinfra/operations/files.py | 1008 | CODE | |
| LOW | src/pyinfra/operations/files.py | 1922 | CODE | |
| LOW | src/pyinfra/operations/git.py | 92 | CODE | |
| LOW | src/pyinfra/operations/git.py | 235 | CODE | |
| LOW | src/pyinfra/operations/server.py | 320 | CODE | |
| LOW | src/pyinfra/operations/server.py | 470 | CODE | |
| LOW | src/pyinfra/operations/server.py | 684 | CODE | |
| LOW | src/pyinfra/operations/server.py | 762 | CODE | |
| LOW | src/pyinfra/operations/server.py | 830 | CODE | |
| LOW | src/pyinfra/operations/server.py | 1011 | CODE | |
| LOW | src/pyinfra/operations/crontab.py | 13 | CODE | |
| LOW | src/pyinfra/operations/snap.py | 13 | CODE | |
| LOW | src/pyinfra/operations/docker.py | 208 | CODE | |
| LOW | src/pyinfra/operations/docker.py | 605 | CODE | |
| LOW | src/pyinfra/operations/zfs.py | 11 | CODE | |
| LOW | src/pyinfra/operations/sysvinit.py | 18 | CODE | |
| LOW | src/pyinfra/operations/gpg.py | 94 | CODE | |
| LOW | src/pyinfra/operations/gpg.py | 142 | CODE | |
| LOW | src/pyinfra/operations/gpg.py | 231 | CODE | |
| LOW | src/pyinfra/operations/apt.py | 92 | CODE | |
| LOW | src/pyinfra/operations/go.py | 34 | CODE | |
| LOW | src/pyinfra/operations/pip.py | 18 | CODE | |
| LOW | src/pyinfra/operations/mysql.py | 58 | CODE | |
| LOW | src/pyinfra/operations/util/files.py | 264 | CODE | |
| LOW | src/pyinfra/operations/util/docker.py | 49 | CODE | |
| LOW | src/pyinfra/operations/util/packaging.py | 176 | CODE | |
| LOW | src/pyinfra/operations/freebsd/service.py | 21 | CODE | |
| LOW | src/pyinfra/operations/freebsd/sysrc.py | 20 | CODE | |
| LOW | src/pyinfra/api/facts.py | 256 | CODE | |
| LOW | src/pyinfra/api/config.py | 86 | CODE | |
| LOW | src/pyinfra/api/operations.py | 61 | CODE | |
| 18 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/test_connectors/test_sshuserclient.py | 441 | # Check if AskPolicy respects not importing and properly raises SSHException | COMMENT |
| LOW | tests/test_connectors/test_sshuserclient.py | 448 | # Check if AskPolicy properly appends to hostfile | COMMENT |
| LOW | tests/facts/server.RebootRequired/linux_no_reboot.json | 2 | "command": "\n# Get OS type\nOS_TYPE=$(uname -s)\nif [ \"$OS_TYPE\" = \"Linux\" ]; then\n # Check if it's Alpine | CODE |
| LOW | …facts/server.RebootRequired/linux_reboot_required.json | 2 | "command": "\n# Get OS type\nOS_TYPE=$(uname -s)\nif [ \"$OS_TYPE\" = \"Linux\" ]; then\n # Check if it's Alpine | CODE |
| LOW | …cts/server.RebootRequired/freebsd_reboot_required.json | 2 | "command": "\n# Get OS type\nOS_TYPE=$(uname -s)\nif [ \"$OS_TYPE\" = \"Linux\" ]; then\n # Check if it's Alpine | CODE |
| LOW | …acts/server.RebootRequired/alpine_reboot_required.json | 2 | "command": "\n# Get OS type\nOS_TYPE=$(uname -s)\nif [ \"$OS_TYPE\" = \"Linux\" ]; then\n # Check if it's Alpine | CODE |
| LOW | scripts/lint_arguments_sync.py | 76 | # Check if this arg has a default | COMMENT |
| LOW | scripts/lint_arguments_sync.py | 160 | # Check if it's just an Optional wrapper difference | COMMENT |
| LOW | src/pyinfra_cli/commands.py | 20 | # Check if we're JSON (in which case we expect a list of two items: | COMMENT |
| LOW | src/pyinfra_cli/inventory.py | 105 | # Read the files locals into a dict | COMMENT |
| LOW | src/pyinfra/operations/files.py | 706 | # Check if this directory is actually a symlink | COMMENT |
| LOW | src/pyinfra/operations/files.py | 731 | # Check if this is a symlink | COMMENT |
| LOW | src/pyinfra/operations/gpg.py | 147 | # Check if the destination keyring exists and contains the target keys | COMMENT |
| LOW⚡ | src/pyinfra/operations/gpg.py | 326 | # Check if key already exists (for idempotence) | COMMENT |
| LOW⚡ | src/pyinfra/operations/gpg.py | 334 | # Check if our destination keyring exists in the fact | COMMENT |
| LOW⚡ | src/pyinfra/operations/gpg.py | 341 | # Check if all requested keys already exist | COMMENT |
| LOW | src/pyinfra/operations/gpg.py | 443 | # Check if it's an ASCII armored key and handle accordingly | COMMENT |
| LOW | src/pyinfra/operations/postgres.py | 176 | # Check if any attributes need updating | COMMENT |
| LOW | src/pyinfra/api/operation.py | 305 | # Check if we're actually running the operation on this host | COMMENT |
| LOW | src/pyinfra/api/operations.py | 152 | # Check if we should retry | COMMENT |
| LOW | src/pyinfra/facts/files.py | 138 | # Check if year_or_time is a year (4 digits) or time (HH:MM) | COMMENT |
| LOW | src/pyinfra/facts/server.py | 1277 | # Check if it's Alpine Linux | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/pyinfra/connectors/util.py | 386 | CODE | |
| LOW | src/pyinfra/operations/files.py | 79 | CODE | |
| LOW | src/pyinfra/operations/files.py | 308 | CODE | |
| LOW | src/pyinfra/operations/files.py | 616 | CODE | |
| LOW | src/pyinfra/operations/files.py | 1008 | CODE | |
| LOW | src/pyinfra/operations/files.py | 1557 | CODE | |
| LOW | src/pyinfra/operations/files.py | 1664 | CODE | |
| LOW | src/pyinfra/operations/files.py | 1766 | CODE | |
| LOW | src/pyinfra/operations/files.py | 1922 | CODE | |
| LOW | src/pyinfra/operations/git.py | 92 | CODE | |
| LOW | src/pyinfra/operations/git.py | 235 | CODE | |
| LOW | src/pyinfra/operations/server.py | 1011 | CODE | |
| LOW | src/pyinfra/operations/zypper.py | 113 | CODE | |
| LOW | src/pyinfra/operations/systemd.py | 37 | CODE | |
| LOW | src/pyinfra/operations/crontab.py | 13 | CODE | |
| LOW | src/pyinfra/operations/docker.py | 26 | CODE | |
| LOW | src/pyinfra/operations/docker.py | 286 | CODE | |
| LOW | src/pyinfra/operations/docker.py | 476 | CODE | |
| LOW | src/pyinfra/operations/docker.py | 812 | CODE | |
| LOW | src/pyinfra/operations/yum.py | 139 | CODE | |
| LOW | src/pyinfra/operations/dnf.py | 140 | CODE | |
| LOW | src/pyinfra/operations/gpg.py | 231 | CODE | |
| LOW | src/pyinfra/operations/runit.py | 18 | CODE | |
| LOW | src/pyinfra/operations/apt.py | 581 | CODE | |
| LOW | src/pyinfra/operations/postgres.py | 62 | CODE | |
| LOW | src/pyinfra/operations/postgres.py | 224 | CODE | |
| LOW | src/pyinfra/operations/uv.py | 234 | CODE | |
| LOW | src/pyinfra/operations/iptables.py | 62 | CODE | |
| LOW | src/pyinfra/operations/pip.py | 122 | CODE | |
| LOW | src/pyinfra/operations/mysql.py | 58 | CODE | |
| LOW | src/pyinfra/operations/mysql.py | 292 | CODE | |
| LOW | src/pyinfra/operations/mysql.py | 395 | CODE | |
| LOW | src/pyinfra/operations/freebsd/freebsd_update.py | 12 | CODE | |
| LOW | src/pyinfra/api/arguments_typed.py | 27 | CODE | |
| LOW | src/pyinfra/facts/files.py | 484 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM⚡ | tests/test_api/test_api_operations.py | 915 | # Create a counter to track retry_until calls | COMMENT |
| MEDIUM⚡ | tests/test_api/test_api_operations.py | 918 | # Create a retry_until function that returns True (retry) for first two calls | COMMENT |
| MEDIUM | tests/test_api/test_api_operations.py | 1018 | # Create a retry_until function that raises an exception | COMMENT |
| MEDIUM | src/pyinfra/operations/server.py | 462 | # Create a whole new hostname file | STRING |
| MEDIUM | src/pyinfra/operations/server.py | 1118 | # Create the user w/home/shell | STRING |
| MEDIUM | src/pyinfra/operations/zypper.py | 52 | # Create the repository file from baseurl/etc | STRING |
| MEDIUM | src/pyinfra/operations/docker.py | 438 | # Create a Docker volume | STRING |
| MEDIUM | src/pyinfra/operations/yum.py | 79 | # Create the repository file from baseurl/etc | STRING |
| MEDIUM | src/pyinfra/operations/dnf.py | 80 | # Create the repository file from baseurl/etc | STRING |
| MEDIUM⚡ | src/pyinfra/operations/mysql.py | 111 | # Create a user with resource limits | STRING |
| MEDIUM⚡ | src/pyinfra/operations/mysql.py | 119 | # Create a user that requires SSL for connections | STRING |
| MEDIUM⚡ | src/pyinfra/operations/mysql.py | 127 | # Create a user that requires a specific certificate | STRING |
| MEDIUM | src/pyinfra/api/arguments.py | 272 | # Create a dictionary for retry arguments | COMMENT |
| MEDIUM | src/pyinfra/api/inventory.py | 58 | # Create the actual host instances and groups | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | scripts/generate_changelog.py | 135 | print("Error: could not determine previous tag", file=sys.stderr) | CODE |
| LOW | scripts/generate_llms_txt.py | 130 | except Exception as exc: # broad: importing plugin code can trigger extras, env checks | CODE |
| LOW | src/pyinfra_cli/log.py | 16 | except Exception: | CODE |
| MEDIUM | src/pyinfra_cli/log.py | 12 | def emit(self, record): | CODE |
| LOW | src/pyinfra_cli/util.py | 70 | except Exception as e: | CODE |
| LOW | src/pyinfra_cli/util.py | 190 | except Exception as e: | CODE |
| LOW | src/pyinfra_cli/util.py | 226 | except Exception as e: | CODE |
| MEDIUM | src/pyinfra_cli/util.py | 218 | def load_file(local_host): | CODE |
| LOW | src/pyinfra_cli/cli.py | 296 | except Exception as e: | CODE |
| LOW | src/pyinfra_cli/inventory.py | 230 | except Exception as e: | CODE |
| LOW | src/pyinfra/version.py | 8 | except Exception: | CODE |
| LOW | src/pyinfra/connectors/util.py | 267 | except Exception as e: | STRING |
| LOW | src/pyinfra/connectors/ssh.py | 322 | except Exception: | STRING |
| LOW | src/pyinfra/connectors/ssh.py | 341 | except Exception: | STRING |
| LOW | src/pyinfra/connectors/sshuserclient/config.py | 37 | except Exception as e: | CODE |
| LOW | src/pyinfra/connectors/sshuserclient/client.py | 181 | except Exception as e: | CODE |
| LOW | src/pyinfra/api/command.py | 255 | except Exception as e: | CODE |
| LOW | src/pyinfra/api/operations.py | 113 | except Exception as e: | CODE |
| LOW | src/pyinfra/api/operations.py | 174 | except Exception as e: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | tests/test_connectors/test_ssh.py | 253 | fake_key = mock.MagicMock() | CODE |
| LOW⚡ | tests/test_connectors/test_ssh.py | 254 | fake_key_open.return_value = fake_key | CODE |
| LOW⚡ | tests/test_connectors/test_ssh.py | 261 | fake_key.load_certificate.assert_called_with("testkey-cert.pub") | CODE |
| LOW⚡ | tests/test_connectors/test_ssh.py | 268 | pkey=fake_key, | CODE |
| LOW⚡ | tests/test_connectors/test_ssh.py | 394 | fake_key = mock.MagicMock() | CODE |
| LOW⚡ | tests/test_connectors/test_ssh.py | 399 | return fake_key | CODE |
| LOW⚡ | tests/test_connectors/test_ssh.py | 408 | fake_key.load_certificate.assert_called_with("testkey-cert.pub") | CODE |
| LOW⚡ | tests/test_connectors/test_ssh.py | 452 | fake_key = mock.MagicMock() | CODE |
| LOW⚡ | tests/test_connectors/test_ssh.py | 453 | fake_key_open.return_value = fake_key | CODE |
| LOW⚡ | tests/test_connectors/test_ssh.py | 500 | fake_key = mock.MagicMock() | CODE |
| LOW⚡ | tests/test_connectors/test_ssh.py | 501 | fake_key_open.return_value = fake_key | CODE |
| LOW | tests/test_connectors/test_ssh.py | 423 | fake_key = mock.MagicMock() | CODE |
| LOW | tests/test_connectors/test_ssh.py | 428 | return fake_key | CODE |
| LOW | tests/test_connectors/test_ssh.py | 439 | fake_key.load_certificate.assert_called_with("testkey-cert.pub") | CODE |
| LOW | tests/operations/snap.package/install_packages.json | 9 | "publisher": "Acme Corp", | CODE |
| LOW | …/operations/snap.package/install_refresh_packages.json | 17 | "publisher": "Acme Corp", | CODE |
| LOW | docs/inventory-data.md | 98 | See [Dynamic Inventories & Data](examples/dynamic_inventories_data.md) for a worked example, including building a fake-d | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/pyinfra/api/facts.py | 128 | def process_data(self, data): | CODE |
| LOW | src/pyinfra/facts/server.py | 1054 | def process_data(self, data) -> str: | STRING |
| LOW | src/pyinfra/facts/server.py | 1141 | def process_data(self, data) -> bool: | STRING |
| LOW | src/pyinfra/facts/docker.py | 193 | def process_data(self, data): | STRING |
| LOW | src/pyinfra/facts/docker.py | 214 | def process_data(self, data): | STRING |
| LOW | src/pyinfra/facts/docker.py | 229 | def process_data(self, data): | STRING |
| LOW | src/pyinfra/facts/docker.py | 241 | def process_data(self, data): | STRING |
| LOW | src/pyinfra/facts/docker.py | 256 | def process_data(self, data): | STRING |
| LOW | src/pyinfra/facts/docker.py | 271 | def process_data(self, data): | STRING |
| LOW | src/pyinfra/facts/docker.py | 290 | def process_data(self, data): | STRING |
| LOW | src/pyinfra/facts/docker.py | 304 | def process_data(self, data): | STRING |
| LOW | src/pyinfra/facts/docker.py | 316 | def process_data(self, data): | STRING |
| LOW⚡ | src/pyinfra/facts/zfs.py | 64 | def process_data(self, data): | CODE |
| LOW⚡ | src/pyinfra/facts/zfs.py | 72 | def process_data(self, data): | CODE |
| LOW⚡ | src/pyinfra/facts/zfs.py | 80 | def process_data(self, data): | CODE |
| LOW | src/pyinfra/facts/hardware.py | 594 | def process_data(self, data): | CODE |
| LOW | src/pyinfra/facts/hardware.py | 656 | def process_data(self, data): | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/pyinfra_cli/virtualenv.py | 40 | # but others can symlink *to* the venv Python, so we can't just use sys.executable. | COMMENT |
| LOW | src/pyinfra_cli/inventory.py | 355 | # we're not ready to make an Inventory. So here we just create a fake one, and | COMMENT |
| LOW | src/pyinfra/progress.py | 68 | # If there's no current state context we're not in CLI mode, so just return a noop | COMMENT |
| LOW | src/pyinfra/operations/files.py | 1374 | # To pass variables to the template file, just add them to the operation call. | STRING |
| LOW | src/pyinfra/operations/bsdinit.py | 52 | # BSD init is simple, just add/remove <service>_enabled="YES" | COMMENT |
| MEDIUM | src/pyinfra/api/config.py | 160 | # were required. To facilitate checking extras we have to pass the extra | COMMENT |
| LOW | src/pyinfra/api/inventory.py | 105 | # Execution connector? Simple, just set it for their host | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | src/pyinfra/operations/files.py | 1313 | Generate a template using jinja2 and write it to the remote system. + src: template filename or IO-like object | STRING |
| HIGH | src/pyinfra/operations/util/docker.py | 50 | Parse a registry string into host and port components. Args: registry: String like "registry.io:5000" | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/pyinfra_cli/inventory.py | 181 | # (Un)fortunately the CLI is pretty flexible for inventory inputs; we support inventory files, a | COMMENT |
| LOW | src/pyinfra/api/config.py | 21 | # % of hosts which have to fail for all operations to stop | COMMENT |
| LOW | src/pyinfra/api/config.py | 141 | # This would raise a DistributionNotFound error from pkg_resources.require() | COMMENT |
| LOW | src/pyinfra/api/arguments_typed.py | 61 | # | COMMENT |
| LOW | src/pyinfra/facts/systemd.py | 1 | from __future__ import annotations | COMMENT |
| LOW | src/pyinfra/facts/snap.py | 81 | # Discard header output line from snap list command | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | src/pyinfra_cli/cli.py | 749 | def _set_fail_prompts(state: State, config: Config) -> None: | CODE |
| LOW | src/pyinfra/api/output.py | 43 | def set_formatter(func: Callable[..., str]) -> None: | CODE |
| LOW | src/pyinfra/api/output.py | 49 | def set_echo(func: Callable[..., None]) -> None: | CODE |
| LOW | src/pyinfra/api/state.py | 283 | def set_stage(self, stage: StateStage) -> None: | CODE |