Warning: Permanently added '13.220.140.237' (ED25519) to the list of known hosts. Running (timeout=18000): unbuffer mock --spec /var/lib/copr-rpmbuild/workspace/workdir-q5p0gqla/python-executing/python-executing.spec --sources /var/lib/copr-rpmbuild/workspace/workdir-q5p0gqla/python-executing --resultdir /var/lib/copr-rpmbuild/results --uniqueext 1747249355.591554 -r /var/lib/copr-rpmbuild/results/configs/child.cfg INFO: mock.py version 6.1 starting (python version = 3.13.0, NVR = mock-6.1-1.fc41), args: /usr/libexec/mock/mock --spec /var/lib/copr-rpmbuild/workspace/workdir-q5p0gqla/python-executing/python-executing.spec --sources /var/lib/copr-rpmbuild/workspace/workdir-q5p0gqla/python-executing --resultdir /var/lib/copr-rpmbuild/results --uniqueext 1747249355.591554 -r /var/lib/copr-rpmbuild/results/configs/child.cfg Start: init plugins INFO: tmpfs initialized INFO: selinux enabled INFO: chroot_scan: initialized INFO: compress_logs: initialized Finish: init plugins INFO: Signal handler active Start: run INFO: Start(/var/lib/copr-rpmbuild/workspace/workdir-q5p0gqla/python-executing/python-executing.spec) Config(fedora-rawhide-x86_64) Start: clean chroot Finish: clean chroot Mock Version: 6.1 INFO: Mock Version: 6.1 Start: chroot init INFO: mounting tmpfs at /var/lib/mock/fedora-rawhide-x86_64-1747249355.591554/root. INFO: calling preinit hooks INFO: enabled root cache INFO: enabled package manager cache Start: cleaning package manager metadata Finish: cleaning package manager metadata INFO: enabled HW Info plugin INFO: Package manager dnf5 detected and used (fallback) INFO: Buildroot is handled by package management from host and used with --installroot: rpm-4.20.1-1.fc41.x86_64 rpm-sequoia-1.7.0-2.fc41.x86_64 python3-dnf-4.23.0-1.fc41.noarch python3-dnf-plugins-core-4.10.1-1.fc41.noarch dnf5-5.2.13.1-1.fc41.x86_64 dnf5-plugins-5.2.13.1-1.fc41.x86_64 Start: installing minimal buildroot with dnf5 Updating and loading repositories: fedora 100% | 381.2 KiB/s | 24.8 KiB | 00m00s Copr repository 100% | 56.9 KiB/s | 1.5 KiB | 00m00s Additional repo http_kojipkgs_fedorapr 100% | 182.3 KiB/s | 3.8 KiB | 00m00s Repositories loaded. Package Arch Version Repository Size Installing group/module packages: bash x86_64 5.2.37-3.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 8.2 MiB bzip2 x86_64 1.0.8-20.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 99.3 KiB coreutils x86_64 9.7-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 5.4 MiB cpio x86_64 2.15-2.fc41 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 1.1 MiB diffutils x86_64 3.12-2.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 1.6 MiB fedora-release-common noarch 43-0.15 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 20.4 KiB findutils x86_64 1:4.10.0-5.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 1.9 MiB gawk x86_64 5.3.2-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 1.8 MiB glibc-minimal-langpack x86_64 2.41.9000-13.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 0.0 B grep x86_64 3.12-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 1.0 MiB gzip x86_64 1.13-3.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 392.9 KiB info x86_64 7.2-3.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 357.9 KiB patch x86_64 2.8-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 226.8 KiB redhat-rpm-config noarch 343-5.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 181.5 KiB rpm-build x86_64 5.99.90-5.fc43 copr_base 281.7 KiB sed x86_64 4.9-4.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 857.3 KiB shadow-utils x86_64 2:4.17.4-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 4.0 MiB tar x86_64 2:1.35-5.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 3.0 MiB unzip x86_64 6.0-66.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 390.3 KiB util-linux x86_64 2.41-2.fc43 copr_base 3.5 MiB which x86_64 2.23-1.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 83.4 KiB xz x86_64 1:5.8.1-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 1.3 MiB Installing dependencies: add-determinism x86_64 0.6.0-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 2.5 MiB alternatives x86_64 1.33-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 62.2 KiB ansible-srpm-macros noarch 1-17.1.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 35.7 KiB audit-libs x86_64 4.0.3-2.fc43 copr_base 347.1 KiB binutils x86_64 2.44-3.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 25.9 MiB build-reproducibility-srpm-macros noarch 0.6.0-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 735.0 B bzip2-libs x86_64 1.0.8-20.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 84.6 KiB ca-certificates noarch 2024.2.69_v8.0.401-5.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 2.6 MiB coreutils-common x86_64 9.7-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 11.3 MiB crypto-policies noarch 20250402-2.git86c0178.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 141.5 KiB curl x86_64 8.14.0~rc1-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 473.2 KiB cyrus-sasl-lib x86_64 2.1.28-30.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 2.3 MiB debugedit x86_64 5.1-6.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 192.7 KiB dwz x86_64 0.15-9.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 291.0 KiB ed x86_64 1.21-2.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 146.5 KiB efi-srpm-macros noarch 6-3.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 40.1 KiB elfutils x86_64 0.193-2.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 2.9 MiB elfutils-debuginfod-client x86_64 0.193-2.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 83.9 KiB elfutils-default-yama-scope noarch 0.193-2.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 1.8 KiB elfutils-libelf x86_64 0.193-2.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 1.2 MiB elfutils-libs x86_64 0.193-2.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 683.4 KiB fedora-gpg-keys noarch 43-0.2 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 129.0 KiB fedora-release noarch 43-0.15 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 0.0 B fedora-release-identity-basic noarch 43-0.15 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 664.0 B fedora-repos noarch 43-0.2 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 4.9 KiB fedora-repos-rawhide noarch 43-0.2 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 2.2 KiB file x86_64 5.46-1.fc43 copr_base 100.2 KiB file-libs x86_64 5.46-1.fc43 copr_base 11.9 MiB filesystem x86_64 3.18-44.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 112.0 B filesystem-srpm-macros noarch 3.18-44.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 38.2 KiB fonts-srpm-macros noarch 1:2.0.5-21.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 55.8 KiB forge-srpm-macros noarch 0.4.0-2.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 38.9 KiB fpc-srpm-macros noarch 1.3-14.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 144.0 B gdb-minimal x86_64 16.3-1.fc43 copr_base 13.2 MiB gdbm-libs x86_64 1:1.23-9.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 129.9 KiB ghc-srpm-macros noarch 1.9.2-2.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 779.0 B glibc x86_64 2.41.9000-13.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 6.7 MiB glibc-common x86_64 2.41.9000-13.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 1.0 MiB glibc-gconv-extra x86_64 2.41.9000-13.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 7.2 MiB gmp x86_64 1:6.3.0-3.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 819.2 KiB gnat-srpm-macros noarch 6-7.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 1.0 KiB gnupg2 x86_64 2.4.7-3.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 9.8 MiB gnutls x86_64 3.8.9-5.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 3.6 MiB go-srpm-macros noarch 3.6.0-7.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 60.8 KiB gpgverify noarch 2.1-3.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 8.7 KiB ima-evm-utils-libs x86_64 1.6.2-5.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 60.7 KiB jansson x86_64 2.14-2.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 93.1 KiB json-c x86_64 0.18-2.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 86.7 KiB kernel-srpm-macros noarch 1.0-25.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 1.9 KiB keyutils-libs x86_64 1.6.3-5.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 58.3 KiB krb5-libs x86_64 1.21.3-5.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 2.3 MiB libacl x86_64 2.3.2-3.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 38.3 KiB libarchive x86_64 3.7.7-4.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 930.6 KiB libassuan x86_64 2.5.7-3.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 167.8 KiB libattr x86_64 2.5.2-5.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 27.1 KiB libblkid x86_64 2.41-2.fc43 copr_base 262.4 KiB libbrotli x86_64 1.1.0-6.fc43 copr_base 833.3 KiB libcap x86_64 2.76-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 209.2 KiB libcap-ng x86_64 0.8.5-4.fc43 copr_base 68.9 KiB libcom_err x86_64 1.47.2-3.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 67.1 KiB libcurl x86_64 8.14.0~rc1-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 891.0 KiB libeconf x86_64 0.7.6-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 64.6 KiB libevent x86_64 2.1.12-15.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 903.1 KiB libfdisk x86_64 2.41-2.fc43 copr_base 376.4 KiB libffi x86_64 3.4.8-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 83.0 KiB libfsverity x86_64 1.6-2.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 32.5 KiB libgcc x86_64 15.1.1-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 266.6 KiB libgcrypt x86_64 1.11.1-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 1.6 MiB libgomp x86_64 15.1.1-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 538.5 KiB libgpg-error x86_64 1.55-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 915.3 KiB libidn2 x86_64 2.3.8-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 552.5 KiB libksba x86_64 1.6.7-3.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 402.5 KiB liblastlog2 x86_64 2.41-2.fc43 copr_base 33.9 KiB libmount x86_64 2.41-2.fc43 copr_base 372.7 KiB libnghttp2 x86_64 1.65.0-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 162.2 KiB libpkgconf x86_64 2.3.0-2.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 78.1 KiB libpsl x86_64 0.21.5-5.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 76.4 KiB libselinux x86_64 3.8-1.fc43 copr_base 193.1 KiB libsemanage x86_64 3.8-1.fc43 copr_base 304.4 KiB libsepol x86_64 3.8-1.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 826.0 KiB libsmartcols x86_64 2.41-2.fc43 copr_base 180.5 KiB libssh x86_64 0.11.1-4.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 565.5 KiB libssh-config noarch 0.11.1-4.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 277.0 B libstdc++ x86_64 15.1.1-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 2.8 MiB libtasn1 x86_64 4.20.0-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 176.3 KiB libtool-ltdl x86_64 2.5.4-4.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 70.1 KiB libunistring x86_64 1.1-9.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 1.7 MiB libusb1 x86_64 1.0.28-2.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 171.0 KiB libuuid x86_64 2.41-2.fc43 copr_base 37.3 KiB libverto x86_64 0.3.2-10.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 25.4 KiB libxcrypt x86_64 4.4.38-7.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 284.5 KiB libxml2 x86_64 2.12.10-1.fc43 copr_base 1.7 MiB libzstd x86_64 1.5.7-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 807.8 KiB lua-libs x86_64 5.4.7-3.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 276.9 KiB lua-srpm-macros noarch 1-15.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 1.3 KiB lz4-libs x86_64 1.10.0-2.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 157.4 KiB mpfr x86_64 4.2.2-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 828.8 KiB ncurses-base noarch 6.5-5.20250125.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 326.8 KiB ncurses-libs x86_64 6.5-5.20250125.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 946.3 KiB nettle x86_64 3.10.1-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 790.5 KiB npth x86_64 1.8-2.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 49.6 KiB ocaml-srpm-macros noarch 10-4.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 1.9 KiB openblas-srpm-macros noarch 2-19.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 112.0 B openldap x86_64 2.6.9-5.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 655.1 KiB openssl-libs x86_64 1:3.5.0-3.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 8.9 MiB p11-kit x86_64 0.25.5-5.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 2.2 MiB p11-kit-trust x86_64 0.25.5-5.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 395.5 KiB package-notes-srpm-macros noarch 0.5-13.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 1.6 KiB pam-libs x86_64 1.7.0-4.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 126.7 KiB pcre2 x86_64 10.45-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 697.7 KiB pcre2-syntax noarch 10.45-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 273.9 KiB perl-srpm-macros noarch 1-57.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 861.0 B pkgconf x86_64 2.3.0-2.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 88.5 KiB pkgconf-m4 noarch 2.3.0-2.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 14.4 KiB pkgconf-pkg-config x86_64 2.3.0-2.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 989.0 B popt x86_64 1.19-8.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 132.8 KiB publicsuffix-list-dafsa noarch 20250116-1.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 68.5 KiB pyproject-srpm-macros noarch 1.18.1-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 1.9 KiB python-srpm-macros noarch 3.14-5.fc43 copr_base 51.7 KiB qt5-srpm-macros noarch 5.15.16-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 500.0 B qt6-srpm-macros noarch 6.9.0-2.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 464.0 B readline x86_64 8.2-13.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 485.0 KiB rpm x86_64 5.99.90-5.fc43 copr_base 3.1 MiB rpm-build-libs x86_64 5.99.90-5.fc43 copr_base 264.4 KiB rpm-libs x86_64 5.99.90-5.fc43 copr_base 929.8 KiB rpm-sequoia x86_64 1.8.0-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 2.5 MiB rpm-sign-libs x86_64 5.99.90-5.fc43 copr_base 39.7 KiB rust-srpm-macros noarch 26.3-4.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 4.8 KiB setup noarch 2.15.0-24.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 724.7 KiB sqlite-libs x86_64 3.49.1-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 1.5 MiB systemd-libs x86_64 257.5-5.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 2.2 MiB systemd-standalone-sysusers x86_64 257.5-5.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 277.3 KiB tpm2-tss x86_64 4.1.3-7.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 1.6 MiB tree-sitter-srpm-macros noarch 0.2.4-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 7.5 KiB util-linux-core x86_64 2.41-2.fc43 copr_base 1.4 MiB xxhash-libs x86_64 0.8.3-2.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 90.2 KiB xz-libs x86_64 1:5.8.1-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 217.8 KiB zig-srpm-macros noarch 1-4.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 1.1 KiB zip x86_64 3.0-43.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 698.5 KiB zlib-ng-compat x86_64 2.2.4-2.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 137.6 KiB zstd x86_64 1.5.7-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 1.7 MiB Installing groups: Buildsystem building group Transaction Summary: Installing: 163 packages Total size of inbound packages is 58 MiB. Need to download 0 B. After this operation, 198 MiB extra will be used (install 198 MiB, remove 0 B). [ 1/163] tar-2:1.35-5.fc42.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 2/163] bzip2-0:1.0.8-20.fc42.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 3/163] redhat-rpm-config-0:343-5.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 4/163] rpm-build-0:5.99.90-5.fc43.x8 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 5/163] unzip-0:6.0-66.fc42.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 6/163] cpio-0:2.15-2.fc41.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 7/163] which-0:2.23-1.fc42.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 8/163] bash-0:5.2.37-3.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 9/163] coreutils-0:9.7-1.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 10/163] grep-0:3.12-1.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 11/163] patch-0:2.8-1.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 12/163] sed-0:4.9-4.fc42.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 13/163] shadow-utils-2:4.17.4-1.fc43. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 14/163] util-linux-0:2.41-2.fc43.x86_ 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 15/163] diffutils-0:3.12-2.fc43.x86_6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 16/163] fedora-release-common-0:43-0. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 17/163] findutils-1:4.10.0-5.fc42.x86 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 18/163] gawk-0:5.3.2-1.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 19/163] glibc-minimal-langpack-0:2.41 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 20/163] gzip-0:1.13-3.fc42.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 21/163] info-0:7.2-3.fc42.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 22/163] xz-1:5.8.1-1.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 23/163] libblkid-0:2.41-2.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 24/163] libfdisk-0:2.41-2.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 25/163] liblastlog2-0:2.41-2.fc43.x86 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 26/163] libmount-0:2.41-2.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 27/163] libsmartcols-0:2.41-2.fc43.x8 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 28/163] libuuid-0:2.41-2.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 29/163] util-linux-core-0:2.41-2.fc43 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 30/163] glibc-0:2.41.9000-13.fc43.x86 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 31/163] glibc-common-0:2.41.9000-13.f 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 32/163] glibc-gconv-extra-0:2.41.9000 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 33/163] xz-libs-1:5.8.1-1.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 34/163] bzip2-libs-0:1.0.8-20.fc42.x8 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 35/163] libacl-0:2.3.2-3.fc42.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 36/163] libselinux-0:3.8-1.fc43.x86_6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 37/163] audit-libs-0:4.0.3-2.fc43.x86 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 38/163] filesystem-0:3.18-44.fc43.x86 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 39/163] libeconf-0:0.7.6-1.fc43.x86_6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 40/163] libsemanage-0:3.8-1.fc43.x86_ 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 41/163] libxcrypt-0:4.4.38-7.fc43.x86 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 42/163] pam-libs-0:1.7.0-4.fc42.x86_6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 43/163] setup-0:2.15.0-24.fc43.noarch 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 44/163] ansible-srpm-macros-0:1-17.1. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 45/163] build-reproducibility-srpm-ma 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 46/163] dwz-0:0.15-9.fc42.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 47/163] efi-srpm-macros-0:6-3.fc43.no 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 48/163] file-0:5.46-1.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 49/163] file-libs-0:5.46-1.fc43.x86_6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 50/163] filesystem-srpm-macros-0:3.18 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 51/163] fonts-srpm-macros-1:2.0.5-21. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 52/163] forge-srpm-macros-0:0.4.0-2.f 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 53/163] fpc-srpm-macros-0:1.3-14.fc42 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 54/163] ghc-srpm-macros-0:1.9.2-2.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 55/163] gnat-srpm-macros-0:6-7.fc42.n 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 56/163] go-srpm-macros-0:3.6.0-7.fc43 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 57/163] kernel-srpm-macros-0:1.0-25.f 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 58/163] lua-srpm-macros-0:1-15.fc42.n 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 59/163] ocaml-srpm-macros-0:10-4.fc42 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 60/163] openblas-srpm-macros-0:2-19.f 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 61/163] package-notes-srpm-macros-0:0 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 62/163] perl-srpm-macros-0:1-57.fc42. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 63/163] pyproject-srpm-macros-0:1.18. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 64/163] python-srpm-macros-0:3.14-5.f 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 65/163] qt5-srpm-macros-0:5.15.16-1.f 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 66/163] qt6-srpm-macros-0:6.9.0-2.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 67/163] rpm-0:5.99.90-5.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 68/163] rust-srpm-macros-0:26.3-4.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 69/163] tree-sitter-srpm-macros-0:0.2 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 70/163] zig-srpm-macros-0:1-4.fc42.no 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 71/163] zip-0:3.0-43.fc42.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 72/163] ed-0:1.21-2.fc42.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 73/163] libattr-0:2.5.2-5.fc42.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 74/163] ncurses-libs-0:6.5-5.20250125 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 75/163] pcre2-0:10.45-1.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 76/163] libgcc-0:15.1.1-1.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 77/163] gmp-1:6.3.0-3.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 78/163] mpfr-0:4.2.2-1.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 79/163] readline-0:8.2-13.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 80/163] fedora-repos-0:43-0.2.noarch 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 81/163] elfutils-libelf-0:0.193-2.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 82/163] coreutils-common-0:9.7-1.fc43 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 83/163] libcap-0:2.76-1.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 84/163] openssl-libs-1:3.5.0-3.fc43.x 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 85/163] systemd-libs-0:257.5-5.fc43.x 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 86/163] add-determinism-0:0.6.0-1.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 87/163] zlib-ng-compat-0:2.2.4-2.fc43 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 88/163] libcap-ng-0:0.8.5-4.fc43.x86_ 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 89/163] binutils-0:2.44-3.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 90/163] debugedit-0:5.1-6.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 91/163] elfutils-0:0.193-2.fc43.x86_6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 92/163] libarchive-0:3.7.7-4.fc43.x86 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 93/163] libstdc++-0:15.1.1-1.fc43.x86 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 94/163] pkgconf-pkg-config-0:2.3.0-2. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 95/163] popt-0:1.19-8.fc42.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 96/163] rpm-build-libs-0:5.99.90-5.fc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 97/163] rpm-libs-0:5.99.90-5.fc43.x86 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 98/163] zstd-0:1.5.7-1.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 99/163] curl-0:8.14.0~rc1-1.fc43.x86_ 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [100/163] libsepol-0:3.8-1.fc42.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [101/163] sqlite-libs-0:3.49.1-1.fc43.x 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [102/163] lz4-libs-0:1.10.0-2.fc42.x86_ 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [103/163] pkgconf-0:2.3.0-2.fc42.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [104/163] pkgconf-m4-0:2.3.0-2.fc42.noa 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [105/163] libpkgconf-0:2.3.0-2.fc42.x86 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [106/163] pcre2-syntax-0:10.45-1.fc43.n 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [107/163] ca-certificates-0:2024.2.69_v 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [108/163] crypto-policies-0:20250402-2. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [109/163] ncurses-base-0:6.5-5.20250125 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [110/163] libxml2-0:2.12.10-1.fc43.x86_ 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [111/163] libzstd-0:1.5.7-1.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [112/163] fedora-gpg-keys-0:43-0.2.noar 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [113/163] fedora-repos-rawhide-0:43-0.2 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [114/163] elfutils-debuginfod-client-0: 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [115/163] elfutils-libs-0:0.193-2.fc43. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [116/163] libffi-0:3.4.8-1.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [117/163] p11-kit-0:0.25.5-5.fc42.x86_6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [118/163] p11-kit-trust-0:0.25.5-5.fc42 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [119/163] alternatives-0:1.33-1.fc43.x8 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [120/163] jansson-0:2.14-2.fc42.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [121/163] lua-libs-0:5.4.7-3.fc43.x86_6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [122/163] rpm-sequoia-0:1.8.0-1.fc43.x8 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [123/163] libgomp-0:15.1.1-1.fc43.x86_6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [124/163] rpm-sign-libs-0:5.99.90-5.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [125/163] libtasn1-0:4.20.0-1.fc43.x86_ 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [126/163] elfutils-default-yama-scope-0 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [127/163] json-c-0:0.18-2.fc42.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [128/163] gnupg2-0:2.4.7-3.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [129/163] ima-evm-utils-libs-0:1.6.2-5. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [130/163] libfsverity-0:1.6-2.fc42.x86_ 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [131/163] gpgverify-0:2.1-3.fc43.noarch 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [132/163] tpm2-tss-0:4.1.3-7.fc43.x86_6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [133/163] gnutls-0:3.8.9-5.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [134/163] libassuan-0:2.5.7-3.fc42.x86_ 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [135/163] libgcrypt-0:1.11.1-1.fc43.x86 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [136/163] libgpg-error-0:1.55-1.fc43.x8 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [137/163] libksba-0:1.6.7-3.fc42.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [138/163] npth-0:1.8-2.fc42.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [139/163] openldap-0:2.6.9-5.fc43.x86_6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [140/163] libusb1-0:1.0.28-2.fc43.x86_6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [141/163] cyrus-sasl-lib-0:2.1.28-30.fc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [142/163] libevent-0:2.1.12-15.fc42.x86 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [143/163] libtool-ltdl-0:2.5.4-4.fc42.x 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [144/163] libidn2-0:2.3.8-1.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [145/163] libunistring-0:1.1-9.fc42.x86 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [146/163] nettle-0:3.10.1-1.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [147/163] gdbm-libs-1:1.23-9.fc42.x86_6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [148/163] fedora-release-0:43-0.15.noar 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [149/163] fedora-release-identity-basic 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [150/163] libcurl-0:8.14.0~rc1-1.fc43.x 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [151/163] gdb-minimal-0:16.3-1.fc43.x86 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [152/163] systemd-standalone-sysusers-0 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [153/163] xxhash-libs-0:0.8.3-2.fc42.x8 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [154/163] krb5-libs-0:1.21.3-5.fc42.x86 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [155/163] libbrotli-0:1.1.0-6.fc43.x86_ 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [156/163] libnghttp2-0:1.65.0-1.fc43.x8 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [157/163] libpsl-0:0.21.5-5.fc42.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [158/163] libssh-0:0.11.1-4.fc42.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [159/163] keyutils-libs-0:1.6.3-5.fc42. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [160/163] libcom_err-0:1.47.2-3.fc42.x8 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [161/163] libverto-0:0.3.2-10.fc42.x86_ 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [162/163] libssh-config-0:0.11.1-4.fc42 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [163/163] publicsuffix-list-dafsa-0:202 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded -------------------------------------------------------------------------------- [163/163] Total 100% | 0.0 B/s | 0.0 B | 00m00s Running transaction [ 1/165] Verify package files 100% | 862.0 B/s | 163.0 B | 00m00s >>> Running pre-transaction scriptlet: filesystem-0:3.18-44.fc43.x86_64 >>> Finished pre-transaction scriptlet: filesystem-0:3.18-44.fc43.x86_64 >>> [RPM] /var/lib/mock/fedora-rawhide-x86_64-1747249355.591554/root/var/cache/d [ 2/165] Prepare transaction 100% | 4.2 KiB/s | 163.0 B | 00m00s [ 3/165] Installing libgcc-0:15.1.1-1. 100% | 262.0 MiB/s | 268.3 KiB | 00m00s [ 4/165] Installing publicsuffix-list- 100% | 0.0 B/s | 69.2 KiB | 00m00s [ 5/165] Installing libssh-config-0:0. 100% | 0.0 B/s | 816.0 B | 00m00s [ 6/165] Installing fedora-release-ide 100% | 0.0 B/s | 920.0 B | 00m00s [ 7/165] Installing fedora-gpg-keys-0: 100% | 42.9 MiB/s | 175.9 KiB | 00m00s [ 8/165] Installing fedora-repos-rawhi 100% | 0.0 B/s | 2.4 KiB | 00m00s [ 9/165] Installing fedora-repos-0:43- 100% | 0.0 B/s | 5.7 KiB | 00m00s [ 10/165] Installing fedora-release-com 100% | 24.1 MiB/s | 24.7 KiB | 00m00s [ 11/165] Installing fedora-release-0:4 100% | 0.0 B/s | 124.0 B | 00m00s [ 12/165] Installing setup-0:2.15.0-24. 100% | 64.8 MiB/s | 730.4 KiB | 00m00s >>> [RPM] /etc/hosts created as /etc/hosts.rpmnew [ 13/165] Installing filesystem-0:3.18- 100% | 2.8 MiB/s | 212.5 KiB | 00m00s [ 14/165] Installing ncurses-base-0:6.5 100% | 86.0 MiB/s | 352.2 KiB | 00m00s [ 15/165] Installing glibc-minimal-lang 100% | 0.0 B/s | 124.0 B | 00m00s [ 16/165] Installing ncurses-libs-0:6.5 100% | 232.6 MiB/s | 952.8 KiB | 00m00s [ 17/165] Installing glibc-0:2.41.9000- 100% | 215.4 MiB/s | 6.7 MiB | 00m00s [ 18/165] Installing bash-0:5.2.37-3.fc 100% | 282.1 MiB/s | 8.2 MiB | 00m00s [ 19/165] Installing glibc-common-0:2.4 100% | 72.9 MiB/s | 1.0 MiB | 00m00s [ 20/165] Installing glibc-gconv-extra- 100% | 261.1 MiB/s | 7.3 MiB | 00m00s [ 21/165] Installing zlib-ng-compat-0:2 100% | 135.2 MiB/s | 138.4 KiB | 00m00s [ 22/165] Installing bzip2-libs-0:1.0.8 100% | 83.7 MiB/s | 85.7 KiB | 00m00s [ 23/165] Installing libstdc++-0:15.1.1 100% | 405.2 MiB/s | 2.8 MiB | 00m00s [ 24/165] Installing xz-libs-1:5.8.1-1. 100% | 213.8 MiB/s | 218.9 KiB | 00m00s [ 25/165] Installing libuuid-0:2.41-2.f 100% | 0.0 B/s | 38.3 KiB | 00m00s [ 26/165] Installing gmp-1:6.3.0-3.fc43 100% | 401.1 MiB/s | 821.5 KiB | 00m00s [ 27/165] Installing readline-0:8.2-13. 100% | 237.8 MiB/s | 487.1 KiB | 00m00s [ 28/165] Installing popt-0:1.19-8.fc42 100% | 68.1 MiB/s | 139.4 KiB | 00m00s [ 29/165] Installing libblkid-0:2.41-2. 100% | 257.4 MiB/s | 263.5 KiB | 00m00s [ 30/165] Installing libxcrypt-0:4.4.38 100% | 280.4 MiB/s | 287.2 KiB | 00m00s [ 31/165] Installing libzstd-0:1.5.7-1. 100% | 395.1 MiB/s | 809.1 KiB | 00m00s [ 32/165] Installing elfutils-libelf-0: 100% | 388.8 MiB/s | 1.2 MiB | 00m00s [ 33/165] Installing libgpg-error-0:1.5 100% | 40.9 MiB/s | 921.1 KiB | 00m00s [ 34/165] Installing crypto-policies-0: 100% | 32.5 MiB/s | 166.6 KiB | 00m00s [ 35/165] Installing libattr-0:2.5.2-5. 100% | 0.0 B/s | 28.1 KiB | 00m00s [ 36/165] Installing libacl-0:2.3.2-3.f 100% | 0.0 B/s | 39.2 KiB | 00m00s [ 37/165] Installing sqlite-libs-0:3.49 100% | 377.1 MiB/s | 1.5 MiB | 00m00s [ 38/165] Installing libtasn1-0:4.20.0- 100% | 173.9 MiB/s | 178.1 KiB | 00m00s [ 39/165] Installing libunistring-0:1.1 100% | 431.7 MiB/s | 1.7 MiB | 00m00s [ 40/165] Installing libidn2-0:2.3.8-1. 100% | 181.9 MiB/s | 558.7 KiB | 00m00s [ 41/165] Installing dwz-0:0.15-9.fc42. 100% | 22.0 MiB/s | 292.4 KiB | 00m00s [ 42/165] Installing mpfr-0:4.2.2-1.fc4 100% | 270.3 MiB/s | 830.4 KiB | 00m00s [ 43/165] Installing gawk-0:5.3.2-1.fc4 100% | 113.5 MiB/s | 1.8 MiB | 00m00s [ 44/165] Installing unzip-0:6.0-66.fc4 100% | 32.0 MiB/s | 393.8 KiB | 00m00s [ 45/165] Installing file-libs-0:5.46-1 100% | 697.5 MiB/s | 11.9 MiB | 00m00s [ 46/165] Installing file-0:5.46-1.fc43 100% | 9.9 MiB/s | 101.7 KiB | 00m00s [ 47/165] Installing libsmartcols-0:2.4 100% | 177.3 MiB/s | 181.6 KiB | 00m00s [ 48/165] Installing libeconf-0:0.7.6-1 100% | 64.7 MiB/s | 66.2 KiB | 00m00s [ 49/165] Installing libcap-ng-0:0.8.5- 100% | 0.0 B/s | 70.8 KiB | 00m00s [ 50/165] Installing audit-libs-0:4.0.3 100% | 341.1 MiB/s | 349.3 KiB | 00m00s [ 51/165] Installing pam-libs-0:1.7.0-4 100% | 126.1 MiB/s | 129.1 KiB | 00m00s [ 52/165] Installing libcap-0:2.76-1.fc 100% | 19.0 MiB/s | 214.3 KiB | 00m00s [ 53/165] Installing systemd-libs-0:257 100% | 372.0 MiB/s | 2.2 MiB | 00m00s [ 54/165] Installing libsepol-0:3.8-1.f 100% | 403.8 MiB/s | 827.0 KiB | 00m00s [ 55/165] Installing lz4-libs-0:1.10.0- 100% | 154.7 MiB/s | 158.5 KiB | 00m00s [ 56/165] Installing libffi-0:3.4.8-1.f 100% | 82.4 MiB/s | 84.3 KiB | 00m00s [ 57/165] Installing p11-kit-0:0.25.5-5 100% | 121.3 MiB/s | 2.2 MiB | 00m00s [ 58/165] Installing alternatives-0:1.3 100% | 5.7 MiB/s | 63.8 KiB | 00m00s [ 59/165] Installing p11-kit-trust-0:0. 100% | 20.4 MiB/s | 397.2 KiB | 00m00s [ 60/165] Installing lua-libs-0:5.4.7-3 100% | 271.5 MiB/s | 278.1 KiB | 00m00s [ 61/165] Installing json-c-0:0.18-2.fc 100% | 0.0 B/s | 88.0 KiB | 00m00s [ 62/165] Installing zstd-0:1.5.7-1.fc4 100% | 114.0 MiB/s | 1.7 MiB | 00m00s [ 63/165] Installing libusb1-0:1.0.28-2 100% | 168.7 MiB/s | 172.7 KiB | 00m00s [ 64/165] Installing zip-0:3.0-43.fc42. 100% | 57.2 MiB/s | 702.4 KiB | 00m00s [ 65/165] Installing libpsl-0:0.21.5-5. 100% | 0.0 B/s | 77.5 KiB | 00m00s [ 66/165] Installing liblastlog2-0:2.41 100% | 0.0 B/s | 35.9 KiB | 00m00s [ 67/165] Installing libassuan-0:2.5.7- 100% | 165.6 MiB/s | 169.6 KiB | 00m00s [ 68/165] Installing libgcrypt-0:1.11.1 100% | 393.8 MiB/s | 1.6 MiB | 00m00s [ 69/165] Installing libksba-0:1.6.7-3. 100% | 395.6 MiB/s | 405.1 KiB | 00m00s [ 70/165] Installing libfdisk-0:2.41-2. 100% | 368.6 MiB/s | 377.5 KiB | 00m00s [ 71/165] Installing nettle-0:3.10.1-1. 100% | 258.3 MiB/s | 793.6 KiB | 00m00s [ 72/165] Installing gnutls-0:3.8.9-5.f 100% | 357.4 MiB/s | 3.6 MiB | 00m00s [ 73/165] Installing libxml2-0:2.12.10- 100% | 113.6 MiB/s | 1.7 MiB | 00m00s [ 74/165] Installing bzip2-0:1.0.8-20.f 100% | 9.2 MiB/s | 103.8 KiB | 00m00s [ 75/165] Installing add-determinism-0: 100% | 154.1 MiB/s | 2.5 MiB | 00m00s [ 76/165] Installing build-reproducibil 100% | 0.0 B/s | 1.0 KiB | 00m00s [ 77/165] Installing filesystem-srpm-ma 100% | 0.0 B/s | 38.9 KiB | 00m00s [ 78/165] Installing ed-0:1.21-2.fc42.x 100% | 14.5 MiB/s | 148.8 KiB | 00m00s [ 79/165] Installing patch-0:2.8-1.fc43 100% | 20.3 MiB/s | 228.3 KiB | 00m00s [ 80/165] Installing elfutils-default-y 100% | 340.5 KiB/s | 2.0 KiB | 00m00s [ 81/165] Installing elfutils-libs-0:0. 100% | 223.1 MiB/s | 685.2 KiB | 00m00s [ 82/165] Installing cpio-0:2.15-2.fc41 100% | 73.3 MiB/s | 1.1 MiB | 00m00s [ 83/165] Installing diffutils-0:3.12-2 100% | 104.1 MiB/s | 1.6 MiB | 00m00s [ 84/165] Installing libpkgconf-0:2.3.0 100% | 77.4 MiB/s | 79.2 KiB | 00m00s [ 85/165] Installing pkgconf-0:2.3.0-2. 100% | 8.1 MiB/s | 91.0 KiB | 00m00s [ 86/165] Installing jansson-0:2.14-2.f 100% | 92.2 MiB/s | 94.4 KiB | 00m00s [ 87/165] Installing libgomp-0:15.1.1-1 100% | 527.3 MiB/s | 539.9 KiB | 00m00s [ 88/165] Installing npth-0:1.8-2.fc42. 100% | 0.0 B/s | 50.7 KiB | 00m00s [ 89/165] Installing libtool-ltdl-0:2.5 100% | 0.0 B/s | 71.2 KiB | 00m00s [ 90/165] Installing gdbm-libs-1:1.23-9 100% | 128.5 MiB/s | 131.6 KiB | 00m00s [ 91/165] Installing cyrus-sasl-lib-0:2 100% | 144.0 MiB/s | 2.3 MiB | 00m00s [ 92/165] Installing xxhash-libs-0:0.8. 100% | 89.4 MiB/s | 91.6 KiB | 00m00s [ 93/165] Installing libbrotli-0:1.1.0- 100% | 272.0 MiB/s | 835.6 KiB | 00m00s [ 94/165] Installing libnghttp2-0:1.65. 100% | 159.5 MiB/s | 163.3 KiB | 00m00s [ 95/165] Installing keyutils-libs-0:1. 100% | 0.0 B/s | 59.7 KiB | 00m00s [ 96/165] Installing libcom_err-0:1.47. 100% | 0.0 B/s | 68.2 KiB | 00m00s [ 97/165] Installing libverto-0:0.3.2-1 100% | 0.0 B/s | 27.2 KiB | 00m00s [ 98/165] Installing pcre2-syntax-0:10. 100% | 269.9 MiB/s | 276.4 KiB | 00m00s [ 99/165] Installing pcre2-0:10.45-1.fc 100% | 341.4 MiB/s | 699.1 KiB | 00m00s [100/165] Installing libselinux-0:3.8-1 100% | 189.8 MiB/s | 194.3 KiB | 00m00s [101/165] Installing grep-0:3.12-1.fc43 100% | 71.6 MiB/s | 1.0 MiB | 00m00s [102/165] Installing sed-0:4.9-4.fc42.x 100% | 65.0 MiB/s | 865.5 KiB | 00m00s [103/165] Installing findutils-1:4.10.0 100% | 117.1 MiB/s | 1.9 MiB | 00m00s [104/165] Installing xz-1:5.8.1-1.fc43. 100% | 83.2 MiB/s | 1.3 MiB | 00m00s [105/165] Installing libmount-0:2.41-2. 100% | 182.4 MiB/s | 373.7 KiB | 00m00s [106/165] Installing util-linux-core-0: 100% | 92.0 MiB/s | 1.5 MiB | 00m00s [107/165] Installing tar-2:1.35-5.fc42. 100% | 164.6 MiB/s | 3.0 MiB | 00m00s [108/165] Installing libsemanage-0:3.8- 100% | 299.0 MiB/s | 306.2 KiB | 00m00s [109/165] Installing systemd-standalone 100% | 24.7 MiB/s | 277.8 KiB | 00m00s [110/165] Installing pkgconf-m4-0:2.3.0 100% | 0.0 B/s | 14.8 KiB | 00m00s [111/165] Installing pkgconf-pkg-config 100% | 177.3 KiB/s | 1.8 KiB | 00m00s [112/165] Installing coreutils-common-0 100% | 418.2 MiB/s | 11.3 MiB | 00m00s [113/165] Installing openssl-libs-1:3.5 100% | 423.3 MiB/s | 8.9 MiB | 00m00s [114/165] Installing coreutils-0:9.7-1. 100% | 165.0 MiB/s | 5.4 MiB | 00m00s [115/165] Installing ca-certificates-0: 100% | 2.1 MiB/s | 2.4 MiB | 00m01s [116/165] Installing libarchive-0:3.7.7 100% | 227.7 MiB/s | 932.6 KiB | 00m00s [117/165] Installing krb5-libs-0:1.21.3 100% | 287.5 MiB/s | 2.3 MiB | 00m00s [118/165] Installing tpm2-tss-0:4.1.3-7 100% | 313.6 MiB/s | 1.6 MiB | 00m00s [119/165] Installing ima-evm-utils-libs 100% | 60.5 MiB/s | 62.0 KiB | 00m00s [120/165] Installing libssh-0:0.11.1-4. 100% | 277.1 MiB/s | 567.5 KiB | 00m00s [121/165] Installing gzip-0:1.13-3.fc42 100% | 27.8 MiB/s | 398.4 KiB | 00m00s [122/165] Installing rpm-sequoia-0:1.8. 100% | 357.7 MiB/s | 2.5 MiB | 00m00s [123/165] Installing rpm-libs-0:5.99.90 100% | 303.2 MiB/s | 931.3 KiB | 00m00s [124/165] Installing libfsverity-0:1.6- 100% | 0.0 B/s | 33.5 KiB | 00m00s [125/165] Installing libevent-0:2.1.12- 100% | 295.2 MiB/s | 906.9 KiB | 00m00s [126/165] Installing openldap-0:2.6.9-5 100% | 214.5 MiB/s | 658.9 KiB | 00m00s [127/165] Installing gnupg2-0:2.4.7-3.f 100% | 251.1 MiB/s | 9.8 MiB | 00m00s [128/165] Installing libcurl-0:8.14.0~r 100% | 290.4 MiB/s | 892.1 KiB | 00m00s [129/165] Installing elfutils-debuginfo 100% | 7.7 MiB/s | 86.2 KiB | 00m00s [130/165] Installing binutils-0:2.44-3. 100% | 332.1 MiB/s | 25.9 MiB | 00m00s [131/165] Installing elfutils-0:0.193-2 100% | 153.8 MiB/s | 2.9 MiB | 00m00s [132/165] Installing gdb-minimal-0:16.3 100% | 301.1 MiB/s | 13.2 MiB | 00m00s [133/165] Installing debugedit-0:5.1-6. 100% | 15.9 MiB/s | 195.4 KiB | 00m00s [134/165] Installing curl-0:8.14.0~rc1- 100% | 22.1 MiB/s | 476.0 KiB | 00m00s [135/165] Installing rpm-0:5.99.90-5.fc 100% | 78.4 MiB/s | 2.5 MiB | 00m00s [136/165] Installing efi-srpm-macros-0: 100% | 40.2 MiB/s | 41.1 KiB | 00m00s [137/165] Installing lua-srpm-macros-0: 100% | 0.0 B/s | 1.9 KiB | 00m00s [138/165] Installing tree-sitter-srpm-m 100% | 0.0 B/s | 8.6 KiB | 00m00s [139/165] Installing zig-srpm-macros-0: 100% | 0.0 B/s | 1.7 KiB | 00m00s [140/165] Installing rpm-sign-libs-0:5. 100% | 39.6 MiB/s | 40.5 KiB | 00m00s [141/165] Installing rpm-build-libs-0:5 100% | 259.0 MiB/s | 265.2 KiB | 00m00s [142/165] Installing gpgverify-0:2.1-3. 100% | 0.0 B/s | 9.4 KiB | 00m00s [143/165] Installing rust-srpm-macros-0 100% | 0.0 B/s | 5.6 KiB | 00m00s [144/165] Installing qt6-srpm-macros-0: 100% | 0.0 B/s | 740.0 B | 00m00s [145/165] Installing qt5-srpm-macros-0: 100% | 0.0 B/s | 776.0 B | 00m00s [146/165] Installing perl-srpm-macros-0 100% | 0.0 B/s | 1.1 KiB | 00m00s [147/165] Installing package-notes-srpm 100% | 0.0 B/s | 2.0 KiB | 00m00s [148/165] Installing openblas-srpm-macr 100% | 0.0 B/s | 392.0 B | 00m00s [149/165] Installing ocaml-srpm-macros- 100% | 0.0 B/s | 2.2 KiB | 00m00s [150/165] Installing kernel-srpm-macros 100% | 0.0 B/s | 2.3 KiB | 00m00s [151/165] Installing gnat-srpm-macros-0 100% | 0.0 B/s | 1.3 KiB | 00m00s [152/165] Installing ghc-srpm-macros-0: 100% | 0.0 B/s | 1.0 KiB | 00m00s [153/165] Installing fpc-srpm-macros-0: 100% | 0.0 B/s | 420.0 B | 00m00s [154/165] Installing ansible-srpm-macro 100% | 0.0 B/s | 36.2 KiB | 00m00s [155/165] Installing fonts-srpm-macros- 100% | 0.0 B/s | 57.0 KiB | 00m00s [156/165] Installing forge-srpm-macros- 100% | 0.0 B/s | 40.3 KiB | 00m00s [157/165] Installing go-srpm-macros-0:3 100% | 0.0 B/s | 62.0 KiB | 00m00s [158/165] Installing python-srpm-macros 100% | 0.0 B/s | 53.0 KiB | 00m00s [159/165] Installing redhat-rpm-config- 100% | 91.8 MiB/s | 188.0 KiB | 00m00s [160/165] Installing rpm-build-0:5.99.9 100% | 21.8 MiB/s | 290.3 KiB | 00m00s [161/165] Installing pyproject-srpm-mac 100% | 0.0 B/s | 2.5 KiB | 00m00s [162/165] Installing which-0:2.23-1.fc4 100% | 7.0 MiB/s | 85.6 KiB | 00m00s [163/165] Installing util-linux-0:2.41- 100% | 98.9 MiB/s | 3.6 MiB | 00m00s [164/165] Installing shadow-utils-2:4.1 100% | 139.8 MiB/s | 4.1 MiB | 00m00s [165/165] Installing info-0:7.2-3.fc42. 100% | 234.8 KiB/s | 358.3 KiB | 00m02s Warning: skipped OpenPGP checks for 163 packages from repositories: copr_base, http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch Complete! Finish: installing minimal buildroot with dnf5 Start: creating root cache Finish: creating root cache Finish: chroot init INFO: Installed packages: INFO: add-determinism-0.6.0-1.fc43.x86_64 alternatives-1.33-1.fc43.x86_64 ansible-srpm-macros-1-17.1.fc42.noarch audit-libs-4.0.3-2.fc43.x86_64 bash-5.2.37-3.fc43.x86_64 binutils-2.44-3.fc43.x86_64 build-reproducibility-srpm-macros-0.6.0-1.fc43.noarch bzip2-1.0.8-20.fc42.x86_64 bzip2-libs-1.0.8-20.fc42.x86_64 ca-certificates-2024.2.69_v8.0.401-5.fc42.noarch coreutils-9.7-1.fc43.x86_64 coreutils-common-9.7-1.fc43.x86_64 cpio-2.15-2.fc41.x86_64 crypto-policies-20250402-2.git86c0178.fc43.noarch curl-8.14.0~rc1-1.fc43.x86_64 cyrus-sasl-lib-2.1.28-30.fc42.x86_64 debugedit-5.1-6.fc43.x86_64 diffutils-3.12-2.fc43.x86_64 dwz-0.15-9.fc42.x86_64 ed-1.21-2.fc42.x86_64 efi-srpm-macros-6-3.fc43.noarch elfutils-0.193-2.fc43.x86_64 elfutils-debuginfod-client-0.193-2.fc43.x86_64 elfutils-default-yama-scope-0.193-2.fc43.noarch elfutils-libelf-0.193-2.fc43.x86_64 elfutils-libs-0.193-2.fc43.x86_64 fedora-gpg-keys-43-0.2.noarch fedora-release-43-0.15.noarch fedora-release-common-43-0.15.noarch fedora-release-identity-basic-43-0.15.noarch fedora-repos-43-0.2.noarch fedora-repos-rawhide-43-0.2.noarch file-5.46-1.fc43.x86_64 file-libs-5.46-1.fc43.x86_64 filesystem-3.18-44.fc43.x86_64 filesystem-srpm-macros-3.18-44.fc43.noarch findutils-4.10.0-5.fc42.x86_64 fonts-srpm-macros-2.0.5-21.fc42.noarch forge-srpm-macros-0.4.0-2.fc42.noarch fpc-srpm-macros-1.3-14.fc42.noarch gawk-5.3.2-1.fc43.x86_64 gdb-minimal-16.3-1.fc43.x86_64 gdbm-libs-1.23-9.fc42.x86_64 ghc-srpm-macros-1.9.2-2.fc42.noarch glibc-2.41.9000-13.fc43.x86_64 glibc-common-2.41.9000-13.fc43.x86_64 glibc-gconv-extra-2.41.9000-13.fc43.x86_64 glibc-minimal-langpack-2.41.9000-13.fc43.x86_64 gmp-6.3.0-3.fc43.x86_64 gnat-srpm-macros-6-7.fc42.noarch gnupg2-2.4.7-3.fc43.x86_64 gnutls-3.8.9-5.fc43.x86_64 go-srpm-macros-3.6.0-7.fc43.noarch gpgverify-2.1-3.fc43.noarch grep-3.12-1.fc43.x86_64 gzip-1.13-3.fc42.x86_64 ima-evm-utils-libs-1.6.2-5.fc43.x86_64 info-7.2-3.fc42.x86_64 jansson-2.14-2.fc42.x86_64 json-c-0.18-2.fc42.x86_64 kernel-srpm-macros-1.0-25.fc42.noarch keyutils-libs-1.6.3-5.fc42.x86_64 krb5-libs-1.21.3-5.fc42.x86_64 libacl-2.3.2-3.fc42.x86_64 libarchive-3.7.7-4.fc43.x86_64 libassuan-2.5.7-3.fc42.x86_64 libattr-2.5.2-5.fc42.x86_64 libblkid-2.41-2.fc43.x86_64 libbrotli-1.1.0-6.fc43.x86_64 libcap-2.76-1.fc43.x86_64 libcap-ng-0.8.5-4.fc43.x86_64 libcom_err-1.47.2-3.fc42.x86_64 libcurl-8.14.0~rc1-1.fc43.x86_64 libeconf-0.7.6-1.fc43.x86_64 libevent-2.1.12-15.fc42.x86_64 libfdisk-2.41-2.fc43.x86_64 libffi-3.4.8-1.fc43.x86_64 libfsverity-1.6-2.fc42.x86_64 libgcc-15.1.1-1.fc43.x86_64 libgcrypt-1.11.1-1.fc43.x86_64 libgomp-15.1.1-1.fc43.x86_64 libgpg-error-1.55-1.fc43.x86_64 libidn2-2.3.8-1.fc43.x86_64 libksba-1.6.7-3.fc42.x86_64 liblastlog2-2.41-2.fc43.x86_64 libmount-2.41-2.fc43.x86_64 libnghttp2-1.65.0-1.fc43.x86_64 libpkgconf-2.3.0-2.fc42.x86_64 libpsl-0.21.5-5.fc42.x86_64 libselinux-3.8-1.fc43.x86_64 libsemanage-3.8-1.fc43.x86_64 libsepol-3.8-1.fc42.x86_64 libsmartcols-2.41-2.fc43.x86_64 libssh-0.11.1-4.fc42.x86_64 libssh-config-0.11.1-4.fc42.noarch libstdc++-15.1.1-1.fc43.x86_64 libtasn1-4.20.0-1.fc43.x86_64 libtool-ltdl-2.5.4-4.fc42.x86_64 libunistring-1.1-9.fc42.x86_64 libusb1-1.0.28-2.fc43.x86_64 libuuid-2.41-2.fc43.x86_64 libverto-0.3.2-10.fc42.x86_64 libxcrypt-4.4.38-7.fc43.x86_64 libxml2-2.12.10-1.fc43.x86_64 libzstd-1.5.7-1.fc43.x86_64 lua-libs-5.4.7-3.fc43.x86_64 lua-srpm-macros-1-15.fc42.noarch lz4-libs-1.10.0-2.fc42.x86_64 mpfr-4.2.2-1.fc43.x86_64 ncurses-base-6.5-5.20250125.fc42.noarch ncurses-libs-6.5-5.20250125.fc42.x86_64 nettle-3.10.1-1.fc43.x86_64 npth-1.8-2.fc42.x86_64 ocaml-srpm-macros-10-4.fc42.noarch openblas-srpm-macros-2-19.fc42.noarch openldap-2.6.9-5.fc43.x86_64 openssl-libs-3.5.0-3.fc43.x86_64 p11-kit-0.25.5-5.fc42.x86_64 p11-kit-trust-0.25.5-5.fc42.x86_64 package-notes-srpm-macros-0.5-13.fc42.noarch pam-libs-1.7.0-4.fc42.x86_64 patch-2.8-1.fc43.x86_64 pcre2-10.45-1.fc43.x86_64 pcre2-syntax-10.45-1.fc43.noarch perl-srpm-macros-1-57.fc42.noarch pkgconf-2.3.0-2.fc42.x86_64 pkgconf-m4-2.3.0-2.fc42.noarch pkgconf-pkg-config-2.3.0-2.fc42.x86_64 popt-1.19-8.fc42.x86_64 publicsuffix-list-dafsa-20250116-1.fc42.noarch pyproject-srpm-macros-1.18.1-1.fc43.noarch python-srpm-macros-3.14-5.fc43.noarch qt5-srpm-macros-5.15.16-1.fc43.noarch qt6-srpm-macros-6.9.0-2.fc43.noarch readline-8.2-13.fc43.x86_64 redhat-rpm-config-343-5.fc43.noarch rpm-5.99.90-5.fc43.x86_64 rpm-build-5.99.90-5.fc43.x86_64 rpm-build-libs-5.99.90-5.fc43.x86_64 rpm-libs-5.99.90-5.fc43.x86_64 rpm-sequoia-1.8.0-1.fc43.x86_64 rpm-sign-libs-5.99.90-5.fc43.x86_64 rust-srpm-macros-26.3-4.fc42.noarch sed-4.9-4.fc42.x86_64 setup-2.15.0-24.fc43.noarch shadow-utils-4.17.4-1.fc43.x86_64 sqlite-libs-3.49.1-1.fc43.x86_64 systemd-libs-257.5-5.fc43.x86_64 systemd-standalone-sysusers-257.5-5.fc43.x86_64 tar-1.35-5.fc42.x86_64 tpm2-tss-4.1.3-7.fc43.x86_64 tree-sitter-srpm-macros-0.2.4-1.fc43.noarch unzip-6.0-66.fc42.x86_64 util-linux-2.41-2.fc43.x86_64 util-linux-core-2.41-2.fc43.x86_64 which-2.23-1.fc42.x86_64 xxhash-libs-0.8.3-2.fc42.x86_64 xz-5.8.1-1.fc43.x86_64 xz-libs-5.8.1-1.fc43.x86_64 zig-srpm-macros-1-4.fc42.noarch zip-3.0-43.fc42.x86_64 zlib-ng-compat-2.2.4-2.fc43.x86_64 zstd-1.5.7-1.fc43.x86_64 Start: buildsrpm Start: rpmbuild -bs Building target platforms: x86_64 Building for target x86_64 setting SOURCE_DATE_EPOCH=1737849600 Wrote: /builddir/build/SRPMS/python-executing-2.2.0-2.fc43.src.rpm Finish: rpmbuild -bs INFO: chroot_scan: 1 files copied to /var/lib/copr-rpmbuild/results/chroot_scan INFO: /var/lib/mock/fedora-rawhide-x86_64-1747249355.591554/root/var/log/dnf5.log INFO: chroot_scan: creating tarball /var/lib/copr-rpmbuild/results/chroot_scan.tar.gz /bin/tar: Removing leading `/' from member names Finish: buildsrpm INFO: Done(/var/lib/copr-rpmbuild/workspace/workdir-q5p0gqla/python-executing/python-executing.spec) Config(child) 0 minutes 7 seconds INFO: Results and/or logs in: /var/lib/copr-rpmbuild/results INFO: Cleaning up build root ('cleanup_on_success=True') Start: clean chroot INFO: unmounting tmpfs. Finish: clean chroot INFO: Start(/var/lib/copr-rpmbuild/results/python-executing-2.2.0-2.fc43.src.rpm) Config(fedora-rawhide-x86_64) Start: chroot init INFO: mounting tmpfs at /var/lib/mock/fedora-rawhide-x86_64-1747249355.591554/root. INFO: calling preinit hooks INFO: enabled root cache Start: unpacking root cache Finish: unpacking root cache INFO: enabled package manager cache Start: cleaning package manager metadata Finish: cleaning package manager metadata INFO: enabled HW Info plugin INFO: Buildroot is handled by package management from host and used with --installroot: rpm-4.20.1-1.fc41.x86_64 rpm-sequoia-1.7.0-2.fc41.x86_64 python3-dnf-4.23.0-1.fc41.noarch python3-dnf-plugins-core-4.10.1-1.fc41.noarch dnf5-5.2.13.1-1.fc41.x86_64 dnf5-plugins-5.2.13.1-1.fc41.x86_64 Finish: chroot init Start: build phase for python-executing-2.2.0-2.fc43.src.rpm Start: build setup for python-executing-2.2.0-2.fc43.src.rpm Building target platforms: x86_64 Building for target x86_64 setting SOURCE_DATE_EPOCH=1737849600 Wrote: /builddir/build/SRPMS/python-executing-2.2.0-2.fc43.src.rpm Updating and loading repositories: fedora 100% | 196.7 KiB/s | 24.8 KiB | 00m00s Copr repository 100% | 24.4 KiB/s | 1.5 KiB | 00m00s Additional repo http_kojipkgs_fedorapr 100% | 212.7 KiB/s | 3.8 KiB | 00m00s Repositories loaded. Package Arch Version Repository Size Installing: python3-devel x86_64 3.14.0~b1-1.fc43 copr_base 1.9 MiB Installing dependencies: expat x86_64 2.7.1-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 294.2 KiB mpdecimal x86_64 4.0.0-2.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 216.8 KiB pyproject-rpm-macros noarch 1.18.1-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 114.5 KiB python-pip-wheel noarch 24.3.1-2.fc42 copr_base 1.2 MiB python-rpm-macros noarch 3.14-5.fc43 copr_base 22.1 KiB python3 x86_64 3.14.0~b1-1.fc43 copr_base 28.9 KiB python3-libs x86_64 3.14.0~b1-1.fc43 copr_base 42.5 MiB python3-packaging noarch 25.0-1.fc43 copr_base 607.5 KiB python3-rpm-generators noarch 14-12.fc42 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 81.7 KiB python3-rpm-macros noarch 3.14-5.fc43 copr_base 6.4 KiB tzdata noarch 2025b-1.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 1.6 MiB Transaction Summary: Installing: 12 packages Total size of inbound packages is 12 MiB. Need to download 0 B. After this operation, 49 MiB extra will be used (install 49 MiB, remove 0 B). [ 1/12] python3-devel-0:3.14.0~b1-1.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 2/12] python3-0:3.14.0~b1-1.fc43.x86_ 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 3/12] python3-libs-0:3.14.0~b1-1.fc43 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 4/12] expat-0:2.7.1-1.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 5/12] mpdecimal-0:4.0.0-2.fc43.x86_64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 6/12] python-pip-wheel-0:24.3.1-2.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 7/12] tzdata-0:2025b-1.fc43.noarch 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 8/12] python-rpm-macros-0:3.14-5.fc43 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 9/12] python3-rpm-macros-0:3.14-5.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [10/12] pyproject-rpm-macros-0:1.18.1-1 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [11/12] python3-rpm-generators-0:14-12. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [12/12] python3-packaging-0:25.0-1.fc43 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded -------------------------------------------------------------------------------- [12/12] Total 100% | 0.0 B/s | 0.0 B | 00m00s Running transaction [ 1/14] Verify package files 100% | 279.0 B/s | 12.0 B | 00m00s [ 2/14] Prepare transaction 100% | 545.0 B/s | 12.0 B | 00m00s [ 3/14] Installing python-rpm-macros-0: 100% | 0.0 B/s | 22.8 KiB | 00m00s [ 4/14] Installing python3-rpm-macros-0 100% | 0.0 B/s | 6.7 KiB | 00m00s [ 5/14] Installing pyproject-rpm-macros 100% | 56.9 MiB/s | 116.4 KiB | 00m00s [ 6/14] Installing tzdata-0:2025b-1.fc4 100% | 63.1 MiB/s | 1.9 MiB | 00m00s [ 7/14] Installing python-pip-wheel-0:2 100% | 622.1 MiB/s | 1.2 MiB | 00m00s [ 8/14] Installing mpdecimal-0:4.0.0-2. 100% | 213.2 MiB/s | 218.4 KiB | 00m00s [ 9/14] Installing expat-0:2.7.1-1.fc43 100% | 18.1 MiB/s | 296.3 KiB | 00m00s [10/14] Installing python3-libs-0:3.14. 100% | 340.3 MiB/s | 42.9 MiB | 00m00s [11/14] Installing python3-0:3.14.0~b1- 100% | 2.7 MiB/s | 30.7 KiB | 00m00s [12/14] Installing python3-packaging-0: 100% | 201.8 MiB/s | 620.0 KiB | 00m00s [13/14] Installing python3-rpm-generato 100% | 81.0 MiB/s | 82.9 KiB | 00m00s [14/14] Installing python3-devel-0:3.14 100% | 28.7 MiB/s | 2.0 MiB | 00m00s Warning: skipped OpenPGP checks for 12 packages from repositories: copr_base, http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch Complete! Finish: build setup for python-executing-2.2.0-2.fc43.src.rpm Start: rpmbuild python-executing-2.2.0-2.fc43.src.rpm Building target platforms: x86_64 Building for target x86_64 setting SOURCE_DATE_EPOCH=1737849600 Executing(%mkbuilddir): /bin/sh -e /var/tmp/rpm-tmp.z9llTl Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.lmgO8s + umask 022 + cd /builddir/build/BUILD/python-executing-2.2.0-build + cd /builddir/build/BUILD/python-executing-2.2.0-build + rm -rf executing-2.2.0 + /usr/lib/rpm/rpmuncompress -x /builddir/build/SOURCES/executing-2.2.0.tar.gz + STATUS=0 + '[' 0 -ne 0 ']' + cd executing-2.2.0 + /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w . + sed -Ei '/coverage-?/d' setup.cfg + RPM_EC=0 ++ jobs -p + exit 0 Executing(%generate_buildrequires): /bin/sh -e /var/tmp/rpm-tmp.8VzX5W + umask 022 + cd /builddir/build/BUILD/python-executing-2.2.0-build + cd executing-2.2.0 + export SETUPTOOLS_SCM_PRETEND_VERSION=2.2.0 + SETUPTOOLS_SCM_PRETEND_VERSION=2.2.0 + echo pyproject-rpm-macros + echo python3-devel + echo 'python3dist(packaging)' + echo 'python3dist(pip) >= 19' + '[' -f pyproject.toml ']' + echo '(python3dist(tomli) if python3-devel < 3.11)' + rm -rfv '*.dist-info/' + '[' -f /usr/bin/python3 ']' + mkdir -p /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/.pyproject-builddir + echo -n + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + VALAFLAGS=-g + RUSTFLAGS='-Copt-level=3 -Cdebuginfo=2 -Ccodegen-units=1 -Cstrip=none -Cforce-frame-pointers=yes --cap-lints=warn' + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,pack-relative-relocs -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-hardened-ld-errors -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 ' + LT_SYS_LIBRARY_PATH=/usr/lib64: + CC=gcc + CXX=g++ + TMPDIR=/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/.pyproject-builddir + RPM_TOXENV=py314 + FEDORA=43 + HOSTNAME=rpmbuild + /usr/bin/python3 -Bs /usr/lib/rpm/redhat/pyproject_buildrequires.py --generate-extras --python3_pkgversion 3 --wheeldir /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/pyproject-wheeldir --output /builddir/build/BUILD/python-executing-2.2.0-build/python-executing-2.2.0-2.fc43.x86_64-pyproject-buildrequires -t Handling setuptools from build-system.requires Requirement not satisfied: setuptools Handling wheel from build-system.requires Requirement not satisfied: wheel Handling setuptools_scm[toml] from build-system.requires Requirement not satisfied: setuptools_scm[toml] Exiting dependency generation pass: build backend + cat /builddir/build/BUILD/python-executing-2.2.0-build/python-executing-2.2.0-2.fc43.x86_64-pyproject-buildrequires + rm -rfv '*.dist-info/' + RPM_EC=0 ++ jobs -p + exit 0 Wrote: /builddir/build/SRPMS/python-executing-2.2.0-2.fc43.buildreqs.nosrc.rpm INFO: Going to install missing dynamic buildrequires Updating and loading repositories: fedora 100% | 269.4 KiB/s | 24.8 KiB | 00m00s Copr repository 100% | 18.3 KiB/s | 1.5 KiB | 00m00s Additional repo http_kojipkgs_fedorapr 100% | 225.2 KiB/s | 3.8 KiB | 00m00s Repositories loaded. Package "pyproject-rpm-macros-1.18.1-1.fc43.noarch" is already installed. Package "python3-devel-3.14.0~b1-1.fc43.x86_64" is already installed. Package "python3-packaging-25.0-1.fc43.noarch" is already installed. Package Arch Version Repository Size Installing: python3-pip noarch 24.3.1-2.fc42 copr_base 12.0 MiB python3-setuptools noarch 78.1.1-5.fc43 copr_base 9.0 MiB python3-setuptools_scm noarch 8.3.1-2.fc43 copr_base 354.5 KiB python3-setuptools_scm+toml noarch 8.3.1-2.fc43 copr_base 9.8 KiB python3-wheel noarch 1:0.45.1-13.fc43 copr_base 593.2 KiB Transaction Summary: Installing: 5 packages Total size of inbound packages is 5 MiB. Need to download 117 KiB. After this operation, 22 MiB extra will be used (install 22 MiB, remove 0 B). [1/5] python3-pip-0:24.3.1-2.fc42.noarc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [2/5] python3-setuptools-0:78.1.1-5.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [3/5] python3-wheel-1:0.45.1-13.fc43.no 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [4/5] python3-setuptools_scm-0:8.3.1-2. 100% | 10.4 MiB/s | 106.7 KiB | 00m00s [5/5] python3-setuptools_scm+toml-0:8.3 100% | 949.7 KiB/s | 10.4 KiB | 00m00s -------------------------------------------------------------------------------- [5/5] Total 100% | 7.6 MiB/s | 117.2 KiB | 00m00s Running transaction [1/7] Verify package files 100% | 263.0 B/s | 5.0 B | 00m00s [2/7] Prepare transaction 100% | 277.0 B/s | 5.0 B | 00m00s [3/7] Installing python3-setuptools-0:7 100% | 224.9 MiB/s | 9.2 MiB | 00m00s [4/7] Installing python3-setuptools_scm 100% | 121.9 MiB/s | 374.4 KiB | 00m00s [5/7] Installing python3-setuptools_scm 100% | 0.0 B/s | 124.0 B | 00m00s [6/7] Installing python3-wheel-1:0.45.1 100% | 35.2 MiB/s | 613.2 KiB | 00m00s [7/7] Installing python3-pip-0:24.3.1-2 100% | 121.0 MiB/s | 12.2 MiB | 00m00s Warning: skipped OpenPGP checks for 5 packages from repository: copr_base Complete! Building target platforms: x86_64 Building for target x86_64 setting SOURCE_DATE_EPOCH=1737849600 Executing(%generate_buildrequires): /bin/sh -e /var/tmp/rpm-tmp.rZi7Lj + umask 022 + cd /builddir/build/BUILD/python-executing-2.2.0-build + cd executing-2.2.0 + export SETUPTOOLS_SCM_PRETEND_VERSION=2.2.0 + SETUPTOOLS_SCM_PRETEND_VERSION=2.2.0 + echo pyproject-rpm-macros + echo python3-devel + echo 'python3dist(packaging)' + echo 'python3dist(pip) >= 19' + '[' -f pyproject.toml ']' + echo '(python3dist(tomli) if python3-devel < 3.11)' + rm -rfv '*.dist-info/' + '[' -f /usr/bin/python3 ']' + mkdir -p /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/.pyproject-builddir + echo -n + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + VALAFLAGS=-g + RUSTFLAGS='-Copt-level=3 -Cdebuginfo=2 -Ccodegen-units=1 -Cstrip=none -Cforce-frame-pointers=yes --cap-lints=warn' + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,pack-relative-relocs -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-hardened-ld-errors -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 ' + LT_SYS_LIBRARY_PATH=/usr/lib64: + CC=gcc + CXX=g++ + TMPDIR=/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/.pyproject-builddir + RPM_TOXENV=py314 + FEDORA=43 + HOSTNAME=rpmbuild + /usr/bin/python3 -Bs /usr/lib/rpm/redhat/pyproject_buildrequires.py --generate-extras --python3_pkgversion 3 --wheeldir /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/pyproject-wheeldir --output /builddir/build/BUILD/python-executing-2.2.0-build/python-executing-2.2.0-2.fc43.x86_64-pyproject-buildrequires -t Handling setuptools from build-system.requires Requirement satisfied: setuptools (installed: setuptools 78.1.1) Handling wheel from build-system.requires Requirement satisfied: wheel (installed: wheel 0.45.1) Handling setuptools_scm[toml] from build-system.requires Requirement satisfied: setuptools_scm[toml] (installed: setuptools_scm 8.3.1) (extras are currently not checked) /usr/lib/python3.14/site-packages/setuptools/dist.py:759: SetuptoolsDeprecationWarning: License classifiers are deprecated. !! ******************************************************************************** Please consider removing the following classifiers in favor of a SPDX license expression: License :: OSI Approved :: MIT License See https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license for details. ******************************************************************************** !! self._finalize_license_expression() Handling setuptools from get_requires_for_build_wheel Requirement satisfied: setuptools (installed: setuptools 78.1.1) Handling setuptools_scm[toml] from get_requires_for_build_wheel Requirement satisfied: setuptools_scm[toml] (installed: setuptools_scm 8.3.1) (extras are currently not checked) Handling tox-current-env >= 0.0.16 from tox itself Requirement not satisfied: tox-current-env >= 0.0.16 Exiting dependency generation pass: tox itself + cat /builddir/build/BUILD/python-executing-2.2.0-build/python-executing-2.2.0-2.fc43.x86_64-pyproject-buildrequires + rm -rfv '*.dist-info/' + RPM_EC=0 ++ jobs -p + exit 0 Wrote: /builddir/build/SRPMS/python-executing-2.2.0-2.fc43.buildreqs.nosrc.rpm INFO: Going to install missing dynamic buildrequires Updating and loading repositories: fedora 100% | 399.7 KiB/s | 24.8 KiB | 00m00s Copr repository 100% | 128.1 KiB/s | 1.5 KiB | 00m00s Additional repo http_kojipkgs_fedorapr 100% | 191.5 KiB/s | 3.8 KiB | 00m00s Repositories loaded. Package "pyproject-rpm-macros-1.18.1-1.fc43.noarch" is already installed. Package "python3-devel-3.14.0~b1-1.fc43.x86_64" is already installed. Package "python3-packaging-25.0-1.fc43.noarch" is already installed. Package "python3-pip-24.3.1-2.fc42.noarch" is already installed. Package "python3-setuptools-78.1.1-5.fc43.noarch" is already installed. Package "python3-setuptools_scm-8.3.1-2.fc43.noarch" is already installed. Package "python3-setuptools_scm+toml-8.3.1-2.fc43.noarch" is already installed. Package "python3-wheel-1:0.45.1-13.fc43.noarch" is already installed. Package Arch Version Repository Size Upgrading: python-pip-wheel noarch 25.1.1-3.fc43 http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch 1.2 MiB replacing python-pip-wheel noarch 24.3.1-2.fc42 copr_base 1.2 MiB Installing: python3-tox-current-env noarch 0.0.16-1.fc43 copr_base 78.4 KiB Installing dependencies: python-setuptools-wheel noarch 78.1.1-5.fc43 copr_base 1.1 MiB python3-cachetools noarch 5.5.2-1.fc43 copr_base 136.6 KiB python3-chardet noarch 5.2.0-18.fc43 copr_base 2.1 MiB python3-colorama noarch 0.4.6-10.fc43 copr_base 190.4 KiB python3-distlib noarch 0.3.9-2.fc43 copr_base 1.2 MiB python3-filelock noarch 3.15.4-5.fc43 copr_base 97.0 KiB python3-platformdirs noarch 4.2.2-4.fc43 copr_base 177.6 KiB python3-pluggy noarch 1.5.0-2.fc43 copr_base 213.2 KiB python3-pyproject-api noarch 1.9.0-1.fc43 copr_base 84.9 KiB python3-virtualenv noarch 20.31.2-1.fc43 copr_base 684.2 KiB tox noarch 4.26.0-2.fc43~bootstrap copr_base 1.4 MiB Transaction Summary: Installing: 12 packages Upgrading: 1 package Replacing: 1 package Total size of inbound packages is 4 MiB. Need to download 4 MiB. After this operation, 7 MiB extra will be used (install 9 MiB, remove 1 MiB). [ 1/13] python3-platformdirs-0:4.2.2-4. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 2/13] python3-pluggy-0:1.5.0-2.fc43.n 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 3/13] python3-tox-current-env-0:0.0.1 100% | 3.1 MiB/s | 32.2 KiB | 00m00s [ 4/13] python3-cachetools-0:5.5.2-1.fc 100% | 3.3 MiB/s | 40.1 KiB | 00m00s [ 5/13] tox-0:4.26.0-2.fc43~bootstrap.n 100% | 28.1 MiB/s | 402.2 KiB | 00m00s [ 6/13] python3-chardet-0:5.2.0-18.fc43 100% | 44.3 MiB/s | 272.0 KiB | 00m00s [ 7/13] python3-colorama-0:0.4.6-10.fc4 100% | 15.7 MiB/s | 64.4 KiB | 00m00s [ 8/13] python3-filelock-0:3.15.4-5.fc4 100% | 19.4 MiB/s | 39.8 KiB | 00m00s [ 9/13] python3-pyproject-api-0:1.9.0-1 100% | 12.6 MiB/s | 38.6 KiB | 00m00s [10/13] python3-distlib-0:0.3.9-2.fc43. 100% | 64.3 MiB/s | 263.5 KiB | 00m00s [11/13] python3-virtualenv-0:20.31.2-1. 100% | 49.5 MiB/s | 253.7 KiB | 00m00s [12/13] python-setuptools-wheel-0:78.1. 100% | 135.7 MiB/s | 1.1 MiB | 00m00s [13/13] python-pip-wheel-0:25.1.1-3.fc4 100% | 40.2 MiB/s | 1.2 MiB | 00m00s -------------------------------------------------------------------------------- [13/13] Total 100% | 69.1 MiB/s | 3.7 MiB | 00m00s Running transaction [ 1/16] Verify package files 100% | 928.0 B/s | 13.0 B | 00m00s [ 2/16] Prepare transaction 100% | 1.2 KiB/s | 14.0 B | 00m00s [ 3/16] Installing python3-platformdirs 100% | 89.8 MiB/s | 184.0 KiB | 00m00s [ 4/16] Installing python3-filelock-0:3 100% | 101.5 MiB/s | 103.9 KiB | 00m00s [ 5/16] Upgrading python-pip-wheel-0:25 100% | 622.5 MiB/s | 1.2 MiB | 00m00s [ 6/16] Installing python-setuptools-wh 100% | 573.9 MiB/s | 1.1 MiB | 00m00s [ 7/16] Installing python3-distlib-0:0. 100% | 299.1 MiB/s | 1.2 MiB | 00m00s [ 8/16] Installing python3-virtualenv-0 100% | 35.1 MiB/s | 754.0 KiB | 00m00s [ 9/16] Installing python3-pyproject-ap 100% | 88.9 MiB/s | 91.0 KiB | 00m00s [10/16] Installing python3-pluggy-0:1.5 100% | 214.5 MiB/s | 219.7 KiB | 00m00s [11/16] Installing python3-colorama-0:0 100% | 97.8 MiB/s | 200.3 KiB | 00m00s [12/16] Installing python3-chardet-0:5. 100% | 125.4 MiB/s | 2.1 MiB | 00m00s [13/16] Installing python3-cachetools-0 100% | 68.8 MiB/s | 141.0 KiB | 00m00s [14/16] Installing tox-0:4.26.0-2.fc43~ 100% | 69.4 MiB/s | 1.5 MiB | 00m00s [15/16] Installing python3-tox-current- 100% | 81.0 MiB/s | 82.9 KiB | 00m00s [16/16] Removing python-pip-wheel-0:24. 100% | 121.0 B/s | 4.0 B | 00m00s Warning: skipped OpenPGP checks for 13 packages from repositories: copr_base, http_kojipkgs_fedoraproject_org_repos_rawhide_latest_basearch Complete! Building target platforms: x86_64 Building for target x86_64 setting SOURCE_DATE_EPOCH=1737849600 Executing(%generate_buildrequires): /bin/sh -e /var/tmp/rpm-tmp.fVzMQa + umask 022 + cd /builddir/build/BUILD/python-executing-2.2.0-build + cd executing-2.2.0 + export SETUPTOOLS_SCM_PRETEND_VERSION=2.2.0 + SETUPTOOLS_SCM_PRETEND_VERSION=2.2.0 + echo pyproject-rpm-macros + echo python3-devel + echo 'python3dist(packaging)' + echo 'python3dist(pip) >= 19' + '[' -f pyproject.toml ']' + echo '(python3dist(tomli) if python3-devel < 3.11)' + rm -rfv '*.dist-info/' + '[' -f /usr/bin/python3 ']' + mkdir -p /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/.pyproject-builddir + echo -n + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + VALAFLAGS=-g + RUSTFLAGS='-Copt-level=3 -Cdebuginfo=2 -Ccodegen-units=1 -Cstrip=none -Cforce-frame-pointers=yes --cap-lints=warn' + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,pack-relative-relocs -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-hardened-ld-errors -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 ' + LT_SYS_LIBRARY_PATH=/usr/lib64: + CC=gcc + CXX=g++ + TMPDIR=/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/.pyproject-builddir + RPM_TOXENV=py314 + FEDORA=43 + HOSTNAME=rpmbuild + /usr/bin/python3 -Bs /usr/lib/rpm/redhat/pyproject_buildrequires.py --generate-extras --python3_pkgversion 3 --wheeldir /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/pyproject-wheeldir --output /builddir/build/BUILD/python-executing-2.2.0-build/python-executing-2.2.0-2.fc43.x86_64-pyproject-buildrequires -t Handling setuptools from build-system.requires Requirement satisfied: setuptools (installed: setuptools 78.1.1) Handling wheel from build-system.requires Requirement satisfied: wheel (installed: wheel 0.45.1) Handling setuptools_scm[toml] from build-system.requires Requirement satisfied: setuptools_scm[toml] (installed: setuptools_scm 8.3.1) (extras are currently not checked) /usr/lib/python3.14/site-packages/setuptools/dist.py:759: SetuptoolsDeprecationWarning: License classifiers are deprecated. !! ******************************************************************************** Please consider removing the following classifiers in favor of a SPDX license expression: License :: OSI Approved :: MIT License See https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license for details. ******************************************************************************** !! self._finalize_license_expression() Handling setuptools from get_requires_for_build_wheel Requirement satisfied: setuptools (installed: setuptools 78.1.1) Handling setuptools_scm[toml] from get_requires_for_build_wheel Requirement satisfied: setuptools_scm[toml] (installed: setuptools_scm 8.3.1) (extras are currently not checked) Handling tox-current-env >= 0.0.16 from tox itself Requirement satisfied: tox-current-env >= 0.0.16 (installed: tox-current-env 0.0.16) py314: OK (0.00 seconds) congratulations :) (0.06 seconds) Handling tox from tox --print-deps-only: py314 Requirement satisfied: tox (installed: tox 4.26.0) py314: OK (0.00 seconds) congratulations :) (0.06 seconds) running dist_info writing executing.egg-info/PKG-INFO writing dependency_links to executing.egg-info/dependency_links.txt writing requirements to executing.egg-info/requires.txt writing top-level names to executing.egg-info/top_level.txt reading manifest file 'executing.egg-info/SOURCES.txt' reading manifest template 'MANIFEST.in' adding license file 'LICENSE.txt' writing manifest file 'executing.egg-info/SOURCES.txt' creating '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/executing-2.2.0.dist-info' /usr/lib/python3.14/site-packages/setuptools/_distutils/cmd.py:135: SetuptoolsDeprecationWarning: bdist_wheel.universal is deprecated !! ******************************************************************************** With Python 2.7 end-of-life, support for building universal wheels (i.e., wheels that support both Python 2 and Python 3) is being obviated. Please discontinue using this option, or if you still need it, file an issue with pypa/setuptools describing your use case. By 2025-Aug-30, you need to update your project and remove deprecated calls or your builds will no longer be supported. ******************************************************************************** !! self.finalize_options() Handling asttokens>=2.1.0; extra == "tests" from hook generated metadata: Requires-Dist (executing) Requirement not satisfied: asttokens>=2.1.0; extra == "tests" Handling ipython; extra == "tests" from hook generated metadata: Requires-Dist (executing) Requirement not satisfied: ipython; extra == "tests" Handling pytest; extra == "tests" from hook generated metadata: Requires-Dist (executing) Requirement not satisfied: pytest; extra == "tests" Handling littleutils; extra == "tests" from hook generated metadata: Requires-Dist (executing) Requirement not satisfied: littleutils; extra == "tests" Handling rich; python_version >= "3.11" and extra == "tests" from hook generated metadata: Requires-Dist (executing) Requirement not satisfied: rich; python_version >= "3.11" and extra == "tests" + cat /builddir/build/BUILD/python-executing-2.2.0-build/python-executing-2.2.0-2.fc43.x86_64-pyproject-buildrequires + rm -rfv executing-2.2.0.dist-info/ removed 'executing-2.2.0.dist-info/top_level.txt' removed 'executing-2.2.0.dist-info/METADATA' removed 'executing-2.2.0.dist-info/licenses/LICENSE.txt' removed directory 'executing-2.2.0.dist-info/licenses' removed directory 'executing-2.2.0.dist-info/' + RPM_EC=0 ++ jobs -p + exit 0 Wrote: /builddir/build/SRPMS/python-executing-2.2.0-2.fc43.buildreqs.nosrc.rpm INFO: Going to install missing dynamic buildrequires Updating and loading repositories: fedora 100% | 751.0 KiB/s | 24.8 KiB | 00m00s Copr repository 100% | 96.1 KiB/s | 1.5 KiB | 00m00s Additional repo http_kojipkgs_fedorapr 100% | 225.2 KiB/s | 3.8 KiB | 00m00s Repositories loaded. Package "pyproject-rpm-macros-1.18.1-1.fc43.noarch" is already installed. Package "python3-devel-3.14.0~b1-1.fc43.x86_64" is already installed. Package "python3-packaging-25.0-1.fc43.noarch" is already installed. Package "python3-pip-24.3.1-2.fc42.noarch" is already installed. Package "python3-setuptools-78.1.1-5.fc43.noarch" is already installed. Package "python3-setuptools_scm-8.3.1-2.fc43.noarch" is already installed. Package "python3-setuptools_scm+toml-8.3.1-2.fc43.noarch" is already installed. Package "tox-4.26.0-2.fc43~bootstrap.noarch" is already installed. Package "python3-tox-current-env-0.0.16-1.fc43.noarch" is already installed. Package "python3-wheel-1:0.45.1-13.fc43.noarch" is already installed. Package Arch Version Repository Size Installing: python3-asttokens noarch 3.0.0-1.fc43 copr_base 199.3 KiB python3-ipython noarch 8.31.0-3.fc43 copr_base 4.7 MiB python3-littleutils noarch 0.2.4-2.fc43 copr_base 53.9 KiB python3-pytest noarch 8.3.4-3.fc43 copr_base 4.1 MiB python3-rich noarch 13.9.4-3.fc42 copr_base 2.7 MiB Installing dependencies: python3-decorator noarch 5.2.1-1.fc43 copr_base 81.8 KiB python3-executing noarch 2.1.0^20240916git3f11fdc-2.fc42 copr_base 270.5 KiB python3-iniconfig noarch 1.1.1-25.fc43 copr_base 21.0 KiB python3-jedi noarch 0.19.2-1.fc43 copr_base 5.7 MiB python3-markdown-it-py noarch 3.0.0-8.fc43 copr_base 541.6 KiB python3-matplotlib-inline noarch 0.1.7-5.fc43 copr_base 39.8 KiB python3-mdurl noarch 0.1.2-9.fc43 copr_base 44.0 KiB python3-parso noarch 0.8.4-6.fc43 copr_base 929.3 KiB python3-pexpect noarch 4.9.0-9.fc43 copr_base 624.7 KiB python3-prompt-toolkit noarch 3.0.41-6.fc43 copr_base 4.1 MiB python3-ptyprocess noarch 0.7.0-10.fc43 copr_base 80.5 KiB python3-pure-eval noarch 0.2.3-2.fc43 copr_base 106.0 KiB python3-pygments noarch 2.19.1-1.fc43 copr_base 11.3 MiB python3-stack-data noarch 0.6.3-11.fc42 copr_base 220.0 KiB python3-traitlets noarch 5.14.3-4.fc43 copr_base 1.0 MiB python3-wcwidth noarch 0.2.13-6.fc43 copr_base 560.4 KiB Transaction Summary: Installing: 21 packages Total size of inbound packages is 8 MiB. Need to download 5 MiB. After this operation, 37 MiB extra will be used (install 37 MiB, remove 0 B). [ 1/21] python3-pytest-0:8.3.4-3.fc43.n 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 2/21] python3-pygments-0:2.19.1-1.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 3/21] python3-iniconfig-0:1.1.1-25.fc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 4/21] python3-littleutils-0:0.2.4-2.f 100% | 2.3 MiB/s | 27.9 KiB | 00m00s [ 5/21] python3-asttokens-0:3.0.0-1.fc4 100% | 4.6 MiB/s | 56.0 KiB | 00m00s [ 6/21] python3-ipython-0:8.31.0-3.fc43 100% | 76.0 MiB/s | 1.1 MiB | 00m00s [ 7/21] python3-decorator-0:5.2.1-1.fc4 100% | 15.8 MiB/s | 32.3 KiB | 00m00s [ 8/21] python3-rich-0:13.9.4-3.fc42.no 100% | 112.8 MiB/s | 577.8 KiB | 00m00s [ 9/21] python3-matplotlib-inline-0:0.1 100% | 8.1 MiB/s | 24.7 KiB | 00m00s [10/21] python3-jedi-0:0.19.2-1.fc43.no 100% | 139.0 MiB/s | 1.3 MiB | 00m00s [11/21] python3-pexpect-0:4.9.0-9.fc43. 100% | 26.5 MiB/s | 162.6 KiB | 00m00s [12/21] python3-prompt-toolkit-0:3.0.41 100% | 73.2 MiB/s | 824.2 KiB | 00m00s [13/21] python3-stack-data-0:0.6.3-11.f 100% | 9.9 MiB/s | 60.9 KiB | 00m00s [14/21] python3-traitlets-0:5.14.3-4.fc 100% | 34.5 MiB/s | 212.2 KiB | 00m00s [15/21] python3-markdown-it-py-0:3.0.0- 100% | 42.3 MiB/s | 173.1 KiB | 00m00s [16/21] python3-ptyprocess-0:0.7.0-10.f 100% | 18.1 MiB/s | 37.0 KiB | 00m00s [17/21] python3-parso-0:0.8.4-6.fc43.no 100% | 49.9 MiB/s | 204.6 KiB | 00m00s [18/21] python3-wcwidth-0:0.2.13-6.fc43 100% | 47.1 MiB/s | 48.3 KiB | 00m00s [19/21] python3-pure-eval-0:0.2.3-2.fc4 100% | 35.3 MiB/s | 36.2 KiB | 00m00s [20/21] python3-executing-0:2.1.0^20240 100% | 32.9 MiB/s | 67.5 KiB | 00m00s [21/21] python3-mdurl-0:0.1.2-9.fc43.no 100% | 26.6 MiB/s | 27.2 KiB | 00m00s -------------------------------------------------------------------------------- [21/21] Total 100% | 120.7 MiB/s | 4.8 MiB | 00m00s Running transaction [ 1/23] Verify package files 100% | 656.0 B/s | 21.0 B | 00m00s [ 2/23] Prepare transaction 100% | 677.0 B/s | 21.0 B | 00m00s [ 3/23] Installing python3-traitlets-0: 100% | 173.9 MiB/s | 1.0 MiB | 00m00s [ 4/23] Installing python3-pygments-0:2 100% | 216.7 MiB/s | 11.5 MiB | 00m00s [ 5/23] Installing python3-matplotlib-i 100% | 43.1 MiB/s | 44.1 KiB | 00m00s [ 6/23] Installing python3-mdurl-0:0.1. 100% | 48.3 MiB/s | 49.4 KiB | 00m00s [ 7/23] Installing python3-markdown-it- 100% | 35.7 MiB/s | 585.7 KiB | 00m00s [ 8/23] Installing python3-pure-eval-0: 100% | 108.3 MiB/s | 110.9 KiB | 00m00s [ 9/23] Installing python3-executing-0: 100% | 269.1 MiB/s | 275.6 KiB | 00m00s [10/23] Installing python3-wcwidth-0:0. 100% | 276.4 MiB/s | 566.1 KiB | 00m00s [11/23] Installing python3-prompt-toolk 100% | 246.6 MiB/s | 4.2 MiB | 00m00s [12/23] Installing python3-ptyprocess-0 100% | 82.8 MiB/s | 84.8 KiB | 00m00s [13/23] Installing python3-pexpect-0:4. 100% | 209.4 MiB/s | 643.2 KiB | 00m00s [14/23] Installing python3-parso-0:0.8. 100% | 153.8 MiB/s | 945.2 KiB | 00m00s [15/23] Installing python3-jedi-0:0.19. 100% | 102.2 MiB/s | 6.1 MiB | 00m00s [16/23] Installing python3-iniconfig-0: 100% | 23.6 MiB/s | 24.2 KiB | 00m00s [17/23] Installing python3-decorator-0: 100% | 82.5 MiB/s | 84.5 KiB | 00m00s [18/23] Installing python3-asttokens-0: 100% | 100.2 MiB/s | 205.3 KiB | 00m00s [19/23] Installing python3-stack-data-0 100% | 110.0 MiB/s | 225.3 KiB | 00m00s [20/23] Installing python3-ipython-0:8. 100% | 159.2 MiB/s | 4.8 MiB | 00m00s [21/23] Installing python3-pytest-0:8.3 100% | 178.8 MiB/s | 4.1 MiB | 00m00s [22/23] Installing python3-rich-0:13.9. 100% | 310.1 MiB/s | 2.8 MiB | 00m00s [23/23] Installing python3-littleutils- 100% | 1.0 MiB/s | 56.7 KiB | 00m00s Warning: skipped OpenPGP checks for 21 packages from repository: copr_base Complete! Building target platforms: x86_64 Building for target x86_64 setting SOURCE_DATE_EPOCH=1737849600 Executing(%generate_buildrequires): /bin/sh -e /var/tmp/rpm-tmp.wLPSzR + umask 022 + cd /builddir/build/BUILD/python-executing-2.2.0-build + cd executing-2.2.0 + export SETUPTOOLS_SCM_PRETEND_VERSION=2.2.0 + SETUPTOOLS_SCM_PRETEND_VERSION=2.2.0 + echo pyproject-rpm-macros + echo python3-devel + echo 'python3dist(packaging)' + echo 'python3dist(pip) >= 19' + '[' -f pyproject.toml ']' + echo '(python3dist(tomli) if python3-devel < 3.11)' + rm -rfv '*.dist-info/' + '[' -f /usr/bin/python3 ']' + mkdir -p /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/.pyproject-builddir + echo -n + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + VALAFLAGS=-g + RUSTFLAGS='-Copt-level=3 -Cdebuginfo=2 -Ccodegen-units=1 -Cstrip=none -Cforce-frame-pointers=yes --cap-lints=warn' + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,pack-relative-relocs -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-hardened-ld-errors -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 ' + LT_SYS_LIBRARY_PATH=/usr/lib64: + CC=gcc + CXX=g++ + TMPDIR=/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/.pyproject-builddir + RPM_TOXENV=py314 + FEDORA=43 + HOSTNAME=rpmbuild + /usr/bin/python3 -Bs /usr/lib/rpm/redhat/pyproject_buildrequires.py --generate-extras --python3_pkgversion 3 --wheeldir /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/pyproject-wheeldir --output /builddir/build/BUILD/python-executing-2.2.0-build/python-executing-2.2.0-2.fc43.x86_64-pyproject-buildrequires -t Handling setuptools from build-system.requires Requirement satisfied: setuptools (installed: setuptools 78.1.1) Handling wheel from build-system.requires Requirement satisfied: wheel (installed: wheel 0.45.1) Handling setuptools_scm[toml] from build-system.requires Requirement satisfied: setuptools_scm[toml] (installed: setuptools_scm 8.3.1) (extras are currently not checked) /usr/lib/python3.14/site-packages/setuptools/dist.py:759: SetuptoolsDeprecationWarning: License classifiers are deprecated. !! ******************************************************************************** Please consider removing the following classifiers in favor of a SPDX license expression: License :: OSI Approved :: MIT License See https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license for details. ******************************************************************************** !! self._finalize_license_expression() Handling setuptools from get_requires_for_build_wheel Requirement satisfied: setuptools (installed: setuptools 78.1.1) Handling setuptools_scm[toml] from get_requires_for_build_wheel Requirement satisfied: setuptools_scm[toml] (installed: setuptools_scm 8.3.1) (extras are currently not checked) Handling tox-current-env >= 0.0.16 from tox itself Requirement satisfied: tox-current-env >= 0.0.16 (installed: tox-current-env 0.0.16) py314: OK (0.00 seconds) congratulations :) (0.06 seconds) Handling tox from tox --print-deps-only: py314 Requirement satisfied: tox (installed: tox 4.26.0) py314: OK (0.00 seconds) congratulations :) (0.06 seconds) running dist_info writing executing.egg-info/PKG-INFO writing dependency_links to executing.egg-info/dependency_links.txt writing requirements to executing.egg-info/requires.txt writing top-level names to executing.egg-info/top_level.txt reading manifest file 'executing.egg-info/SOURCES.txt' reading manifest template 'MANIFEST.in' adding license file 'LICENSE.txt' writing manifest file 'executing.egg-info/SOURCES.txt' creating '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/executing-2.2.0.dist-info' /usr/lib/python3.14/site-packages/setuptools/_distutils/cmd.py:135: SetuptoolsDeprecationWarning: bdist_wheel.universal is deprecated !! ******************************************************************************** With Python 2.7 end-of-life, support for building universal wheels (i.e., wheels that support both Python 2 and Python 3) is being obviated. Please discontinue using this option, or if you still need it, file an issue with pypa/setuptools describing your use case. By 2025-Aug-30, you need to update your project and remove deprecated calls or your builds will no longer be supported. ******************************************************************************** !! self.finalize_options() Handling asttokens>=2.1.0; extra == "tests" from hook generated metadata: Requires-Dist (executing) Requirement satisfied: asttokens>=2.1.0; extra == "tests" (installed: asttokens 3.0.0) Handling ipython; extra == "tests" from hook generated metadata: Requires-Dist (executing) Requirement satisfied: ipython; extra == "tests" (installed: ipython 8.31.0) Handling pytest; extra == "tests" from hook generated metadata: Requires-Dist (executing) Requirement satisfied: pytest; extra == "tests" (installed: pytest 8.3.4) Handling littleutils; extra == "tests" from hook generated metadata: Requires-Dist (executing) Requirement satisfied: littleutils; extra == "tests" (installed: littleutils 0.2.4) Handling rich; python_version >= "3.11" and extra == "tests" from hook generated metadata: Requires-Dist (executing) Requirement satisfied: rich; python_version >= "3.11" and extra == "tests" (installed: rich 13.9.4) + cat /builddir/build/BUILD/python-executing-2.2.0-build/python-executing-2.2.0-2.fc43.x86_64-pyproject-buildrequires + rm -rfv executing-2.2.0.dist-info/ removed 'executing-2.2.0.dist-info/top_level.txt' removed 'executing-2.2.0.dist-info/METADATA' removed 'executing-2.2.0.dist-info/licenses/LICENSE.txt' removed directory 'executing-2.2.0.dist-info/licenses' removed directory 'executing-2.2.0.dist-info/' + RPM_EC=0 ++ jobs -p + exit 0 Wrote: /builddir/build/SRPMS/python-executing-2.2.0-2.fc43.buildreqs.nosrc.rpm INFO: Going to install missing dynamic buildrequires Updating and loading repositories: fedora 100% | 272.3 KiB/s | 24.8 KiB | 00m00s Copr repository 100% | 22.0 KiB/s | 1.5 KiB | 00m00s Additional repo http_kojipkgs_fedorapr 100% | 201.5 KiB/s | 3.8 KiB | 00m00s Repositories loaded. Package "pyproject-rpm-macros-1.18.1-1.fc43.noarch" is already installed. Package "python3-devel-3.14.0~b1-1.fc43.x86_64" is already installed. Package "python3-asttokens-3.0.0-1.fc43.noarch" is already installed. Package "python3-ipython-8.31.0-3.fc43.noarch" is already installed. Package "python3-littleutils-0.2.4-2.fc43.noarch" is already installed. Package "python3-packaging-25.0-1.fc43.noarch" is already installed. Package "python3-pip-24.3.1-2.fc42.noarch" is already installed. Package "python3-pytest-8.3.4-3.fc43.noarch" is already installed. Package "python3-rich-13.9.4-3.fc42.noarch" is already installed. Package "python3-setuptools-78.1.1-5.fc43.noarch" is already installed. Package "python3-setuptools_scm-8.3.1-2.fc43.noarch" is already installed. Package "python3-setuptools_scm+toml-8.3.1-2.fc43.noarch" is already installed. Package "tox-4.26.0-2.fc43~bootstrap.noarch" is already installed. Package "python3-tox-current-env-0.0.16-1.fc43.noarch" is already installed. Package "python3-wheel-1:0.45.1-13.fc43.noarch" is already installed. Nothing to do. Building target platforms: x86_64 Building for target x86_64 setting SOURCE_DATE_EPOCH=1737849600 Executing(%generate_buildrequires): /bin/sh -e /var/tmp/rpm-tmp.6JZJOi + umask 022 + cd /builddir/build/BUILD/python-executing-2.2.0-build + cd executing-2.2.0 + export SETUPTOOLS_SCM_PRETEND_VERSION=2.2.0 + SETUPTOOLS_SCM_PRETEND_VERSION=2.2.0 + echo pyproject-rpm-macros + echo python3-devel + echo 'python3dist(packaging)' + echo 'python3dist(pip) >= 19' + '[' -f pyproject.toml ']' + echo '(python3dist(tomli) if python3-devel < 3.11)' + rm -rfv '*.dist-info/' + '[' -f /usr/bin/python3 ']' + mkdir -p /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/.pyproject-builddir + echo -n + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + VALAFLAGS=-g + RUSTFLAGS='-Copt-level=3 -Cdebuginfo=2 -Ccodegen-units=1 -Cstrip=none -Cforce-frame-pointers=yes --cap-lints=warn' + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,pack-relative-relocs -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-hardened-ld-errors -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 ' + LT_SYS_LIBRARY_PATH=/usr/lib64: + CC=gcc + CXX=g++ + TMPDIR=/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/.pyproject-builddir + RPM_TOXENV=py314 + FEDORA=43 + HOSTNAME=rpmbuild + /usr/bin/python3 -Bs /usr/lib/rpm/redhat/pyproject_buildrequires.py --generate-extras --python3_pkgversion 3 --wheeldir /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/pyproject-wheeldir --output /builddir/build/BUILD/python-executing-2.2.0-build/python-executing-2.2.0-2.fc43.x86_64-pyproject-buildrequires -t Handling setuptools from build-system.requires Requirement satisfied: setuptools (installed: setuptools 78.1.1) Handling wheel from build-system.requires Requirement satisfied: wheel (installed: wheel 0.45.1) Handling setuptools_scm[toml] from build-system.requires Requirement satisfied: setuptools_scm[toml] (installed: setuptools_scm 8.3.1) (extras are currently not checked) /usr/lib/python3.14/site-packages/setuptools/dist.py:759: SetuptoolsDeprecationWarning: License classifiers are deprecated. !! ******************************************************************************** Please consider removing the following classifiers in favor of a SPDX license expression: License :: OSI Approved :: MIT License See https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license for details. ******************************************************************************** !! self._finalize_license_expression() Handling setuptools from get_requires_for_build_wheel Requirement satisfied: setuptools (installed: setuptools 78.1.1) Handling setuptools_scm[toml] from get_requires_for_build_wheel Requirement satisfied: setuptools_scm[toml] (installed: setuptools_scm 8.3.1) (extras are currently not checked) Handling tox-current-env >= 0.0.16 from tox itself Requirement satisfied: tox-current-env >= 0.0.16 (installed: tox-current-env 0.0.16) py314: OK (0.00 seconds) congratulations :) (0.06 seconds) Handling tox from tox --print-deps-only: py314 Requirement satisfied: tox (installed: tox 4.26.0) py314: OK (0.00 seconds) congratulations :) (0.06 seconds) running dist_info writing executing.egg-info/PKG-INFO writing dependency_links to executing.egg-info/dependency_links.txt writing requirements to executing.egg-info/requires.txt writing top-level names to executing.egg-info/top_level.txt reading manifest file 'executing.egg-info/SOURCES.txt' reading manifest template 'MANIFEST.in' adding license file 'LICENSE.txt' writing manifest file 'executing.egg-info/SOURCES.txt' creating '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/executing-2.2.0.dist-info' /usr/lib/python3.14/site-packages/setuptools/_distutils/cmd.py:135: SetuptoolsDeprecationWarning: bdist_wheel.universal is deprecated !! ******************************************************************************** With Python 2.7 end-of-life, support for building universal wheels (i.e., wheels that support both Python 2 and Python 3) is being obviated. Please discontinue using this option, or if you still need it, file an issue with pypa/setuptools describing your use case. By 2025-Aug-30, you need to update your project and remove deprecated calls or your builds will no longer be supported. ******************************************************************************** !! self.finalize_options() Handling asttokens>=2.1.0; extra == "tests" from hook generated metadata: Requires-Dist (executing) Requirement satisfied: asttokens>=2.1.0; extra == "tests" (installed: asttokens 3.0.0) Handling ipython; extra == "tests" from hook generated metadata: Requires-Dist (executing) Requirement satisfied: ipython; extra == "tests" (installed: ipython 8.31.0) Handling pytest; extra == "tests" from hook generated metadata: Requires-Dist (executing) Requirement satisfied: pytest; extra == "tests" (installed: pytest 8.3.4) Handling littleutils; extra == "tests" from hook generated metadata: Requires-Dist (executing) Requirement satisfied: littleutils; extra == "tests" (installed: littleutils 0.2.4) Handling rich; python_version >= "3.11" and extra == "tests" from hook generated metadata: Requires-Dist (executing) Requirement satisfied: rich; python_version >= "3.11" and extra == "tests" (installed: rich 13.9.4) + cat /builddir/build/BUILD/python-executing-2.2.0-build/python-executing-2.2.0-2.fc43.x86_64-pyproject-buildrequires + rm -rfv executing-2.2.0.dist-info/ removed 'executing-2.2.0.dist-info/top_level.txt' removed 'executing-2.2.0.dist-info/METADATA' removed 'executing-2.2.0.dist-info/licenses/LICENSE.txt' removed directory 'executing-2.2.0.dist-info/licenses' removed directory 'executing-2.2.0.dist-info/' + RPM_EC=0 ++ jobs -p + exit 0 Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.YSjZHg + umask 022 + cd /builddir/build/BUILD/python-executing-2.2.0-build + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + export CFLAGS + CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + export CXXFLAGS + FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + export FFLAGS + FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + export FCFLAGS + VALAFLAGS=-g + export VALAFLAGS + RUSTFLAGS='-Copt-level=3 -Cdebuginfo=2 -Ccodegen-units=1 -Cstrip=none -Cforce-frame-pointers=yes -Clink-arg=-specs=/usr/lib/rpm/redhat/redhat-package-notes --cap-lints=warn' + export RUSTFLAGS + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,pack-relative-relocs -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-hardened-ld-errors -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -specs=/usr/lib/rpm/redhat/redhat-package-notes ' + export LDFLAGS + LT_SYS_LIBRARY_PATH=/usr/lib64: + export LT_SYS_LIBRARY_PATH + CC=gcc + export CC + CXX=g++ + export CXX + cd executing-2.2.0 + export SETUPTOOLS_SCM_PRETEND_VERSION=2.2.0 + SETUPTOOLS_SCM_PRETEND_VERSION=2.2.0 + mkdir -p /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/.pyproject-builddir + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + VALAFLAGS=-g + RUSTFLAGS='-Copt-level=3 -Cdebuginfo=2 -Ccodegen-units=1 -Cstrip=none -Cforce-frame-pointers=yes -Clink-arg=-specs=/usr/lib/rpm/redhat/redhat-package-notes --cap-lints=warn' + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,pack-relative-relocs -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-hardened-ld-errors -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -specs=/usr/lib/rpm/redhat/redhat-package-notes ' + LT_SYS_LIBRARY_PATH=/usr/lib64: + CC=gcc + CXX=g++ + TMPDIR=/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/.pyproject-builddir + /usr/bin/python3 -Bs /usr/lib/rpm/redhat/pyproject_wheel.py /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/pyproject-wheeldir Processing /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0 Preparing metadata (pyproject.toml): started Running command Preparing metadata (pyproject.toml) /usr/lib/python3.14/site-packages/setuptools/dist.py:759: SetuptoolsDeprecationWarning: License classifiers are deprecated. !! ******************************************************************************** Please consider removing the following classifiers in favor of a SPDX license expression: License :: OSI Approved :: MIT License See https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license for details. ******************************************************************************** !! self._finalize_license_expression() running dist_info creating /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/.pyproject-builddir/pip-modern-metadata-_v0hca_j/executing.egg-info writing /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/.pyproject-builddir/pip-modern-metadata-_v0hca_j/executing.egg-info/PKG-INFO writing dependency_links to /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/.pyproject-builddir/pip-modern-metadata-_v0hca_j/executing.egg-info/dependency_links.txt writing requirements to /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/.pyproject-builddir/pip-modern-metadata-_v0hca_j/executing.egg-info/requires.txt writing top-level names to /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/.pyproject-builddir/pip-modern-metadata-_v0hca_j/executing.egg-info/top_level.txt writing manifest file '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/.pyproject-builddir/pip-modern-metadata-_v0hca_j/executing.egg-info/SOURCES.txt' reading manifest file '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/.pyproject-builddir/pip-modern-metadata-_v0hca_j/executing.egg-info/SOURCES.txt' reading manifest template 'MANIFEST.in' adding license file 'LICENSE.txt' writing manifest file '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/.pyproject-builddir/pip-modern-metadata-_v0hca_j/executing.egg-info/SOURCES.txt' creating '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/.pyproject-builddir/pip-modern-metadata-_v0hca_j/executing-2.2.0.dist-info' /usr/lib/python3.14/site-packages/setuptools/_distutils/cmd.py:135: SetuptoolsDeprecationWarning: bdist_wheel.universal is deprecated !! ******************************************************************************** With Python 2.7 end-of-life, support for building universal wheels (i.e., wheels that support both Python 2 and Python 3) is being obviated. Please discontinue using this option, or if you still need it, file an issue with pypa/setuptools describing your use case. By 2025-Aug-30, you need to update your project and remove deprecated calls or your builds will no longer be supported. ******************************************************************************** !! self.finalize_options() Preparing metadata (pyproject.toml): finished with status 'done' Building wheels for collected packages: executing Building wheel for executing (pyproject.toml): started Running command Building wheel for executing (pyproject.toml) /usr/lib/python3.14/site-packages/setuptools/dist.py:759: SetuptoolsDeprecationWarning: License classifiers are deprecated. !! ******************************************************************************** Please consider removing the following classifiers in favor of a SPDX license expression: License :: OSI Approved :: MIT License See https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license for details. ******************************************************************************** !! self._finalize_license_expression() running bdist_wheel /usr/lib/python3.14/site-packages/setuptools/_distutils/cmd.py:135: SetuptoolsDeprecationWarning: bdist_wheel.universal is deprecated !! ******************************************************************************** With Python 2.7 end-of-life, support for building universal wheels (i.e., wheels that support both Python 2 and Python 3) is being obviated. Please discontinue using this option, or if you still need it, file an issue with pypa/setuptools describing your use case. By 2025-Aug-30, you need to update your project and remove deprecated calls or your builds will no longer be supported. ******************************************************************************** !! self.finalize_options() running build running build_py creating build/lib/executing copying executing/__init__.py -> build/lib/executing copying executing/_exceptions.py -> build/lib/executing copying executing/_position_node_finder.py -> build/lib/executing copying executing/_pytest_utils.py -> build/lib/executing copying executing/executing.py -> build/lib/executing copying executing/version.py -> build/lib/executing running egg_info writing executing.egg-info/PKG-INFO writing dependency_links to executing.egg-info/dependency_links.txt writing requirements to executing.egg-info/requires.txt writing top-level names to executing.egg-info/top_level.txt reading manifest file 'executing.egg-info/SOURCES.txt' reading manifest template 'MANIFEST.in' adding license file 'LICENSE.txt' writing manifest file 'executing.egg-info/SOURCES.txt' copying executing/py.typed -> build/lib/executing installing to build/bdist.linux-x86_64/wheel running install running install_lib creating build/bdist.linux-x86_64/wheel creating build/bdist.linux-x86_64/wheel/executing copying build/lib/executing/__init__.py -> build/bdist.linux-x86_64/wheel/./executing copying build/lib/executing/_exceptions.py -> build/bdist.linux-x86_64/wheel/./executing copying build/lib/executing/_position_node_finder.py -> build/bdist.linux-x86_64/wheel/./executing copying build/lib/executing/_pytest_utils.py -> build/bdist.linux-x86_64/wheel/./executing copying build/lib/executing/executing.py -> build/bdist.linux-x86_64/wheel/./executing copying build/lib/executing/version.py -> build/bdist.linux-x86_64/wheel/./executing copying build/lib/executing/py.typed -> build/bdist.linux-x86_64/wheel/./executing running install_egg_info Copying executing.egg-info to build/bdist.linux-x86_64/wheel/./executing-2.2.0-py3.14.egg-info running install_scripts creating build/bdist.linux-x86_64/wheel/executing-2.2.0.dist-info/WHEEL creating '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/.pyproject-builddir/pip-wheel-3a1r5er7/.tmp-x2_d0k1u/executing-2.2.0-py2.py3-none-any.whl' and adding 'build/bdist.linux-x86_64/wheel' to it adding 'executing/__init__.py' adding 'executing/_exceptions.py' adding 'executing/_position_node_finder.py' adding 'executing/_pytest_utils.py' adding 'executing/executing.py' adding 'executing/py.typed' adding 'executing/version.py' adding 'executing-2.2.0.dist-info/licenses/LICENSE.txt' adding 'executing-2.2.0.dist-info/METADATA' adding 'executing-2.2.0.dist-info/WHEEL' adding 'executing-2.2.0.dist-info/top_level.txt' adding 'executing-2.2.0.dist-info/RECORD' removing build/bdist.linux-x86_64/wheel Building wheel for executing (pyproject.toml): finished with status 'done' Created wheel for executing: filename=executing-2.2.0-py2.py3-none-any.whl size=26720 sha256=33a68ba61c25ea2a60b690e2ff98cbe15bf1b0a6f1dc341d2ab4c8a7d2587f48 Stored in directory: /builddir/.cache/pip/wheels/68/ac/e7/21483b4236b0d3ebdf6938a886a4f763d9d66dd963ae932ed9 Successfully built executing + RPM_EC=0 ++ jobs -p + exit 0 Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.UChPXM + umask 022 + cd /builddir/build/BUILD/python-executing-2.2.0-build + '[' /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT '!=' / ']' + rm -rf /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT ++ dirname /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT + mkdir -p /builddir/build/BUILD/python-executing-2.2.0-build + mkdir /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + export CFLAGS + CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + export CXXFLAGS + FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + export FFLAGS + FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + export FCFLAGS + VALAFLAGS=-g + export VALAFLAGS + RUSTFLAGS='-Copt-level=3 -Cdebuginfo=2 -Ccodegen-units=1 -Cstrip=none -Cforce-frame-pointers=yes -Clink-arg=-specs=/usr/lib/rpm/redhat/redhat-package-notes --cap-lints=warn' + export RUSTFLAGS + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,pack-relative-relocs -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-hardened-ld-errors -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -specs=/usr/lib/rpm/redhat/redhat-package-notes ' + export LDFLAGS + LT_SYS_LIBRARY_PATH=/usr/lib64: + export LT_SYS_LIBRARY_PATH + CC=gcc + export CC + CXX=g++ + export CXX + cd executing-2.2.0 ++ ls /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/pyproject-wheeldir/executing-2.2.0-py2.py3-none-any.whl ++ xargs basename --multiple ++ sed -E 's/([^-]+)-([^-]+)-.+\.whl/\1==\2/' + specifier=executing==2.2.0 + '[' -z executing==2.2.0 ']' + TMPDIR=/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/.pyproject-builddir + /usr/bin/python3 -m pip install --root /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT --prefix /usr --no-deps --disable-pip-version-check --progress-bar off --verbose --ignore-installed --no-warn-script-location --no-index --no-cache-dir --find-links /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/pyproject-wheeldir executing==2.2.0 Using pip 24.3.1 from /usr/lib/python3.14/site-packages/pip (python 3.14) Looking in links: /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/pyproject-wheeldir Processing ./pyproject-wheeldir/executing-2.2.0-py2.py3-none-any.whl Installing collected packages: executing Successfully installed executing-2.2.0 + '[' -d /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/bin ']' + rm -f /builddir/build/BUILD/python-executing-2.2.0-build/python-executing-2.2.0-2.fc43.x86_64-pyproject-ghost-distinfo + site_dirs=() + '[' -d /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/lib/python3.14/site-packages ']' + site_dirs+=("/usr/lib/python3.14/site-packages") + '[' /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/lib64/python3.14/site-packages '!=' /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/lib/python3.14/site-packages ']' + '[' -d /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/lib64/python3.14/site-packages ']' + for site_dir in ${site_dirs[@]} + for distinfo in /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT$site_dir/*.dist-info + echo '%ghost /usr/lib/python3.14/site-packages/executing-2.2.0.dist-info' + sed -i s/pip/rpm/ /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/lib/python3.14/site-packages/executing-2.2.0.dist-info/INSTALLER + PYTHONPATH=/usr/lib/rpm/redhat + /usr/bin/python3 -B /usr/lib/rpm/redhat/pyproject_preprocess_record.py --buildroot /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT --record /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/lib/python3.14/site-packages/executing-2.2.0.dist-info/RECORD --output /builddir/build/BUILD/python-executing-2.2.0-build/python-executing-2.2.0-2.fc43.x86_64-pyproject-record + rm -fv /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/lib/python3.14/site-packages/executing-2.2.0.dist-info/RECORD removed '/builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/lib/python3.14/site-packages/executing-2.2.0.dist-info/RECORD' + rm -fv /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/lib/python3.14/site-packages/executing-2.2.0.dist-info/REQUESTED removed '/builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/lib/python3.14/site-packages/executing-2.2.0.dist-info/REQUESTED' ++ wc -l /builddir/build/BUILD/python-executing-2.2.0-build/python-executing-2.2.0-2.fc43.x86_64-pyproject-ghost-distinfo ++ cut -f1 '-d ' + lines=1 + '[' 1 -ne 1 ']' + RPM_FILES_ESCAPE=4.19 + /usr/bin/python3 /usr/lib/rpm/redhat/pyproject_save_files.py --output-files /builddir/build/BUILD/python-executing-2.2.0-build/python-executing-2.2.0-2.fc43.x86_64-pyproject-files --output-modules /builddir/build/BUILD/python-executing-2.2.0-build/python-executing-2.2.0-2.fc43.x86_64-pyproject-modules --buildroot /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT --sitelib /usr/lib/python3.14/site-packages --sitearch /usr/lib64/python3.14/site-packages --python-version 3.14 --pyproject-record /builddir/build/BUILD/python-executing-2.2.0-build/python-executing-2.2.0-2.fc43.x86_64-pyproject-record --prefix /usr executing + /usr/lib/rpm/check-buildroot + /usr/lib/rpm/redhat/brp-ldconfig + /usr/lib/rpm/brp-compress + /usr/lib/rpm/brp-strip /usr/bin/strip + /usr/lib/rpm/brp-strip-comment-note /usr/bin/strip /usr/bin/objdump + /usr/lib/rpm/redhat/brp-strip-lto /usr/bin/strip + /usr/lib/rpm/brp-strip-static-archive /usr/bin/strip + /usr/lib/rpm/check-rpaths + /usr/lib/rpm/redhat/brp-mangle-shebangs + /usr/lib/rpm/brp-remove-la-files + /usr/lib/rpm/redhat/brp-python-rpm-in-distinfo + env /usr/lib/rpm/redhat/brp-python-bytecompile '' 1 0 -j4 Bytecompiling .py files below /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/lib/python3.14 using python3.14 + /usr/lib/rpm/redhat/brp-python-hardlink + /usr/bin/add-determinism --brp -j4 /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/lib/python3.14/site-packages/executing/__pycache__/__init__.cpython-314.pyc: rewriting with normalized contents /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/lib/python3.14/site-packages/executing/__pycache__/_pytest_utils.cpython-314.pyc: rewriting with normalized contents /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/lib/python3.14/site-packages/executing/__pycache__/_exceptions.cpython-314.pyc: rewriting with normalized contents /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/lib/python3.14/site-packages/executing/__pycache__/version.cpython-314.pyc: rewriting with normalized contents /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/lib/python3.14/site-packages/executing/__pycache__/_position_node_finder.cpython-314.pyc: replacing with normalized version /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/lib/python3.14/site-packages/executing/__pycache__/_position_node_finder.cpython-314.opt-1.pyc: replacing with normalized version /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/lib/python3.14/site-packages/executing/__pycache__/executing.cpython-314.opt-1.pyc: replacing with normalized version /builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/lib/python3.14/site-packages/executing/__pycache__/executing.cpython-314.pyc: replacing with normalized version Scanned 9 directories and 24 files, processed 8 inodes, 8 modified (4 replaced + 4 rewritten), 0 unsupported format, 0 errors Executing(%check): /bin/sh -e /var/tmp/rpm-tmp.bvLS8T + umask 022 + cd /builddir/build/BUILD/python-executing-2.2.0-build + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + export CFLAGS + CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + export CXXFLAGS + FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + export FFLAGS + FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + export FCFLAGS + VALAFLAGS=-g + export VALAFLAGS + RUSTFLAGS='-Copt-level=3 -Cdebuginfo=2 -Ccodegen-units=1 -Cstrip=none -Cforce-frame-pointers=yes -Clink-arg=-specs=/usr/lib/rpm/redhat/redhat-package-notes --cap-lints=warn' + export RUSTFLAGS + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,pack-relative-relocs -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-hardened-ld-errors -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -specs=/usr/lib/rpm/redhat/redhat-package-notes ' + export LDFLAGS + LT_SYS_LIBRARY_PATH=/usr/lib64: + export LT_SYS_LIBRARY_PATH + CC=gcc + export CC + CXX=g++ + export CXX + cd executing-2.2.0 + '[' '!' -f /builddir/build/BUILD/python-executing-2.2.0-build/python-executing-2.2.0-2.fc43.x86_64-pyproject-modules ']' + PATH=/builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/sbin + PYTHONPATH=/builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/lib64/python3.14/site-packages:/builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/lib/python3.14/site-packages + _PYTHONSITE=/builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/lib64/python3.14/site-packages:/builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/lib/python3.14/site-packages + PYTHONDONTWRITEBYTECODE=1 + /usr/bin/python3 -sP /usr/lib/rpm/redhat/import_all_modules.py -f /builddir/build/BUILD/python-executing-2.2.0-build/python-executing-2.2.0-2.fc43.x86_64-pyproject-modules Check import: executing Check import: executing.executing Check import: executing.version + export EXECUTING_SLOW_TESTS=1 + EXECUTING_SLOW_TESTS=1 + TOX_TESTENV_PASSENV='*' + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,pack-relative-relocs -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-hardened-ld-errors -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -specs=/usr/lib/rpm/redhat/redhat-package-notes ' + PATH=/builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/sbin + PYTHONPATH=/builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/lib64/python3.14/site-packages:/builddir/build/BUILD/python-executing-2.2.0-build/BUILDROOT/usr/lib/python3.14/site-packages + PYTHONDONTWRITEBYTECODE=1 + PYTEST_ADDOPTS=' --ignore=/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/.pyproject-builddir' + PYTEST_XDIST_AUTO_NUM_WORKERS=4 + HOSTNAME=rpmbuild + /usr/bin/python3 -m tox --current-env --assert-config -q --recreate -e py314 -- -rs ============================= test session starts ============================== platform linux -- Python 3.14.0b1, pytest-8.3.4, pluggy-1.5.0 cachedir: .tox/py314/.pytest_cache rootdir: /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0 configfile: pyproject.toml collected 209 items tests/test_ipython.py .. [ 0%] tests/test_main.py .F..............................FFF.F.F..F.F.F....... [ 26%] .FFF..FF.FF..FFF..FF.FF....F.FFF.....F.F....F.FF......F....F.FFF.F..F.F. [ 60%] F.F......F...F...FF...F...F.F.F..FF.FF.F.F.F..FF..F..FFFFFFFFFFFFFFFFF [ 94%] tests/test_pytest.py .......F.... [100%] =================================== FAILURES =================================== __________________________ TestStuff.test_call_things __________________________ self = def test_call_things(self): # call things which are no methods or functions if sys.version_info >= (3,11): > tester[5](5) tests/test_main.py:507: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/utils.py:90: in __getitem__ node = self.get_node(ast.Subscript) tests/utils.py:35: in get_node ex = self.get_executing(inspect.currentframe().f_back.f_back) tests/utils.py:42: in get_executing return Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Subscript(value=Name(id='tester', ctx=Load()), slice=Constant(value=5, kind=None), ctx=Load()) instruction = Instruction(opname='BINARY_OP', opcode=44, arg=26, argval=26, argrepr='[]', offset=56, start_offset=56, starts_line=Fa...et=12, end_col_offset=21), cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( > ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): E KeyError: '[]' executing/_position_node_finder.py:661: KeyError _____________________________ TestStuff.test_with ______________________________ self = def test_with(self): if sys.version_info >= (3, 11): > with tester: tests/test_main.py:571: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/utils.py:157: in __enter__ self.get_node(ast.With) tests/utils.py:35: in get_node ex = self.get_executing(inspect.currentframe().f_back.f_back) tests/utils.py:42: in get_executing return Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Name(id='tester', ctx=Load()) instruction = Instruction(opname='CALL', opcode=52, arg=0, argval=0, argrepr='', offset=64, start_offset=64, starts_line=False, line... col_offset=17, end_col_offset=23), cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.Name is not created from CALL executing/_position_node_finder.py:938: VerifierFailure _ test_small_samples[0126981e43aec288449c540bef895abc32c6046ac22095919e1a1564ece7160b.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/0126981e43aec288449c540bef895abc32c6046ac22095919e1a1564ece7160b.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/0126981e43aec288449c540bef895abc32c6046ac22095919e1a1564ece7160b-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = GeneratorExp(elt=Name(id='cls', ctx=Load()), generators=[comprehension(target=Name(id='attr', ctx=Store(...)), iter=Name(id='_get_protocol_attrs', ctx=Load(...)), ifs=[], is_async=0)]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='.0', argrepr='.0', offset=6, start_offset=6, starts_l...ne_number=2, label=None, positions=Positions(lineno=2, end_lineno=2, col_offset=4, end_col_offset=43), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.GeneratorExp is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/0126981e43aec288449c540bef895abc32c6046ac22095919e1a1564ece7160b.py VerifierFailure: ast.GeneratorExp is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (.0) node: GeneratorExp(elt=Name(id='cls', ctx=Load(), lineno=2, col_offset=6, end_lineno=2, end_col_offset=9), generators=[comprehension(target=Name(id='attr', ctx=Store(), lineno=2, col_offset=15, end_lineno=2, end_col_offset=19), iter=Name(id='_get_protocol_attrs', ctx=Load(), lineno=2, col_offset=23, end_lineno=2, end_col_offset=42), is_async=0)], lineno=2, col_offset=4, end_lineno=2, end_col_offset=43) parent node: Expr source code: 1: class _ProtocolMeta: 2: ((cls) for attr in _get_protocol_attrs) 3: super().__instancecheck__ None bytecode: _ test_small_samples[0194cd769109c110d50905631c5793818736ff3835dd0a5ef97ed2f34cd65892.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/0194cd769109c110d50905631c5793818736ff3835dd0a5ef97ed2f34cd65892.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/0194cd769109c110d50905631c5793818736ff3835dd0a5ef97ed2f34cd65892-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Name(id='frame', ctx=Load()) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=2, argval='frame', argrepr='frame', offset=2, start_offset=2, st...number=17, label=None, positions=Positions(lineno=17, end_lineno=17, col_offset=7, end_col_offset=12), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.Name is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/0194cd769109c110d50905631c5793818736ff3835dd0a5ef97ed2f34cd65892.py VerifierFailure: ast.Name is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 2 (frame) node: Name(id='frame', ctx=Load(), lineno=17, col_offset=7, end_lineno=17, end_col_offset=12) parent node: BoolOp source code: 13: # except AttributeError as e: 14: # 15: 16: def after_stmt(self, node, frame, exc_value, exc_traceback, exc_node): 17: if frame or _tracing_recursively: 18: return None 19: exc_value None bytecode: _ test_small_samples[0675309754ba4277c9cb3c52d7131377fe69c7744a271e2b7471917dabb5aaa1.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/0675309754ba4277c9cb3c52d7131377fe69c7744a271e2b7471917dabb5aaa1.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/0675309754ba4277c9cb3c52d7131377fe69c7744a271e2b7471917dabb5aaa1-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Name(id='name_0', ctx=Load()) instruction = Instruction(opname='CALL', opcode=52, arg=0, argval=0, argrepr='', offset=32, start_offset=32, starts_line=False, line..., col_offset=9, end_col_offset=15), cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.Name is not created from CALL executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/0675309754ba4277c9cb3c52d7131377fe69c7744a271e2b7471917dabb5aaa1.py VerifierFailure: ast.Name is not created from CALL instruction: CALL 0 node: Name(id='name_0', ctx=Load(), lineno=2, col_offset=9, end_lineno=2, end_col_offset=15) parent node: withitem source code: 1: class name_2: 2: with name_0: # type: ignoresome text 3: 4: class name_2[name_5]: 5: pass None bytecode: _ test_small_samples[09c2b2709b3507baf8a9e749c6e3bed21728d2159858adcfa66c49bb3e2f35f2.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/09c2b2709b3507baf8a9e749c6e3bed21728d2159858adcfa66c49bb3e2f35f2.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/09c2b2709b3507baf8a9e749c6e3bed21728d2159858adcfa66c49bb3e2f35f2-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = FunctionDef(name='func', args=arguments(posonlyargs=[], args=[], vararg=None, kwonlyargs=[arg(arg='b', annotation=None...], decorator_list=[], returns=None, type_comment=None, type_params=[TypeVar(name='T', bound=None, default_value=None)]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='.defaults', argrepr='.defaults', offset=12, start_off...ine_number=1, label=None, positions=Positions(lineno=1, end_lineno=2, col_offset=0, end_col_offset=8), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/09c2b2709b3507baf8a9e749c6e3bed21728d2159858adcfa66c49bb3e2f35f2.py VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (.defaults) node: FunctionDef(name='func', args=arguments(kwonlyargs=[arg(arg='b', lineno=1, col_offset=15, end_lineno=1, end_col_offset=16)], kw_defaults=[Constant(value='b', lineno=1, col_offset=17, end_lineno=1, end_col_offset=20)]), body=[Pass(lineno=2, col_offset=4, end_lineno=2, end_col_offset=8)], type_params=[TypeVar(name='T', lineno=1, col_offset=9, end_lineno=1, end_col_offset=10)], lineno=1, col_offset=0, end_lineno=2, end_col_offset=8) parent node: Module source code: 1: def func[T](*, b='b'): 2: pass None bytecode: _ test_small_samples[0fe16ec438396e003734858ad326d907e514273262547abaee0cd15e6eb7083e.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/0fe16ec438396e003734858ad326d907e514273262547abaee0cd15e6eb7083e.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/0fe16ec438396e003734858ad326d907e514273262547abaee0cd15e6eb7083e-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Subscript(value=Name(id='self', ctx=Load()), slice=Name(id='name', ctx=Load()), ctx=Load()) instruction = Instruction(opname='BINARY_OP', opcode=44, arg=26, argval=26, argrepr='[]', offset=24, start_offset=24, starts_line=Fa...et=15, end_col_offset=25), cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( > ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): E KeyError: '[]' executing/_position_node_finder.py:661: KeyError ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/0fe16ec438396e003734858ad326d907e514273262547abaee0cd15e6eb7083e.py mapping failed '[]' search bytecode BINARY_OP 26 ([]) in file /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/0fe16ec438396e003734858ad326d907e514273262547abaee0cd15e6eb7083e.py at position Positions(lineno=18, end_lineno=18, col_offset=15, end_col_offset=25) source code: 14: # 15: 16: def __getattr__(): 17: try: 18: return self[name] 19: except KeyError: 20: return '' 21: name possible node 18 18 15 19 Name(id='self', ctx=Load()) possible node 18 18 20 24 Name(id='name', ctx=Load()) possible node 18 18 15 25 Subscript(value=Name(id='self', ctx=Load()), slice=Name(id='name', ctx=Load()), ctx=Load()) possible node 18 18 8 25 Return(value=Subscript(value=Name(id='self', ctx=Load()), slice=Name(id='name', ctx=Load()), ctx=Load())) _ test_small_samples[126f1cda2062caf2c74dcdcd77f5cb3a0e2d20b749329f84f48aa4d90701f2d0.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/126f1cda2062caf2c74dcdcd77f5cb3a0e2d20b749329f84f48aa4d90701f2d0.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/126f1cda2062caf2c74dcdcd77f5cb3a0e2d20b749329f84f48aa4d90701f2d0-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Subscript(value=Name(id='session', ctx=Load()), slice=Slice(lower=None, upper=Constant(value=100, kind=None), step=None), ctx=Load()) instruction = Instruction(opname='BINARY_OP', opcode=44, arg=26, argval=26, argrepr='[]', offset=6, start_offset=6, starts_line=Fals...set=0, end_col_offset=13), cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( > ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): E KeyError: '[]' executing/_position_node_finder.py:661: KeyError ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/126f1cda2062caf2c74dcdcd77f5cb3a0e2d20b749329f84f48aa4d90701f2d0.py mapping failed '[]' search bytecode BINARY_OP 26 ([]) in file /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/126f1cda2062caf2c74dcdcd77f5cb3a0e2d20b749329f84f48aa4d90701f2d0.py at position Positions(lineno=1, end_lineno=1, col_offset=0, end_col_offset=13) source code: 1: session[:100] possible node 1 1 9 12 Constant(value=100) possible node 1 1 8 12 Slice(upper=Constant(value=100)) possible node 1 1 0 7 Name(id='session', ctx=Load()) possible node 1 1 0 13 Expr(value=Subscript(value=Name(id='session', ctx=Load()), slice=Slice(upper=Constant(value=100)), ctx=Load())) possible node 1 1 0 13 Subscript(value=Name(id='session', ctx=Load()), slice=Slice(upper=Constant(value=100)), ctx=Load()) _ test_small_samples[16b59c539eacafcbb66df969aa7a3a6f612fd4fa9acb07a2a30f837350c555a4.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/16b59c539eacafcbb66df969aa7a3a6f612fd4fa9acb07a2a30f837350c555a4.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/16b59c539eacafcbb66df969aa7a3a6f612fd4fa9acb07a2a30f837350c555a4-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Name(id='context', ctx=Store()) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=1, argval='context', argrepr='context', offset=2, start_offset=2...number=17, label=None, positions=Positions(lineno=17, end_lineno=17, col_offset=4, end_col_offset=11), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.Name is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/16b59c539eacafcbb66df969aa7a3a6f612fd4fa9acb07a2a30f837350c555a4.py VerifierFailure: ast.Name is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 1 (context) node: Name(id='context', ctx=Store(), lineno=17, col_offset=4, end_lineno=17, end_col_offset=11) parent node: AugAssign source code: 13: # ): 14: # 15: 16: def trace_this_module(self, context=0, deep=False): 17: context -= 1 None bytecode: _ test_small_samples[248c72657ee1942a557f5521fe25423a53aa4b44e7890abf76ebaf1960952f2f.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/248c72657ee1942a557f5521fe25423a53aa4b44e7890abf76ebaf1960952f2f.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/248c72657ee1942a557f5521fe25423a53aa4b44e7890abf76ebaf1960952f2f-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Name(id='self', ctx=Load()) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='self', argrepr='self', offset=2, start_offset=2, star...umber=17, label=None, positions=Positions(lineno=17, end_lineno=17, col_offset=29, end_col_offset=33), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.Name is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/248c72657ee1942a557f5521fe25423a53aa4b44e7890abf76ebaf1960952f2f.py VerifierFailure: ast.Name is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (self) node: Name(id='self', ctx=Load(), lineno=17, col_offset=29, end_lineno=17, end_col_offset=33) parent node: For source code: 13: # 14: # 15: 16: def replace(self, string): 17: for start, end, match in self: 18: pass 19: else: 20: return False 21: self None bytecode: _ test_small_samples[2680ea2b168d077ec7ad4d22c7897f402c4984d93b314a8566d227ce894a6c14.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/2680ea2b168d077ec7ad4d22c7897f402c4984d93b314a8566d227ce894a6c14.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/2680ea2b168d077ec7ad4d22c7897f402c4984d93b314a8566d227ce894a6c14-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = FunctionDef(name='more_generic', args=arguments(posonlyargs=[], args=[], vararg=None, kwonlyargs=[], kw_defaults=[], k...oad(...)))], decorator_list=[], returns=None, type_comment=None, type_params=[ParamSpec(name='P', default_value=None)]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=1, argval='P', argrepr='P', offset=14, start_offset=14, starts_l...ne_number=1, label=None, positions=Positions(lineno=1, end_lineno=2, col_offset=0, end_col_offset=15), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/2680ea2b168d077ec7ad4d22c7897f402c4984d93b314a8566d227ce894a6c14.py VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 1 (P) node: FunctionDef(name='more_generic', args=arguments(), body=[TypeAlias(name=Name(id='TA', ctx=Store(), lineno=2, col_offset=9, end_lineno=2, end_col_offset=11), value=Name(id='P', ctx=Load(), lineno=2, col_offset=14, end_lineno=2, end_col_offset=15), lineno=2, col_offset=4, end_lineno=2, end_col_offset=15)], type_params=[ParamSpec(name='P', lineno=1, col_offset=17, end_lineno=1, end_col_offset=20)], lineno=1, col_offset=0, end_lineno=2, end_col_offset=15) parent node: Module source code: 1: def more_generic[**P](): 2: type TA = P None bytecode: _ test_small_samples[289bcf3ad1de1e72dab056250fe9516668937d7d9c55be773acd60a8f05c4318.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/289bcf3ad1de1e72dab056250fe9516668937d7d9c55be773acd60a8f05c4318.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/289bcf3ad1de1e72dab056250fe9516668937d7d9c55be773acd60a8f05c4318-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = FunctionDef(name='__init__', args=arguments(posonlyargs=[], args=[arg(arg='self', annotation=None, type_comment=None)]...value=Call(...), attr='__init__', ctx=Load(...)))], decorator_list=[], returns=None, type_comment=None, type_params=[]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='__class__', argrepr='__class__', offset=22, start_off...ne_number=3, label=None, positions=Positions(lineno=3, end_lineno=4, col_offset=4, end_col_offset=24), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/289bcf3ad1de1e72dab056250fe9516668937d7d9c55be773acd60a8f05c4318.py VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (__class__) node: FunctionDef(name='__init__', args=arguments(args=[arg(arg='self', lineno=3, col_offset=17, end_lineno=3, end_col_offset=21)]), body=[Expr(value=Attribute(value=Call(func=Name(id='super', ctx=Load(), lineno=4, col_offset=8, end_lineno=4, end_col_offset=13), lineno=4, col_offset=8, end_lineno=4, end_col_offset=15), attr='__init__', ctx=Load(), lineno=4, col_offset=8, end_lineno=4, end_col_offset=24), lineno=4, col_offset=8, end_lineno=4, end_col_offset=24)], lineno=3, col_offset=4, end_lineno=4, end_col_offset=24) parent node: ClassDef source code: 1: class VerifierFailure: 2: 3: def __init__(self): 4: super().__init__ None bytecode: _ test_small_samples[2ad55a93b62d942e84a4ec6cf3385da73bfe13a70739c8b6e21d6917cdf54142.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/2ad55a93b62d942e84a4ec6cf3385da73bfe13a70739c8b6e21d6917cdf54142.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/2ad55a93b62d942e84a4ec6cf3385da73bfe13a70739c8b6e21d6917cdf54142-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = FunctionDef(name='__new__', args=arguments(posonlyargs=[], args=[arg(arg='cls', annotation=None, type_comment=None)], ...(value=Call(...), attr='__new__', ctx=Load(...)))], decorator_list=[], returns=None, type_comment=None, type_params=[]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='__class__', argrepr='__class__', offset=22, start_off...ne_number=3, label=None, positions=Positions(lineno=3, end_lineno=4, col_offset=4, end_col_offset=23), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/2ad55a93b62d942e84a4ec6cf3385da73bfe13a70739c8b6e21d6917cdf54142.py VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (__class__) node: FunctionDef(name='__new__', args=arguments(args=[arg(arg='cls', lineno=3, col_offset=16, end_lineno=3, end_col_offset=19)]), body=[Expr(value=Attribute(value=Call(func=Name(id='super', ctx=Load(), lineno=4, col_offset=8, end_lineno=4, end_col_offset=13), lineno=4, col_offset=8, end_lineno=4, end_col_offset=15), attr='__new__', ctx=Load(), lineno=4, col_offset=8, end_lineno=4, end_col_offset=23), lineno=4, col_offset=8, end_lineno=4, end_col_offset=23)], lineno=3, col_offset=4, end_lineno=4, end_col_offset=23) parent node: ClassDef source code: 1: class Any(metaclass=_AnyMeta): 2: 3: def __new__(cls): 4: super().__new__ None bytecode: _ test_small_samples[2bfb9b3e488bd50d6e05a300b7cec608d2b0d54260b7ca4ce834bd81a96e1e54.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/2bfb9b3e488bd50d6e05a300b7cec608d2b0d54260b7ca4ce834bd81a96e1e54.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/2bfb9b3e488bd50d6e05a300b7cec608d2b0d54260b7ca4ce834bd81a96e1e54-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Lambda(args=arguments(posonlyargs=[], args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=Name(id='vars_order', ctx=Load())) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='vars_order', argrepr='vars_order', offset=16, start_o...ne_number=3, label=None, positions=Positions(lineno=3, end_lineno=3, col_offset=4, end_col_offset=22), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.Lambda is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/2bfb9b3e488bd50d6e05a300b7cec608d2b0d54260b7ca4ce834bd81a96e1e54.py VerifierFailure: ast.Lambda is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (vars_order) node: Lambda(args=arguments(), body=Name(id='vars_order', ctx=Load(), lineno=3, col_offset=12, end_lineno=3, end_col_offset=22), lineno=3, col_offset=4, end_lineno=3, end_col_offset=22) parent node: Expr source code: 1: def get_local_reprs(): 2: vars_order = something 3: lambda: vars_order None bytecode: _ test_small_samples[2fa69a57eb3b16f9ce0d5be427ad471c93a54c6d7e68b5be024b6a046ecc6bb2.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/2fa69a57eb3b16f9ce0d5be427ad471c93a54c6d7e68b5be024b6a046ecc6bb2.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/2fa69a57eb3b16f9ce0d5be427ad471c93a54c6d7e68b5be024b6a046ecc6bb2-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Name(id='self', ctx=Load()) instruction = Instruction(opname='CALL', opcode=52, arg=0, argval=0, argrepr='', offset=14, start_offset=14, starts_line=False, line...6, col_offset=5, end_col_offset=9), cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.Name is not created from CALL executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/2fa69a57eb3b16f9ce0d5be427ad471c93a54c6d7e68b5be024b6a046ecc6bb2.py VerifierFailure: ast.Name is not created from CALL instruction: CALL 0 node: Name(id='self', ctx=Load(), lineno=16, col_offset=5, end_lineno=16, end_col_offset=9) parent node: withitem source code: 12: # self.walk_deadcode(node.msg, deadcode) 13: # deadcode = True 14: # 15: 16: with self as session: 17: assert isinstance 18: db_func None bytecode: _ test_small_samples[318c09f5abc7ace5b69c55380616ebf1cc984e6c365ff8d9f021725eabbe02ae.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/318c09f5abc7ace5b69c55380616ebf1cc984e6c365ff8d9f021725eabbe02ae.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/318c09f5abc7ace5b69c55380616ebf1cc984e6c365ff8d9f021725eabbe02ae-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = ClassDef(name='Inner', bases=[], keywords=[], body=[Pass()], decorator_list=[], type_params=[TypeVar(name='C', bound=None, default_value=None)]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='__classdict__', argrepr='__classdict__', offset=20, s...ne_number=3, label=None, positions=Positions(lineno=3, end_lineno=4, col_offset=4, end_col_offset=12), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.ClassDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/318c09f5abc7ace5b69c55380616ebf1cc984e6c365ff8d9f021725eabbe02ae.py VerifierFailure: ast.ClassDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (__classdict__) node: ClassDef(name='Inner', body=[Pass(lineno=4, col_offset=8, end_lineno=4, end_col_offset=12)], type_params=[TypeVar(name='C', lineno=3, col_offset=16, end_lineno=3, end_col_offset=17)], lineno=3, col_offset=4, end_lineno=4, end_col_offset=12) parent node: ClassDef source code: 1: class Outer: 2: 3: class Inner[C]: 4: pass None bytecode: _ test_small_samples[393abb63bcdcf6c3f6b008fb7a7635ac6f615f1ef83579b2ad0e735d738e9ddd.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/393abb63bcdcf6c3f6b008fb7a7635ac6f615f1ef83579b2ad0e735d738e9ddd.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/393abb63bcdcf6c3f6b008fb7a7635ac6f615f1ef83579b2ad0e735d738e9ddd-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = TypeAlias(name=Name(id='_Func', ctx=Store()), type_params=[], value=Name(id='Callable', ctx=Load())) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='.format', argrepr='.format', offset=2, start_offset=2...ne_number=1, label=None, positions=Positions(lineno=1, end_lineno=1, col_offset=0, end_col_offset=21), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.TypeAlias is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/393abb63bcdcf6c3f6b008fb7a7635ac6f615f1ef83579b2ad0e735d738e9ddd.py VerifierFailure: ast.TypeAlias is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (.format) node: TypeAlias(name=Name(id='_Func', ctx=Store(), lineno=1, col_offset=5, end_lineno=1, end_col_offset=10), value=Name(id='Callable', ctx=Load(), lineno=1, col_offset=13, end_lineno=1, end_col_offset=21), lineno=1, col_offset=0, end_lineno=1, end_col_offset=21) parent node: Module source code: 1: type _Func = Callable None bytecode: _ test_small_samples[3946430f5c3048d7d85d5424c4fcb541db50c9c41d5653c977e974351b2f6bc9.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/3946430f5c3048d7d85d5424c4fcb541db50c9c41d5653c977e974351b2f6bc9.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/3946430f5c3048d7d85d5424c4fcb541db50c9c41d5653c977e974351b2f6bc9-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = FunctionDef(name='__instancecheck__', args=arguments(posonlyargs=[], args=[arg(arg='cls', annotation=None, type_commen...l(...), attr='__instancecheck__', ctx=Load(...)))], decorator_list=[], returns=None, type_comment=None, type_params=[]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='__class__', argrepr='__class__', offset=22, start_off...ne_number=3, label=None, positions=Positions(lineno=3, end_lineno=5, col_offset=4, end_col_offset=33), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/3946430f5c3048d7d85d5424c4fcb541db50c9c41d5653c977e974351b2f6bc9.py VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (__class__) node: FunctionDef(name='__instancecheck__', args=arguments(args=[arg(arg='cls', lineno=3, col_offset=26, end_lineno=3, end_col_offset=29)]), body=[Expr(value=GeneratorExp(elt=Name(id='cls', ctx=Load(), lineno=4, col_offset=10, end_lineno=4, end_col_offset=13), generators=[comprehension(target=Name(id='attr', ctx=Store(), lineno=4, col_offset=19, end_lineno=4, end_col_offset=23), iter=Name(id='_get_protocol_attrs', ctx=Load(), lineno=4, col_offset=27, end_lineno=4, end_col_offset=46), is_async=0)], lineno=4, col_offset=8, end_lineno=4, end_col_offset=47), lineno=4, col_offset=8, end_lineno=4, end_col_offset=47), Expr(value=Attribute(value=Call(func=Name(id='super', ctx=Load(), lineno=5, col_offset=8, end_lineno=5, end_col_offset=13), lineno=5, col_offset=8, end_lineno=5, end_col_offset=15), attr='__instancecheck__', ctx=Load(), lineno=5, col_offset=8, end_lineno=5, end_col_offset=33), lineno=5, col_offset=8, end_lineno=5, end_col_offset=33)], lineno=3, col_offset=4, end_lineno=5, end_col_offset=33) parent node: ClassDef source code: 1: class _ProtocolMeta: 2: 3: def __instancecheck__(cls): 4: ((cls) for attr in _get_protocol_attrs) 5: super().__instancecheck__ None bytecode: _ test_small_samples[3a50eb1aed494e7b3b7e6fc814943b6b24acafdbc5b40644b79ec50bdb29b023.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/3a50eb1aed494e7b3b7e6fc814943b6b24acafdbc5b40644b79ec50bdb29b023.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/3a50eb1aed494e7b3b7e6fc814943b6b24acafdbc5b40644b79ec50bdb29b023-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = TypeAlias(name=Name(id='TA1', ctx=Store()), type_params=[], value=Name(id='int', ctx=Load())) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='.format', argrepr='.format', offset=2, start_offset=2...ne_number=2, label=None, positions=Positions(lineno=2, end_lineno=2, col_offset=4, end_col_offset=18), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.TypeAlias is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/3a50eb1aed494e7b3b7e6fc814943b6b24acafdbc5b40644b79ec50bdb29b023.py VerifierFailure: ast.TypeAlias is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (.format) node: TypeAlias(name=Name(id='TA1', ctx=Store(), lineno=2, col_offset=9, end_lineno=2, end_col_offset=12), value=Name(id='int', ctx=Load(), lineno=2, col_offset=15, end_lineno=2, end_col_offset=18), lineno=2, col_offset=4, end_lineno=2, end_col_offset=18) parent node: FunctionDef source code: 1: def test_alias_value_01(): 2: type TA1 = int None bytecode: _ test_small_samples[3e40f2921fbaf6ccbabb2fa5c3cd3a42b54914d66f7a67f8b2ade36f89ed761b.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/3e40f2921fbaf6ccbabb2fa5c3cd3a42b54914d66f7a67f8b2ade36f89ed761b.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/3e40f2921fbaf6ccbabb2fa5c3cd3a42b54914d66f7a67f8b2ade36f89ed761b-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Name(id='something', ctx=Load()) instruction = Instruction(opname='CALL', opcode=52, arg=0, argval=0, argrepr='', offset=26, start_offset=26, starts_line=False, line... col_offset=15, end_col_offset=24), cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.Name is not created from CALL executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/3e40f2921fbaf6ccbabb2fa5c3cd3a42b54914d66f7a67f8b2ade36f89ed761b.py VerifierFailure: ast.Name is not created from CALL instruction: CALL 0 node: Name(id='something', ctx=Load(), lineno=2, col_offset=15, end_lineno=2, end_col_offset=24) parent node: withitem source code: 1: async def wait(): 2: async with something: 3: pass None bytecode: _ test_small_samples[42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = FunctionDef(name='__init__', args=arguments(posonlyargs=[], args=[arg(arg='self', annotation=None, type_comment=None),...tionalNotMatched', ctx=Load(...))]), body=[Pass()], decorator_list=[], returns=None, type_comment=None, type_params=[]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='__classdict__', argrepr='__classdict__', offset=24, s...number=18, label=None, positions=Positions(lineno=18, end_lineno=19, col_offset=4, end_col_offset=12), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a.py VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (__classdict__) node: FunctionDef(name='__init__', args=arguments(args=[arg(arg='self', lineno=18, col_offset=17, end_lineno=18, end_col_offset=21), arg(arg='expr', annotation=Name(id='Union', ctx=Load(), lineno=18, col_offset=29, end_lineno=18, end_col_offset=34), lineno=18, col_offset=23, end_lineno=18, end_col_offset=34), arg(arg='default', annotation=Name(id='Any', ctx=Load(), lineno=18, col_offset=45, end_lineno=18, end_col_offset=48), lineno=18, col_offset=36, end_lineno=18, end_col_offset=48)], defaults=[Name(id='__optionalNotMatched', ctx=Load(), lineno=18, col_offset=49, end_lineno=18, end_col_offset=69)]), body=[Pass(lineno=19, col_offset=8, end_lineno=19, end_col_offset=12)], lineno=18, col_offset=4, end_lineno=19, end_col_offset=12) parent node: ClassDef source code: 14: # 15: 16: class Opt: 17: 18: def __init__(self, expr: Union, default: Any=__optionalNotMatched): 19: pass None bytecode: _ test_small_samples[45a20d9fefe2db8c5fbc91ad26e8e9dce0667e126dab5e34fd6825c085776be5.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/45a20d9fefe2db8c5fbc91ad26e8e9dce0667e126dab5e34fd6825c085776be5.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/45a20d9fefe2db8c5fbc91ad26e8e9dce0667e126dab5e34fd6825c085776be5-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Name(id='r', ctx=Load()) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='r', argrepr='r', offset=64, start_offset=64, starts_l...ine_number=16, label=4, positions=Positions(lineno=16, end_lineno=16, col_offset=1, end_col_offset=2), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.Name is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/45a20d9fefe2db8c5fbc91ad26e8e9dce0667e126dab5e34fd6825c085776be5.py VerifierFailure: ast.Name is not created from LOAD_FAST_BORROW instruction: L4: LOAD_FAST_BORROW 0 (r) node: Name(id='r', ctx=Load(), lineno=16, col_offset=1, end_lineno=16, end_col_offset=2) parent node: ListComp source code: 12: # if isinstance(node, ast.Assert): 13: # # pytest assigns the position of the assertion to all expressions of the rewritten assertion. 14: # 15: 16: [r for r in results if start <= r <= end] None bytecode: _ test_small_samples[46597f8f896f11c5d7f432236344cc7e5645c2a39836eb6abdd2437c0422f0f4.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/46597f8f896f11c5d7f432236344cc7e5645c2a39836eb6abdd2437c0422f0f4.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/46597f8f896f11c5d7f432236344cc7e5645c2a39836eb6abdd2437c0422f0f4-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Import(names=[alias(name='ast', asname=None)]) instruction = Instruction(opname='STORE_NAME', opcode=116, arg=237, argval='__annotate__', argrepr='__annotate__', offset=8, start_o...number=15, label=None, positions=Positions(lineno=15, end_lineno=15, col_offset=0, end_col_offset=10), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.Import is not created from STORE_NAME executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/46597f8f896f11c5d7f432236344cc7e5645c2a39836eb6abdd2437c0422f0f4.py VerifierFailure: ast.Import is not created from STORE_NAME instruction: STORE_NAME 237 (__annotate__) node: Import(names=[alias(name='ast', lineno=15, col_offset=7, end_lineno=15, end_col_offset=10)], lineno=15, col_offset=0, end_lineno=15, end_col_offset=10) parent node: Module source code: 11: # 12: # if ( 13: 14: 15: import ast 16: from abc import ABC, abstractmethod 17: from collections import defaultdict 18: from concurrent.futures import Executor, ThreadPoolExecutor, ProcessPoolExecutor 19: from contextlib import contextmanager 20: from datetime import datetime None bytecode: _ test_small_samples[4d3f8fa60aa762d76852454257bd527e40f38549b584e45269cfc5977248fb62.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/4d3f8fa60aa762d76852454257bd527e40f38549b584e45269cfc5977248fb62.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/4d3f8fa60aa762d76852454257bd527e40f38549b584e45269cfc5977248fb62-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Tuple(elts=[Name(id='str', ctx=Load())], ctx=Load()) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='.format', argrepr='.format', offset=2, start_offset=2...e_number=1, label=None, positions=Positions(lineno=1, end_lineno=1, col_offset=39, end_col_offset=45), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.Tuple is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/4d3f8fa60aa762d76852454257bd527e40f38549b584e45269cfc5977248fb62.py VerifierFailure: ast.Tuple is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (.format) node: Tuple(elts=[Name(id='str', ctx=Load(), lineno=1, col_offset=40, end_lineno=1, end_col_offset=43)], ctx=Load(), lineno=1, col_offset=39, end_lineno=1, end_col_offset=45) parent node: TypeVar source code: 1: type ConstrainedGenericAlias[LongName: (str,)] = list None bytecode: _ test_small_samples[508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = FunctionDef(name='onClickPage', args=arguments(posonlyargs=[], args=[arg(arg='self', annotation=None, type_comment=Non...dy=[Expr(value=Name(id='__test2', ctx=Load(...)))], decorator_list=[], returns=None, type_comment=None, type_params=[]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='__classdict__', argrepr='__classdict__', offset=30, s...number=18, label=None, positions=Positions(lineno=18, end_lineno=19, col_offset=4, end_col_offset=15), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a.py VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (__classdict__) node: FunctionDef(name='onClickPage', args=arguments(args=[arg(arg='self', lineno=18, col_offset=20, end_lineno=18, end_col_offset=24), arg(arg='event', lineno=18, col_offset=26, end_lineno=18, end_col_offset=31)]), body=[Expr(value=Name(id='__test2', ctx=Load(), lineno=19, col_offset=8, end_lineno=19, end_col_offset=15), lineno=19, col_offset=8, end_lineno=19, end_col_offset=15)], lineno=18, col_offset=4, end_lineno=19, end_col_offset=15) parent node: ClassDef source code: 14: # 15: 16: class __test: 17: 18: def onClickPage(self, event): 19: __test2 None bytecode: _ test_small_samples[5182c37c0eb2a1b7402d1c3fc623d4e57106429cc932cce07630fc07781e4167.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/5182c37c0eb2a1b7402d1c3fc623d4e57106429cc932cce07630fc07781e4167.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/5182c37c0eb2a1b7402d1c3fc623d4e57106429cc932cce07630fc07781e4167-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Name(id='frame', ctx=Load()) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=2, argval='frame', argrepr='frame', offset=2, start_offset=2, st...number=17, label=None, positions=Positions(lineno=17, end_lineno=17, col_offset=7, end_col_offset=12), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.Name is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/5182c37c0eb2a1b7402d1c3fc623d4e57106429cc932cce07630fc07781e4167.py VerifierFailure: ast.Name is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 2 (frame) node: Name(id='frame', ctx=Load(), lineno=17, col_offset=7, end_lineno=17, end_col_offset=12) parent node: If source code: 13: # self.walk_deadcode(node.subject, deadcode) 14: # 15: 16: def before_stmt(self, node, frame): 17: if frame: 18: return 19: isinstance None bytecode: _ test_small_samples[524a7a805db753f5ea998182ddaea49a177b75a7ae88ab77eaa879755857a15a.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/524a7a805db753f5ea998182ddaea49a177b75a7ae88ab77eaa879755857a15a.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/524a7a805db753f5ea998182ddaea49a177b75a7ae88ab77eaa879755857a15a-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = TypeAlias(name=Name(id='TA1', ctx=Store()), type_params=[], value=Name(id='dict', ctx=Load())) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='__classdict__', argrepr='__classdict__', offset=26, s...ne_number=2, label=None, positions=Positions(lineno=2, end_lineno=2, col_offset=4, end_col_offset=19), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.TypeAlias is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/524a7a805db753f5ea998182ddaea49a177b75a7ae88ab77eaa879755857a15a.py VerifierFailure: ast.TypeAlias is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (__classdict__) node: TypeAlias(name=Name(id='TA1', ctx=Store(), lineno=2, col_offset=9, end_lineno=2, end_col_offset=12), value=Name(id='dict', ctx=Load(), lineno=2, col_offset=15, end_lineno=2, end_col_offset=19), lineno=2, col_offset=4, end_lineno=2, end_col_offset=19) parent node: ClassDef source code: 1: class Parent: 2: type TA1 = dict None bytecode: _ test_small_samples[635d56ede8cbcb2824d42291eb9fe9288d5f09c768636aaa19984ffdfc91e9fe.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/635d56ede8cbcb2824d42291eb9fe9288d5f09c768636aaa19984ffdfc91e9fe.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/635d56ede8cbcb2824d42291eb9fe9288d5f09c768636aaa19984ffdfc91e9fe-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Name(id='self', ctx=Load()) instruction = Instruction(opname='CALL', opcode=52, arg=0, argval=0, argrepr='', offset=14, start_offset=14, starts_line=False, line...6, col_offset=5, end_col_offset=9), cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.Name is not created from CALL executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/635d56ede8cbcb2824d42291eb9fe9288d5f09c768636aaa19984ffdfc91e9fe.py VerifierFailure: ast.Name is not created from CALL instruction: CALL 0 node: Name(id='self', ctx=Load(), lineno=16, col_offset=5, end_lineno=16, end_col_offset=9) parent node: withitem source code: 12: # if else_is_dead and not contains_break(node.body): 13: # # for a in l: 14: # 15: 16: with self: 17: for _ in tester: 18: pass 19: else: 20: tester None bytecode: _ test_small_samples[69bd4dd67f6d3737f72f314978488dfedd5e8071b45a2648757451ac47bf1b33.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/69bd4dd67f6d3737f72f314978488dfedd5e8071b45a2648757451ac47bf1b33.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/69bd4dd67f6d3737f72f314978488dfedd5e8071b45a2648757451ac47bf1b33-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Name(id='self', ctx=Load()) instruction = Instruction(opname='CALL', opcode=52, arg=0, argval=0, argrepr='', offset=14, start_offset=14, starts_line=False, line...6, col_offset=5, end_col_offset=9), cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.Name is not created from CALL executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/69bd4dd67f6d3737f72f314978488dfedd5e8071b45a2648757451ac47bf1b33.py VerifierFailure: ast.Name is not created from CALL instruction: CALL 0 node: Name(id='self', ctx=Load(), lineno=16, col_offset=5, end_lineno=16, end_col_offset=9) parent node: withitem source code: 12: # childs = node_or_list 13: # else: 14: # 15: 16: with self: 17: for _ in tester: 18: pass 19: else: 20: raise ValueError None bytecode: _ test_small_samples[6e57262c88b56d0d657064aec550809ad12bb5f22524f12b25dfa8840a9856e2.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/6e57262c88b56d0d657064aec550809ad12bb5f22524f12b25dfa8840a9856e2.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/6e57262c88b56d0d657064aec550809ad12bb5f22524f12b25dfa8840a9856e2-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Name(id='text', ctx=Load()) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=1, argval='text', argrepr='text', offset=16, start_offset=16, st...umber=18, label=None, positions=Positions(lineno=18, end_lineno=18, col_offset=20, end_col_offset=24), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.Name is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/6e57262c88b56d0d657064aec550809ad12bb5f22524f12b25dfa8840a9856e2.py VerifierFailure: ast.Name is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 1 (text) node: Name(id='text', ctx=Load(), lineno=18, col_offset=20, end_lineno=18, end_col_offset=24) parent node: Call source code: 14: # 15: 16: def filterChanged(self, text): 17: try: 18: e = compile(text, '', 'eval') 19: except Exception as e: 20: pass 21: 22: def f(t): 23: e None bytecode: _ test_small_samples[73d0fdb16164fc57d2dfc4fad6182f18b9c004a668645de8c14219daa546e2d1.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/73d0fdb16164fc57d2dfc4fad6182f18b9c004a668645de8c14219daa546e2d1.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/73d0fdb16164fc57d2dfc4fad6182f18b9c004a668645de8c14219daa546e2d1-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = FunctionDef(name='__setattr__', args=arguments(posonlyargs=[], args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kw...body=[Expr(value=Name(id='super', ctx=Load(...)))], decorator_list=[], returns=None, type_comment=None, type_params=[]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='__class__', argrepr='__class__', offset=22, start_off...ne_number=3, label=None, positions=Positions(lineno=3, end_lineno=4, col_offset=4, end_col_offset=13), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/73d0fdb16164fc57d2dfc4fad6182f18b9c004a668645de8c14219daa546e2d1.py VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (__class__) node: FunctionDef(name='__setattr__', args=arguments(), body=[Expr(value=Name(id='super', ctx=Load(), lineno=4, col_offset=8, end_lineno=4, end_col_offset=13), lineno=4, col_offset=8, end_lineno=4, end_col_offset=13)], lineno=3, col_offset=4, end_lineno=4, end_col_offset=13) parent node: ClassDef source code: 1: class Tester: 2: 3: def __setattr__(): 4: super 5: __add__ None bytecode: _ test_small_samples[7532e0e7ee9c85347bb4bfcc8751604bf934d3e96e48f3bc8b5778d7856d5a7e.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/7532e0e7ee9c85347bb4bfcc8751604bf934d3e96e48f3bc8b5778d7856d5a7e.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/7532e0e7ee9c85347bb4bfcc8751604bf934d3e96e48f3bc8b5778d7856d5a7e-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = FunctionDef(name='__call__', args=arguments(posonlyargs=[], args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg..., returns=Name(id='T', ctx=Load()), type_comment=None, type_params=[TypeVar(name='T', bound=None, default_value=None)]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='__classdict__', argrepr='__classdict__', offset=20, s...ne_number=3, label=None, positions=Positions(lineno=3, end_lineno=4, col_offset=4, end_col_offset=12), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/7532e0e7ee9c85347bb4bfcc8751604bf934d3e96e48f3bc8b5778d7856d5a7e.py VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (__classdict__) node: FunctionDef(name='__call__', args=arguments(), body=[Pass(lineno=4, col_offset=8, end_lineno=4, end_col_offset=12)], returns=Name(id='T', ctx=Load(), lineno=3, col_offset=25, end_lineno=3, end_col_offset=26), type_params=[TypeVar(name='T', lineno=3, col_offset=17, end_lineno=3, end_col_offset=18)], lineno=3, col_offset=4, end_lineno=4, end_col_offset=12) parent node: ClassDef source code: 1: class _IdentityCallable: 2: 3: def __call__[T]() -> T: 4: pass None bytecode: _ test_small_samples[7fff707ddf87544616f198155d98e215700b261e39fda3844940ec2aab5a0610.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/7fff707ddf87544616f198155d98e215700b261e39fda3844940ec2aab5a0610.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/7fff707ddf87544616f198155d98e215700b261e39fda3844940ec2aab5a0610-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Subscript(value=Name(id='source_cache', ctx=Load()), slice=Name(id='filename', ctx=Load()), ctx=Load()) instruction = Instruction(opname='BINARY_OP', opcode=44, arg=26, argval=26, argrepr='[]', offset=24, start_offset=24, starts_line=Fa...et=15, end_col_offset=37), cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( > ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): E KeyError: '[]' executing/_position_node_finder.py:661: KeyError ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/7fff707ddf87544616f198155d98e215700b261e39fda3844940ec2aab5a0610.py mapping failed '[]' search bytecode BINARY_OP 26 ([]) in file /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/7fff707ddf87544616f198155d98e215700b261e39fda3844940ec2aab5a0610.py at position Positions(lineno=18, end_lineno=18, col_offset=15, end_col_offset=37) source code: 14: # 15: 16: def for_filename(): 17: try: 18: return source_cache[filename] 19: except KeyError: 20: pass 21: linecache possible node 18 18 28 36 Name(id='filename', ctx=Load()) possible node 18 18 15 27 Name(id='source_cache', ctx=Load()) possible node 18 18 15 37 Subscript(value=Name(id='source_cache', ctx=Load()), slice=Name(id='filename', ctx=Load()), ctx=Load()) possible node 18 18 8 37 Return(value=Subscript(value=Name(id='source_cache', ctx=Load()), slice=Name(id='filename', ctx=Load()), ctx=Load())) _ test_small_samples[867a476c53701b28e25aa4b445e586b8a6764f9f8582b98955c4352b0d8ba415.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/867a476c53701b28e25aa4b445e586b8a6764f9f8582b98955c4352b0d8ba415.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/867a476c53701b28e25aa4b445e586b8a6764f9f8582b98955c4352b0d8ba415-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = TypeAlias(name=Name(id='TA1', ctx=Store()), type_params=[TypeVar(name='B', bound=None, default_value=None)], value=Name(id='dict', ctx=Load())) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='.format', argrepr='.format', offset=2, start_offset=2...ne_number=1, label=None, positions=Positions(lineno=1, end_lineno=1, col_offset=0, end_col_offset=18), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.TypeAlias is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/867a476c53701b28e25aa4b445e586b8a6764f9f8582b98955c4352b0d8ba415.py VerifierFailure: ast.TypeAlias is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (.format) node: TypeAlias(name=Name(id='TA1', ctx=Store(), lineno=1, col_offset=5, end_lineno=1, end_col_offset=8), type_params=[TypeVar(name='B', lineno=1, col_offset=9, end_lineno=1, end_col_offset=10)], value=Name(id='dict', ctx=Load(), lineno=1, col_offset=14, end_lineno=1, end_col_offset=18), lineno=1, col_offset=0, end_lineno=1, end_col_offset=18) parent node: Module source code: 1: type TA1[B] = dict None bytecode: _ test_small_samples[8a2d183daa29dea1fdad279688a2b99dcfef00932e06d4693385dfc1634c6f6c.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/8a2d183daa29dea1fdad279688a2b99dcfef00932e06d4693385dfc1634c6f6c.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/8a2d183daa29dea1fdad279688a2b99dcfef00932e06d4693385dfc1634c6f6c-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = FunctionDef(name='func', args=arguments(posonlyargs=[], args=[arg(arg='a', annotation=None, type_comment=None)], varar...], decorator_list=[], returns=None, type_comment=None, type_params=[TypeVar(name='T', bound=None, default_value=None)]) instruction = Instruction(opname='LOAD_FAST_BORROW_LOAD_FAST_BORROW', opcode=87, arg=1, argval=('.defaults', '.kwdefaults'), argrepr...ine_number=1, label=None, positions=Positions(lineno=1, end_lineno=2, col_offset=0, end_col_offset=8), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW_LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/8a2d183daa29dea1fdad279688a2b99dcfef00932e06d4693385dfc1634c6f6c.py VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW_LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW_LOAD_FAST_BORROW 1 (.defaults, .kwdefaults) node: FunctionDef(name='func', args=arguments(args=[arg(arg='a', lineno=1, col_offset=12, end_lineno=1, end_col_offset=13)], kwonlyargs=[arg(arg='b', lineno=1, col_offset=22, end_lineno=1, end_col_offset=23)], kw_defaults=[Constant(value='b', lineno=1, col_offset=24, end_lineno=1, end_col_offset=27)], defaults=[Constant(value='a', lineno=1, col_offset=14, end_lineno=1, end_col_offset=17)]), body=[Pass(lineno=2, col_offset=4, end_lineno=2, end_col_offset=8)], type_params=[TypeVar(name='T', lineno=1, col_offset=9, end_lineno=1, end_col_offset=10)], lineno=1, col_offset=0, end_lineno=2, end_col_offset=8) parent node: Module source code: 1: def func[T](a='a', *, b='b'): 2: pass None bytecode: _ test_small_samples[8d7d8e2330522993cf517ba2f4191e01c336fb27bbbfa40815629432b96d74fa.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/8d7d8e2330522993cf517ba2f4191e01c336fb27bbbfa40815629432b96d74fa.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/8d7d8e2330522993cf517ba2f4191e01c336fb27bbbfa40815629432b96d74fa-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = ClassDef(name='SupportsAbs', bases=[], keywords=[], body=[Pass()], decorator_list=[], type_params=[TypeVar(name='T', bound=None, default_value=None)]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=2, argval='.type_params', argrepr='.type_params', offset=20, sta...ine_number=1, label=None, positions=Positions(lineno=1, end_lineno=2, col_offset=0, end_col_offset=8), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.ClassDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/8d7d8e2330522993cf517ba2f4191e01c336fb27bbbfa40815629432b96d74fa.py VerifierFailure: ast.ClassDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 2 (.type_params) node: ClassDef(name='SupportsAbs', body=[Pass(lineno=2, col_offset=4, end_lineno=2, end_col_offset=8)], type_params=[TypeVar(name='T', lineno=1, col_offset=18, end_lineno=1, end_col_offset=19)], lineno=1, col_offset=0, end_lineno=2, end_col_offset=8) parent node: Module source code: 1: class SupportsAbs[T]: 2: pass None bytecode: _ test_small_samples[91f5b684f56b415a61d211027904e023f2371952602a8d71c17416d8fa3ceed7.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/91f5b684f56b415a61d211027904e023f2371952602a8d71c17416d8fa3ceed7.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/91f5b684f56b415a61d211027904e023f2371952602a8d71c17416d8fa3ceed7-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = FunctionDef(name='__init__', args=arguments(posonlyargs=[], args=[arg(arg='self', annotation=None, type_comment=None),...body=[Expr(value=Name(id='super', ctx=Load(...)))], decorator_list=[], returns=None, type_comment=None, type_params=[]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='__class__', argrepr='__class__', offset=24, start_off...number=18, label=None, positions=Positions(lineno=18, end_lineno=19, col_offset=4, end_col_offset=13), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/91f5b684f56b415a61d211027904e023f2371952602a8d71c17416d8fa3ceed7.py VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (__class__) node: FunctionDef(name='__init__', args=arguments(args=[arg(arg='self', lineno=18, col_offset=17, end_lineno=18, end_col_offset=21), arg(arg='db_uri', lineno=18, col_offset=23, end_lineno=18, end_col_offset=29), arg(arg='num_samples', lineno=18, col_offset=36, end_lineno=18, end_col_offset=47)], defaults=[Constant(value=None, lineno=18, col_offset=30, end_lineno=18, end_col_offset=34), Constant(value=None, lineno=18, col_offset=48, end_lineno=18, end_col_offset=52)]), body=[Expr(value=Name(id='super', ctx=Load(), lineno=19, col_offset=8, end_lineno=19, end_col_offset=13), lineno=19, col_offset=8, end_lineno=19, end_col_offset=13)], lineno=18, col_offset=4, end_lineno=19, end_col_offset=13) parent node: ClassDef source code: 14: # 15: 16: class BirdsEye: 17: 18: def __init__(self, db_uri=None, num_samples=None): 19: super None bytecode: _ test_small_samples[93f00cfd350495557ead44e2dd46ac4ce7d913f6e5d86ba1b0d5044cec188438.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/93f00cfd350495557ead44e2dd46ac4ce7d913f6e5d86ba1b0d5044cec188438.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/93f00cfd350495557ead44e2dd46ac4ce7d913f6e5d86ba1b0d5044cec188438-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = ClassDef(name='ConfiguredTracer', bases=[], keywords=[], body=[Expr(value=Name(id='self', ctx=Load(...)))], decorator_list=[], type_params=[]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='self', argrepr='self', offset=8, start_offset=8, star...number=18, label=None, positions=Positions(lineno=18, end_lineno=19, col_offset=4, end_col_offset=12), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.ClassDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/93f00cfd350495557ead44e2dd46ac4ce7d913f6e5d86ba1b0d5044cec188438.py VerifierFailure: ast.ClassDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (self) node: ClassDef(name='ConfiguredTracer', body=[Expr(value=Name(id='self', ctx=Load(), lineno=19, col_offset=8, end_lineno=19, end_col_offset=12), lineno=19, col_offset=8, end_lineno=19, end_col_offset=12)], lineno=18, col_offset=4, end_lineno=19, end_col_offset=12) parent node: FunctionDef source code: 14: # 15: 16: def __init__(self, out=None, prefix='', columns='time', overwrite=False, color=None, enabled=True, watch_extras=(), replace_watch_extras=None, formatter_class=DefaultFormatter): 17: 18: class ConfiguredTracer: 19: self None bytecode: _ test_small_samples[9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = AsyncFunctionDef(name='_start', args=arguments(posonlyargs=[], args=[arg(arg='self', annotation=Name(...), type_commen...Cloud', ctx=Load(...)), slice=Name(id='IsAsynchronous', ctx=Load(...)), ctx=Load()), type_comment=None, type_params=[]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='format', argrepr='format', offset=2, start_offset=2, ..._number=18, label=None, positions=Positions(lineno=18, end_lineno=19, col_offset=0, end_col_offset=8), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.AsyncFunctionDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43.py VerifierFailure: ast.AsyncFunctionDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (format) node: AsyncFunctionDef(name='_start', args=arguments(args=[arg(arg='self', annotation=Name(id='Cloud', ctx=Load(), lineno=18, col_offset=23, end_lineno=18, end_col_offset=28), lineno=18, col_offset=17, end_lineno=18, end_col_offset=28)]), body=[Pass(lineno=19, col_offset=4, end_lineno=19, end_col_offset=8)], returns=Subscript(value=Name(id='Cloud', ctx=Load(), lineno=18, col_offset=33, end_lineno=18, end_col_offset=38), slice=Name(id='IsAsynchronous', ctx=Load(), lineno=18, col_offset=39, end_lineno=18, end_col_offset=53), ctx=Load(), lineno=18, col_offset=33, end_lineno=18, end_col_offset=54), lineno=18, col_offset=0, end_lineno=19, end_col_offset=8) parent node: Module source code: 14: # 15: 16: from __future__ import annotations, with_statement 17: 18: async def _start(self: Cloud) -> Cloud[IsAsynchronous]: 19: pass None bytecode: _ test_small_samples[9f7d4ed823cb426db2e435dd7856f07c9965a88102bd63e5640a7e63250e2718.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/9f7d4ed823cb426db2e435dd7856f07c9965a88102bd63e5640a7e63250e2718.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/9f7d4ed823cb426db2e435dd7856f07c9965a88102bd63e5640a7e63250e2718-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Subscript(value=Name(id='hangs', ctx=Load()), slice=Name(id='depth', ctx=Load()), ctx=Load()) instruction = Instruction(opname='BINARY_OP', opcode=44, arg=26, argval=26, argrepr='[]', offset=6, start_offset=6, starts_line=Fals...set=3, end_col_offset=15), cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( > ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): E KeyError: '[]' executing/_position_node_finder.py:661: KeyError ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/9f7d4ed823cb426db2e435dd7856f07c9965a88102bd63e5640a7e63250e2718.py mapping failed '[]' search bytecode BINARY_OP 26 ([]) in file /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/9f7d4ed823cb426db2e435dd7856f07c9965a88102bd63e5640a7e63250e2718.py at position Positions(lineno=18, end_lineno=18, col_offset=3, end_col_offset=15) source code: 14: # pass 15: # 16: # 17: 18: if hangs[depth]: 19: hang possible node 18 18 3 8 Name(id='hangs', ctx=Load()) possible node 18 18 9 14 Name(id='depth', ctx=Load()) possible node 18 18 3 15 Subscript(value=Name(id='hangs', ctx=Load()), slice=Name(id='depth', ctx=Load()), ctx=Load()) _ test_small_samples[a2389f211aec4c553b1cec683b416480636d7c13d10e8db50b5da567192ce42f.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/a2389f211aec4c553b1cec683b416480636d7c13d10e8db50b5da567192ce42f.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/a2389f211aec4c553b1cec683b416480636d7c13d10e8db50b5da567192ce42f-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = ClassDef(name='Foo', bases=[], keywords=[], body=[Pass()], decorator_list=[], type_params=[TypeVar(name='__T', bound=None, default_value=None)]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=2, argval='.type_params', argrepr='.type_params', offset=20, sta...ine_number=1, label=None, positions=Positions(lineno=1, end_lineno=2, col_offset=0, end_col_offset=8), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.ClassDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/a2389f211aec4c553b1cec683b416480636d7c13d10e8db50b5da567192ce42f.py VerifierFailure: ast.ClassDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 2 (.type_params) node: ClassDef(name='Foo', body=[Pass(lineno=2, col_offset=4, end_lineno=2, end_col_offset=8)], type_params=[TypeVar(name='__T', lineno=1, col_offset=10, end_lineno=1, end_col_offset=13)], lineno=1, col_offset=0, end_lineno=2, end_col_offset=8) parent node: Module source code: 1: class Foo[__T]: 2: pass None bytecode: _ test_small_samples[a35a3b669faf7fa486c7ca0a95a61efab9591a0d1677406c48c53e1a04ebe850.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/a35a3b669faf7fa486c7ca0a95a61efab9591a0d1677406c48c53e1a04ebe850.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/a35a3b669faf7fa486c7ca0a95a61efab9591a0d1677406c48c53e1a04ebe850-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Name(id='_Func', ctx=Load()) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='.format', argrepr='.format', offset=2, start_offset=2...e_number=1, label=None, positions=Positions(lineno=1, end_lineno=1, col_offset=16, end_col_offset=21), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.Name is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/a35a3b669faf7fa486c7ca0a95a61efab9591a0d1677406c48c53e1a04ebe850.py VerifierFailure: ast.Name is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (.format) node: Name(id='_Func', ctx=Load(), lineno=1, col_offset=16, end_lineno=1, end_col_offset=21) parent node: TypeVar source code: 1: def override[F: _Func](): 2: pass None bytecode: _ test_small_samples[ae9b3821230822abe9910bb1ebfe74ff2cedc19f646975fb2931f4b67fd4f189.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/ae9b3821230822abe9910bb1ebfe74ff2cedc19f646975fb2931f4b67fd4f189.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/ae9b3821230822abe9910bb1ebfe74ff2cedc19f646975fb2931f4b67fd4f189-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Subscript(value=Name(id='tuple', ctx=Load()), slice=Tuple(elts=[Starred(value=Name(...), ctx=Load(...))], ctx=Load()), ctx=Load()) instruction = Instruction(opname='BINARY_OP', opcode=44, arg=26, argval=26, argrepr='[]', offset=12, start_offset=12, starts_line=Fa...fset=0, end_col_offset=9), cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( > ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): E KeyError: '[]' executing/_position_node_finder.py:661: KeyError ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/ae9b3821230822abe9910bb1ebfe74ff2cedc19f646975fb2931f4b67fd4f189.py mapping failed '[]' search bytecode BINARY_OP 26 ([]) in file /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/ae9b3821230822abe9910bb1ebfe74ff2cedc19f646975fb2931f4b67fd4f189.py at position Positions(lineno=1, end_lineno=1, col_offset=0, end_col_offset=9) source code: 1: tuple[*a] possible node 1 1 7 8 Name(id='a', ctx=Load()) possible node 1 1 6 8 Tuple(elts=[Starred(value=Name(id='a', ctx=Load()), ctx=Load())], ctx=Load()) possible node 1 1 6 8 Starred(value=Name(id='a', ctx=Load()), ctx=Load()) possible node 1 1 0 5 Name(id='tuple', ctx=Load()) possible node 1 1 0 9 Expr(value=Subscript(value=Name(id='tuple', ctx=Load()), slice=Tuple(elts=[Starred(value=Name(id='a', ctx=Load()), ctx=Load())], ctx=Load()), ctx=Load())) possible node 1 1 0 9 Subscript(value=Name(id='tuple', ctx=Load()), slice=Tuple(elts=[Starred(value=Name(id='a', ctx=Load()), ctx=Load())], ctx=Load()), ctx=Load()) _ test_small_samples[b8be3216d583e1ce26486ee2aff5cbe74fed88ebba7118db80a375c9514d1bc1.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/b8be3216d583e1ce26486ee2aff5cbe74fed88ebba7118db80a375c9514d1bc1.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/b8be3216d583e1ce26486ee2aff5cbe74fed88ebba7118db80a375c9514d1bc1-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Name(id='S', ctx=Load()) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=2, argval='S', argrepr='S', offset=16, start_offset=16, starts_l...e_number=1, label=None, positions=Positions(lineno=1, end_lineno=1, col_offset=15, end_col_offset=16), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.Name is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/b8be3216d583e1ce26486ee2aff5cbe74fed88ebba7118db80a375c9514d1bc1.py VerifierFailure: ast.Name is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 2 (S) node: Name(id='S', ctx=Load(), lineno=1, col_offset=15, end_lineno=1, end_col_offset=16) parent node: TypeVar source code: 1: def func[S, T: S](): 2: pass None bytecode: _ test_small_samples[baeab95d7182162c404ae9662cf716dba0a7d7c7662266307ae591a273993ea5.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/baeab95d7182162c404ae9662cf716dba0a7d7c7662266307ae591a273993ea5.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/baeab95d7182162c404ae9662cf716dba0a7d7c7662266307ae591a273993ea5-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Subscript(value=Name(id='Sequence', ctx=Load()), slice=Name(id='S', ctx=Load()), ctx=Load()) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=2, argval='S', argrepr='S', offset=16, start_offset=16, starts_l...e_number=1, label=None, positions=Positions(lineno=1, end_lineno=1, col_offset=15, end_col_offset=26), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.Subscript is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/baeab95d7182162c404ae9662cf716dba0a7d7c7662266307ae591a273993ea5.py VerifierFailure: ast.Subscript is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 2 (S) node: Subscript(value=Name(id='Sequence', ctx=Load(), lineno=1, col_offset=15, end_lineno=1, end_col_offset=23), slice=Name(id='S', ctx=Load(), lineno=1, col_offset=24, end_lineno=1, end_col_offset=25), ctx=Load(), lineno=1, col_offset=15, end_lineno=1, end_col_offset=26) parent node: TypeVar source code: 1: def func[S, T: Sequence[S]](): 2: pass None bytecode: _ test_small_samples[c069969a742f2faa3f432cb50c36f58a8158cdae7c19ce0536464b3f3e4b1dd9.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/c069969a742f2faa3f432cb50c36f58a8158cdae7c19ce0536464b3f3e4b1dd9.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/c069969a742f2faa3f432cb50c36f58a8158cdae7c19ce0536464b3f3e4b1dd9-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = TypeAlias(name=Name(id='TA2', ctx=Store()), type_params=[], value=Name(id='TA1', ctx=Load())) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=1, argval='TA1', argrepr='TA1', offset=28, start_offset=28, star...ne_number=3, label=None, positions=Positions(lineno=3, end_lineno=3, col_offset=4, end_col_offset=18), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.TypeAlias is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/c069969a742f2faa3f432cb50c36f58a8158cdae7c19ce0536464b3f3e4b1dd9.py VerifierFailure: ast.TypeAlias is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 1 (TA1) node: TypeAlias(name=Name(id='TA2', ctx=Store(), lineno=3, col_offset=9, end_lineno=3, end_col_offset=12), value=Name(id='TA1', ctx=Load(), lineno=3, col_offset=15, end_lineno=3, end_col_offset=18), lineno=3, col_offset=4, end_lineno=3, end_col_offset=18) parent node: FunctionDef source code: 1: def test_alias_value_01(): 2: type TA1 = int 3: type TA2 = TA1 None bytecode: _ test_small_samples[c9b64c28f424df67919f825adf4f93dfa774463768fc26cd36964121d34e28dd.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/c9b64c28f424df67919f825adf4f93dfa774463768fc26cd36964121d34e28dd.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/c9b64c28f424df67919f825adf4f93dfa774463768fc26cd36964121d34e28dd-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = FunctionDef(name='main', args=arguments(posonlyargs=[], args=[arg(arg='argv', annotation=Name(...), type_comment=None)...(...))], type_comment=None)], decorator_list=[], returns=Name(id='int', ctx=Load()), type_comment=None, type_params=[]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='format', argrepr='format', offset=2, start_offset=2, ...number=16, label=None, positions=Positions(lineno=16, end_lineno=22, col_offset=0, end_col_offset=22), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/c9b64c28f424df67919f825adf4f93dfa774463768fc26cd36964121d34e28dd.py VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (format) node: FunctionDef(name='main', args=arguments(args=[arg(arg='argv', annotation=Name(id='Sequence', ctx=Load(), lineno=16, col_offset=15, end_lineno=16, end_col_offset=23), lineno=16, col_offset=9, end_lineno=16, end_col_offset=23)], defaults=[Constant(value=None, lineno=16, col_offset=24, end_lineno=16, end_col_offset=28)]), body=[With(items=[withitem(context_expr=Name(id='error_handler', ctx=Load(), lineno=17, col_offset=9, end_lineno=17, end_col_offset=22))], body=[If(test=Name(id='args', ctx=Load(), lineno=18, col_offset=11, end_lineno=18, end_col_offset=15), body=[Return(value=Name(id='uninstall', ctx=Load(), lineno=19, col_offset=19, end_lineno=19, end_col_offset=28), lineno=19, col_offset=12, end_lineno=19, end_col_offset=28)], orelse=[Raise(exc=Name(id='NotImplementedError', ctx=Load(), lineno=21, col_offset=18, end_lineno=21, end_col_offset=37), lineno=21, col_offset=12, end_lineno=21, end_col_offset=37)], lineno=18, col_offset=8, end_lineno=21, end_col_offset=37), Expr(value=Name(id='AssertionError', ctx=Load(), lineno=22, col_offset=8, end_lineno=22, end_col_offset=22), lineno=22, col_offset=8, end_lineno=22, end_col_offset=22)], lineno=17, col_offset=4, end_lineno=22, end_col_offset=22)], returns=Name(id='int', ctx=Load(), lineno=16, col_offset=33, end_lineno=16, end_col_offset=36), lineno=16, col_offset=0, end_lineno=22, end_col_offset=22) parent node: Module source code: 12: # elif isinstance(node, ast.Match): 13: # self.walk_deadcode(node.subject, deadcode) 14: # 15: 16: def main(argv: Sequence=None) -> int: 17: with error_handler: 18: if args: 19: return uninstall 20: else: 21: raise NotImplementedError 22: AssertionError None bytecode: _ test_small_samples[d06afcef230a0babce66218961fb7dc171e71ae19f194ebf34e85e3c9501eda7.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/d06afcef230a0babce66218961fb7dc171e71ae19f194ebf34e85e3c9501eda7.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/d06afcef230a0babce66218961fb7dc171e71ae19f194ebf34e85e3c9501eda7-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/d06afcef230a0babce66218961fb7dc171e71ae19f194ebf34e85e3c9501eda7.py' check_names = True def check_filename(self, filename, check_names): # increase the recursion limit in testing mode, because there are files out there with large ast-nodes # example: tests/small_samples/1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc.py sys.setrecursionlimit(3000) try: source = Source.for_filename(filename) except RecursionError: if sys.version_info>=(3,13): # sys.setrecursionlimit has no effect for cpython 3.13 pytest.skip("cpython has a hard recursion limit") else: raise if source.tree is None: # we could not parse this file (maybe wrong python version) print("skip %s"%filename) return print("check %s"%filename) nodes = defaultdict(list) decorators = defaultdict(list) expected_decorators = {} for node in ast.walk(source.tree): if isinstance(node, ( (ast.Name,) * check_names, ast.UnaryOp, ast.BinOp, ast.Subscript, ast.Call, ast.Compare, ast.Attribute )): nodes[node] = [] elif isinstance(node, (ast.ClassDef, function_node_types)): expected_decorators[(node.lineno, node.name)] = node.decorator_list[::-1] decorators[(node.lineno, node.name)] = [] try: code = compile(source.tree, source.filename, "exec", dont_inherit=True) except SyntaxError: # for example: # SyntaxError: 'return' outside function print("skip %s" % filename) return except RecursionError: print("skip %s" % filename) return if sys.version_info < (3, 11): for subcode, qualname in find_qualnames(code): if not qualname.endswith(">"): code_qualname = source.code_qualname(subcode) assert code_qualname == qualname result = list(self.check_code(code, nodes, decorators, check_names=check_names)) if not re.search(r'^\s*if 0(:| and )', source.text, re.MULTILINE): for node, values in nodes.items(): # skip some cases cases if sys.version_info < (3, 11): if is_unary_not(node): continue if sys.version_info >= (3, 6): if is_annotation(node): continue ctx = getattr(node, 'ctx', None) if isinstance(ctx, ast.Store): # Assignment to attributes and subscripts is less magical # but can also fail fairly easily, so we can't guarantee # that every node can be identified with some instruction. continue if isinstance(ctx, (ast.Del, getattr(ast, 'Param', ()))): assert not values, [ast.dump(node), values] continue if isinstance(node, ast.Compare): if sys.version_info >= (3, 10): continue if len(node.ops) > 1: assert not values continue if is_unary_not(node.parent) and isinstance( node.ops[0], (ast.In, ast.Is) ): continue if is_literal(node): continue if isinstance(node,ast.Name) and node.id=="__debug__": continue else: # x (is/is not) None none_comparison = ( isinstance(node, ast.Compare) and len(node.ops) == 1 and isinstance(node.ops[0], (ast.IsNot, ast.Is)) and len(node.comparators) == 1 and isinstance(node.comparators[0], ast.Constant) and node.comparators[0].value == None ) if is_unary_not(node) or none_comparison: # some ast-nodes are transformed into control flow, if it is used at places like `if not a: ...` # There are no bytecode instructions which can be mapped to this ast-node, # because the compiler generates POP_JUMP_FORWARD_IF_TRUE which mapps to the `if` statement. # only code like `a=not b` generates a UNARY_NOT # handles cases like # if not x is None: ... # assert a if cnd else not b first_node = node while is_unary_not(first_node.parent) or ( isinstance(first_node.parent, ast.IfExp) and first_node in (first_node.parent.body, first_node.parent.orelse) ): first_node = first_node.parent if isinstance(first_node.parent,(ast.If,ast.Assert,ast.While,ast.IfExp)) and first_node is first_node.parent.test: continue if isinstance(first_node.parent,(ast.match_case)) and first_node is first_node.parent.guard: continue if isinstance(first_node.parent,(ast.BoolOp,ast.Return)): continue if isinstance(first_node.parent,(ast.comprehension)) and first_node in first_node.parent.ifs: continue if isinstance(first_node.parent,(ast.comprehension)) and first_node in first_node.parent.ifs: continue if ( isinstance(node, ast.UnaryOp) and isinstance(node.op, ast.Not) and isinstance(node.operand, ast.Compare) and len(node.operand.ops) == 1 and isinstance(node.operand.ops[0], (ast.In,ast.Is)) ): # `not a in l` the not becomes part of the comparison continue if is_annotation(node): continue if is_literal(node) and not isinstance(node, ast.Constant): continue if isinstance(node,ast.Name) and node.id=="__debug__": continue if isinstance(node, ast.Compare) and len(node.comparators) > 1: continue if is_pattern(node): continue if ( isinstance(node, ast.BinOp) and isinstance(node.op, ast.Mod) and isinstance(node.left, ast.Constant) and isinstance(node.right, ast.Tuple) and isinstance(node.left.value, str) and re.fullmatch(r"%(-?\d+)?[sr]", node.left.value) ): # "%50s"%(a,) is missing an BUILD_STRING instruction which normally maps to BinOp continue if ( isinstance(node, ast.Name) and isinstance(node.ctx, ast.Store) and node.id == "__classcell__" ): continue if sys.version_info >= (3, 12): if ( isinstance(node, ast.Call) and isinstance(node.func, ast.Name) and node.func.id == "super" ): # super optimization continue if isinstance(node, ast.Name) and isinstance( node.parent, ast.TypeAlias ): # type alias names have no associated bytecode continue if sys.version_info >= (3, 13): if isinstance(node, ast.Name): # STORE_FAST_STORE_FAST is generated from two ast nodes, and can not be mapped back continue if ( isinstance(node, ast.UnaryOp) and isinstance(node.op, ast.Not) and ( isinstance(node.operand, ast.UnaryOp) and isinstance(node.operand.op, ast.Not) or isinstance(node.parent, ast.UnaryOp) and isinstance(node.parent.op, ast.Not) ) ): # `not not x` is optimized to a single TO_BOOL continue # the deadcode check has to be the last check because it is expensive if len(values)==0 and is_deadcode(node): continue if sys.version_info >= (3, 10): correct = len(values) >= 1 elif sys.version_info >= (3, 9) and in_finally(node): correct = len(values) > 1 else: correct = len(values) == 1 if not correct: def p(*args): print(*args, file=sys.stderr) p("node without associated Bytecode") p("in file:", filename) p("correct:", correct) p("len(values):", len(values)) p("values:", values) p("deadcode:", is_deadcode(node)) p() p("ast node:") p(ast_dump(node, indent=4)) parents = [] parent = node while hasattr(parent, "parent"): parent = parent.parent parents.append(parent) p("parents:", parents) if sys.version_info >= (3,8): p( "node range:", "lineno=%s" % node.lineno, "end_lineno=%s" % node.end_lineno, "col_offset=%s" % node.col_offset, "end_col_offset=%s" % node.end_col_offset, ) else: p("line:",node.lineno) dump_source( source.text, start_position(node), end_position(node), file=sys.stderr, ) p() if sys.version_info >= (3, 11): p("all bytecodes in this range:") bc = compile(source.text, filename, "exec") def inspect(bc): first = True for i in dis.get_instructions(bc): if ( i.positions.lineno is not None and i.positions.lineno <= node.end_lineno and node.lineno <= i.positions.end_lineno ): if first: p("block name:", bc.co_name) first = False p(i.positions, i.opname, i.argval) for const in bc.co_consts: if isinstance(const, types.CodeType): inspect(const) inspect(bc) > raise AssertionError() E AssertionError tests/test_main.py:1135: AssertionError ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/d06afcef230a0babce66218961fb7dc171e71ae19f194ebf34e85e3c9501eda7.py ----------------------------- Captured stderr call ----------------------------- node without associated Bytecode in file: /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/d06afcef230a0babce66218961fb7dc171e71ae19f194ebf34e85e3c9501eda7.py correct: False len(values): 0 values: [] deadcode: False ast node: Subscript( value=Name(id='src', ctx=Load()), slice=Name(id='start_pos', ctx=Load()), ctx=Load()) parents: [AugAssign(target=Name(id='result', ctx=Store()), op=Add(), value=Subscript(value=Name(id='src', ctx=Load(...)), slice=Name(id='start_pos', ctx=Load(...)), ctx=Load())), Module(body=[AugAssign(target=Name(id='result', ctx=Store(...)), op=Add(), value=Subscript(value=Name(...), slice=Name(...), ctx=Load(...)))], type_ignores=[])] node range: lineno=17 end_lineno=17 col_offset=10 end_col_offset=24 source code: 13: # ) and inst_match( 14: # ("LOAD_NAME", "LOAD_FAST", "LOAD_GLOBAL", "LOAD_DEREF"), argval=mangled_name(node) 15: # 16: 17: result += src[start_pos] all bytecodes in this range: block name: Positions(lineno=17, end_lineno=17, col_offset=0, end_col_offset=6) LOAD_NAME result Positions(lineno=17, end_lineno=17, col_offset=10, end_col_offset=13) LOAD_NAME src Positions(lineno=17, end_lineno=17, col_offset=14, end_col_offset=23) LOAD_NAME start_pos Positions(lineno=17, end_lineno=17, col_offset=10, end_col_offset=24) BINARY_OP 26 Positions(lineno=17, end_lineno=17, col_offset=0, end_col_offset=24) BINARY_OP 13 Positions(lineno=17, end_lineno=17, col_offset=0, end_col_offset=6) STORE_NAME result Positions(lineno=17, end_lineno=17, col_offset=0, end_col_offset=6) LOAD_CONST None Positions(lineno=17, end_lineno=17, col_offset=0, end_col_offset=6) RETURN_VALUE None _ test_small_samples[d88dbf79f1c03ac9d231408b03584e8396ab41a959edecfde86b82df8ee7c918.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/d88dbf79f1c03ac9d231408b03584e8396ab41a959edecfde86b82df8ee7c918.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/d88dbf79f1c03ac9d231408b03584e8396ab41a959edecfde86b82df8ee7c918-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = ClassDef(name='C', bases=[], keywords=[], body=[Nonlocal(names=['__firstlineno__'])], decorator_list=[], type_params=[]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=1, argval='__firstlineno__', argrepr='__firstlineno__', offset=1...ne_number=4, label=None, positions=Positions(lineno=4, end_lineno=5, col_offset=4, end_col_offset=32), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.ClassDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/d88dbf79f1c03ac9d231408b03584e8396ab41a959edecfde86b82df8ee7c918.py VerifierFailure: ast.ClassDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 1 (__firstlineno__) node: ClassDef(name='C', body=[Nonlocal(names=['__firstlineno__'], lineno=5, col_offset=8, end_lineno=5, end_col_offset=32)], lineno=4, col_offset=4, end_lineno=5, end_col_offset=32) parent node: FunctionDef source code: 1: def test_getsource_on_class_without_firstlineno(): 2: __firstlineno__ = 0 3: 4: class C: 5: nonlocal __firstlineno__ None bytecode: _ test_small_samples[d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = AsyncFunctionDef(name='get_message', args=arguments(posonlyargs=[], args=[arg(arg='self', annotation=None, type_commen...aults=[]), body=[Pass()], decorator_list=[], returns=Name(id='Message', ctx=Load()), type_comment=None, type_params=[]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='format', argrepr='format', offset=2, start_offset=2, ..._number=18, label=None, positions=Positions(lineno=18, end_lineno=19, col_offset=0, end_col_offset=8), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.AsyncFunctionDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d.py VerifierFailure: ast.AsyncFunctionDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (format) node: AsyncFunctionDef(name='get_message', args=arguments(args=[arg(arg='self', lineno=18, col_offset=22, end_lineno=18, end_col_offset=26)]), body=[Pass(lineno=19, col_offset=4, end_lineno=19, end_col_offset=8)], returns=Name(id='Message', ctx=Load(), lineno=18, col_offset=31, end_lineno=18, end_col_offset=38), lineno=18, col_offset=0, end_lineno=19, end_col_offset=8) parent node: Module source code: 14: # 15: 16: from __future__ import annotations 17: 18: async def get_message(self) -> Message: 19: pass None bytecode: _ test_small_samples[dcf515466528197be9497b7a599fedb9ad7837e4c66d9356a426ce86c8742123.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/dcf515466528197be9497b7a599fedb9ad7837e4c66d9356a426ce86c8742123.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/dcf515466528197be9497b7a599fedb9ad7837e4c66d9356a426ce86c8742123-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = TypeAlias(name=Name(id='ClassLevel', ctx=Store()), type_params=[], value=Name(id='str', ctx=Load())) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='__classdict__', argrepr='__classdict__', offset=26, s...ne_number=2, label=None, positions=Positions(lineno=2, end_lineno=2, col_offset=4, end_col_offset=25), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.TypeAlias is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/dcf515466528197be9497b7a599fedb9ad7837e4c66d9356a426ce86c8742123.py VerifierFailure: ast.TypeAlias is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (__classdict__) node: TypeAlias(name=Name(id='ClassLevel', ctx=Store(), lineno=2, col_offset=9, end_lineno=2, end_col_offset=19), value=Name(id='str', ctx=Load(), lineno=2, col_offset=22, end_lineno=2, end_col_offset=25), lineno=2, col_offset=4, end_lineno=2, end_col_offset=25) parent node: ClassDef source code: 1: class TypeAliasPickleTest: 2: type ClassLevel = str 3: 4: def test_pickling_local(): 5: pass None bytecode: ___________________ test_small_samples[deadcode_listcomp.py] ___________________ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/deadcode_listcomp.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/deadcode_listcomp-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = GeneratorExp(elt=BinOp(left=Name(id='v', ctx=Load(...)), op=Add(), right=Constant(value=1, kind=None)), generators=[co...=Name(id='v', ctx=Store(...)), iter=List(elts=[], ctx=Load(...)), ifs=[Constant(value=False, kind=None)], is_async=0)]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='.0', argrepr='.0', offset=6, start_offset=6, starts_l...ne_number=6, label=None, positions=Positions(lineno=6, end_lineno=6, col_offset=0, end_col_offset=26), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.GeneratorExp is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/deadcode_listcomp.py VerifierFailure: ast.GeneratorExp is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (.0) node: GeneratorExp(elt=BinOp(left=Name(id='v', ctx=Load(), lineno=6, col_offset=1, end_lineno=6, end_col_offset=2), op=Add(), right=Constant(value=1, lineno=6, col_offset=3, end_lineno=6, end_col_offset=4), lineno=6, col_offset=1, end_lineno=6, end_col_offset=4), generators=[comprehension(target=Name(id='v', ctx=Store(), lineno=6, col_offset=9, end_lineno=6, end_col_offset=10), iter=List(ctx=Load(), lineno=6, col_offset=14, end_lineno=6, end_col_offset=16), ifs=[Constant(value=False, lineno=6, col_offset=20, end_lineno=6, end_col_offset=25)], is_async=0)], lineno=6, col_offset=0, end_lineno=6, end_col_offset=26) parent node: Expr source code: 2: 3: 4: [v+1 for v in [] if False] 5: {v+1 for v in [] if False} 6: (v+1 for v in [] if False) 7: {v+1:v+2 for v in [] if False} 8: 9: [v+1 for v in [] if v+5 if False if v+6] None bytecode: _ test_small_samples[e0d5430c6d9ee891b8adb6dc69d571ada7b1da181b905e47bc09bd291b90b3db.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/e0d5430c6d9ee891b8adb6dc69d571ada7b1da181b905e47bc09bd291b90b3db.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/e0d5430c6d9ee891b8adb6dc69d571ada7b1da181b905e47bc09bd291b90b3db-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = ClassDef(name='SupportsAbs', bases=[], keywords=[], body=[FunctionDef(name='__abs__', args=arguments(posonlyargs=[], a...ype_comment=None, type_params=[])], decorator_list=[], type_params=[TypeVar(name='T', bound=None, default_value=None)]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=1, argval='.type_params', argrepr='.type_params', offset=22, sta...ne_number=1, label=None, positions=Positions(lineno=1, end_lineno=4, col_offset=0, end_col_offset=12), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.ClassDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/e0d5430c6d9ee891b8adb6dc69d571ada7b1da181b905e47bc09bd291b90b3db.py VerifierFailure: ast.ClassDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 1 (.type_params) node: ClassDef(name='SupportsAbs', body=[FunctionDef(name='__abs__', args=arguments(), body=[Pass(lineno=4, col_offset=8, end_lineno=4, end_col_offset=12)], returns=Name(id='T', ctx=Load(), lineno=3, col_offset=21, end_lineno=3, end_col_offset=22), lineno=3, col_offset=4, end_lineno=4, end_col_offset=12)], type_params=[TypeVar(name='T', lineno=1, col_offset=18, end_lineno=1, end_col_offset=19)], lineno=1, col_offset=0, end_lineno=4, end_col_offset=12) parent node: Module source code: 1: class SupportsAbs[T]: 2: 3: def __abs__() -> T: 4: pass None bytecode: _ test_small_samples[e463c913f286b9b53abcb9cca02fa76b9d85c4e100607ed26947a49b42bb0499.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/e463c913f286b9b53abcb9cca02fa76b9d85c4e100607ed26947a49b42bb0499.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/e463c913f286b9b53abcb9cca02fa76b9d85c4e100607ed26947a49b42bb0499-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = AsyncFunctionDef(name='inner', args=arguments(posonlyargs=[], args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwa... body=[Expr(value=Name(id='func', ctx=Load(...)))], decorator_list=[], returns=None, type_comment=None, type_params=[]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='func', argrepr='func', offset=4, start_offset=4, star...ne_number=3, label=None, positions=Positions(lineno=3, end_lineno=4, col_offset=4, end_col_offset=12), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.AsyncFunctionDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/e463c913f286b9b53abcb9cca02fa76b9d85c4e100607ed26947a49b42bb0499.py VerifierFailure: ast.AsyncFunctionDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (func) node: AsyncFunctionDef(name='inner', args=arguments(), body=[Expr(value=Name(id='func', ctx=Load(), lineno=4, col_offset=8, end_lineno=4, end_col_offset=12), lineno=4, col_offset=8, end_lineno=4, end_col_offset=12)], lineno=3, col_offset=4, end_lineno=4, end_col_offset=12) parent node: FunctionDef source code: 1: def __call__(func): 2: 3: async def inner(): 4: func None bytecode: _ test_small_samples[e796977fbd5072af21adf19dd5ea5b6dd5e8affb91d39e280718aea2a7736fb9.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/e796977fbd5072af21adf19dd5ea5b6dd5e8affb91d39e280718aea2a7736fb9.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/e796977fbd5072af21adf19dd5ea5b6dd5e8affb91d39e280718aea2a7736fb9-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = AnnAssign(target=Name(id='data', ctx=Store()), annotation=Name(id='NestedDict', ctx=Load()), value=None, simple=1) instruction = Instruction(opname='STORE_NAME', opcode=116, arg=1, argval='__annotate__', argrepr='__annotate__', offset=8, start_off...number=16, label=None, positions=Positions(lineno=16, end_lineno=16, col_offset=0, end_col_offset=16), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.AnnAssign is not created from STORE_NAME executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/e796977fbd5072af21adf19dd5ea5b6dd5e8affb91d39e280718aea2a7736fb9.py VerifierFailure: ast.AnnAssign is not created from STORE_NAME instruction: STORE_NAME 1 (__annotate__) node: AnnAssign(target=Name(id='data', ctx=Store(), lineno=16, col_offset=0, end_lineno=16, end_col_offset=4), annotation=Name(id='NestedDict', ctx=Load(), lineno=16, col_offset=6, end_lineno=16, end_col_offset=16), simple=1, lineno=16, col_offset=0, end_lineno=16, end_col_offset=16) parent node: Module source code: 12: # ): 13: # return 14: # 15: 16: data: NestedDict None bytecode: _ test_small_samples[e8a94f0a994ea84627b7cbc9132cf519ccaa6d756f8cb3458cf019e672a510a4.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/e8a94f0a994ea84627b7cbc9132cf519ccaa6d756f8cb3458cf019e672a510a4.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/e8a94f0a994ea84627b7cbc9132cf519ccaa6d756f8cb3458cf019e672a510a4-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Name(id='i', ctx=Load()) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='i', argrepr='i', offset=74, start_offset=74, starts_l...umber=18, label=None, positions=Positions(lineno=18, end_lineno=18, col_offset=29, end_col_offset=30), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.Name is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/e8a94f0a994ea84627b7cbc9132cf519ccaa6d756f8cb3458cf019e672a510a4.py VerifierFailure: ast.Name is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (i) node: Name(id='i', ctx=Load(), lineno=18, col_offset=29, end_lineno=18, end_col_offset=30) parent node: Subscript source code: 14: # 15: 16: def _get_windows_argv(): 17: try: 18: argv = [argv_unicode[i] for i in range(0, argc.value)] 19: finally: 20: del argv_unicode None bytecode: _ test_small_samples[ea94f24a1d9b57c7a7d62c428082790caae2fa16429db2e58b2f4addb67a1964.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/ea94f24a1d9b57c7a7d62c428082790caae2fa16429db2e58b2f4addb67a1964.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/ea94f24a1d9b57c7a7d62c428082790caae2fa16429db2e58b2f4addb67a1964-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Name(id='open_with_encoding_check', ctx=Load()) instruction = Instruction(opname='CALL', opcode=52, arg=0, argval=0, argrepr='', offset=34, start_offset=34, starts_line=False, line..., col_offset=9, end_col_offset=33), cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.Name is not created from CALL executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/ea94f24a1d9b57c7a7d62c428082790caae2fa16429db2e58b2f4addb67a1964.py VerifierFailure: ast.Name is not created from CALL instruction: CALL 0 node: Name(id='open_with_encoding_check', ctx=Load(), lineno=18, col_offset=9, end_lineno=18, end_col_offset=33) parent node: withitem source code: 14: # 15: 16: def read_source_file(filename): 17: from lib2to3.pgen2.tokenize import cookie_re 18: with open_with_encoding_check as f: 19: [cookie_re for i, line in enumerate] None bytecode: _ test_small_samples[f4486595a4c229797a00be326b58743a5a386e343d70c54d451de212f97a7a8b.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/f4486595a4c229797a00be326b58743a5a386e343d70c54d451de212f97a7a8b.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/f4486595a4c229797a00be326b58743a5a386e343d70c54d451de212f97a7a8b-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = FunctionDef(name='reveal_type', args=arguments(posonlyargs=[], args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kw..., returns=Name(id='T', ctx=Load()), type_comment=None, type_params=[TypeVar(name='T', bound=None, default_value=None)]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=1, argval='T', argrepr='T', offset=14, start_offset=14, starts_l...ine_number=1, label=None, positions=Positions(lineno=1, end_lineno=2, col_offset=0, end_col_offset=8), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/f4486595a4c229797a00be326b58743a5a386e343d70c54d451de212f97a7a8b.py VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 1 (T) node: FunctionDef(name='reveal_type', args=arguments(), body=[Pass(lineno=2, col_offset=4, end_lineno=2, end_col_offset=8)], returns=Name(id='T', ctx=Load(), lineno=1, col_offset=24, end_lineno=1, end_col_offset=25), type_params=[TypeVar(name='T', lineno=1, col_offset=16, end_lineno=1, end_col_offset=17)], lineno=1, col_offset=0, end_lineno=2, end_col_offset=8) parent node: Module source code: 1: def reveal_type[T]() -> T: 2: pass None bytecode: _ test_small_samples[f4962cd6e6b77f4f1d6f676de32f29200067bf3ac05c63e1d60ef2823b4d1b10.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/f4962cd6e6b77f4f1d6f676de32f29200067bf3ac05c63e1d60ef2823b4d1b10.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/f4962cd6e6b77f4f1d6f676de32f29200067bf3ac05c63e1d60ef2823b4d1b10-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = FunctionDef(name='__instancecheck__', args=arguments(posonlyargs=[], args=[], vararg=None, kwonlyargs=[], kw_defaults=...l(...), attr='__instancecheck__', ctx=Load(...)))], decorator_list=[], returns=None, type_comment=None, type_params=[]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='__class__', argrepr='__class__', offset=22, start_off...ne_number=3, label=None, positions=Positions(lineno=3, end_lineno=5, col_offset=4, end_col_offset=33), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/f4962cd6e6b77f4f1d6f676de32f29200067bf3ac05c63e1d60ef2823b4d1b10.py VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (__class__) node: FunctionDef(name='__instancecheck__', args=arguments(), body=[Expr(value=GeneratorExp(elt=Name(id='cls', ctx=Load(), lineno=4, col_offset=10, end_lineno=4, end_col_offset=13), generators=[comprehension(target=Name(id='attr', ctx=Store(), lineno=4, col_offset=19, end_lineno=4, end_col_offset=23), iter=Name(id='_get_protocol_attrs', ctx=Load(), lineno=4, col_offset=27, end_lineno=4, end_col_offset=46), is_async=0)], lineno=4, col_offset=8, end_lineno=4, end_col_offset=47), lineno=4, col_offset=8, end_lineno=4, end_col_offset=47), Expr(value=Attribute(value=Call(func=Name(id='super', ctx=Load(), lineno=5, col_offset=8, end_lineno=5, end_col_offset=13), lineno=5, col_offset=8, end_lineno=5, end_col_offset=15), attr='__instancecheck__', ctx=Load(), lineno=5, col_offset=8, end_lineno=5, end_col_offset=33), lineno=5, col_offset=8, end_lineno=5, end_col_offset=33)], lineno=3, col_offset=4, end_lineno=5, end_col_offset=33) parent node: ClassDef source code: 1: class _ProtocolMeta: 2: 3: def __instancecheck__(): 4: ((cls) for attr in _get_protocol_attrs) 5: super().__instancecheck__ None bytecode: _ test_small_samples[fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228.py] _ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = FunctionDef(name='test', args=arguments(posonlyargs=[], args=[arg(arg='self', annotation=None, type_comment=None)], va..._e', body=[Expr(...)])], orelse=[], finalbody=[])], decorator_list=[], returns=None, type_comment=None, type_params=[]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='__classdict__', argrepr='__classdict__', offset=30, s...number=18, label=None, positions=Positions(lineno=18, end_lineno=22, col_offset=4, end_col_offset=15), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228.py VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (__classdict__) node: FunctionDef(name='test', args=arguments(args=[arg(arg='self', lineno=18, col_offset=13, end_lineno=18, end_col_offset=17)]), body=[Try(body=[Raise(exc=Call(func=Name(id='Exception', ctx=Load(), lineno=20, col_offset=18, end_lineno=20, end_col_offset=27), args=[Constant(value=10, lineno=20, col_offset=28, end_lineno=20, end_col_offset=30)], lineno=20, col_offset=18, end_lineno=20, end_col_offset=31), lineno=20, col_offset=12, end_lineno=20, end_col_offset=31)], handlers=[ExceptHandler(type=Name(id='Exception', ctx=Load(), lineno=21, col_offset=15, end_lineno=21, end_col_offset=24), name='__e', body=[Expr(value=Name(id='__e', ctx=Load(), lineno=22, col_offset=12, end_lineno=22, end_col_offset=15), lineno=22, col_offset=12, end_lineno=22, end_col_offset=15)], lineno=21, col_offset=8, end_lineno=22, end_col_offset=15)], lineno=19, col_offset=8, end_lineno=22, end_col_offset=15)], lineno=18, col_offset=4, end_lineno=22, end_col_offset=15) parent node: ClassDef source code: 14: # 15: 16: class TestMangling: 17: 18: def test(self): 19: try: 20: raise Exception(10) 21: except Exception as __e: 22: __e None bytecode: ______________________ test_small_samples[load_deref.py] _______________________ full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/load_deref.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/load_deref-py-3.14.json' @pytest.mark.parametrize( "full_filename,result_filename", list(sample_files("small_samples")) ) @pytest.mark.skipif(sys.version_info<(3,),reason="no 2.7 support") def test_small_samples(full_filename, result_filename): skip_sentinel = [ "load_deref", "4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5", "508ccd0dcac13ecee6f0cea939b73ba5319c780ddbb6c496be96fe5614871d4a", "fc6eb521024986baa84af2634f638e40af090be4aa70ab3c22f3d022e8068228", "42a37b8a823eb2e510b967332661afd679c82c60b7177b992a47c16d81117c8a", "206e0609ff0589a0a32422ee902f09156af91746e27157c32c9595d12072f92a", ] skip_annotations = [ "d98e27d8963331b58e4e6b84c7580dafde4d9e2980ad4277ce55e6b186113c1d", "9b3db37076d3c7c76bdfd9badcc70d8047584433e1eea89f45014453d58bbc43", ] if any(s in full_filename for s in skip_sentinel) and sys.version_info < (3, 11): pytest.xfail("SentinelNodeFinder does not find some of the nodes (maybe a bug)") if any(s in full_filename for s in skip_annotations) and sys.version_info < (3, 7): pytest.xfail("no `from __future__ import annotations`") if ( (sys.version_info[:2] == (3, 7)) and "ad8aa993e6ee4eb5ee764d55f2e3fd636a99b2ecb8c5aff2b35fbb78a074ea30" in full_filename ): pytest.xfail("(i async for i in arange) can not be analyzed in 3.7") if ( (sys.version_info[:2] == (3, 5) or PYPY) and "1656dc52edd2385921104de7bb255ca369713f4b8c034ebeba5cf946058109bc" in full_filename ): pytest.skip("recursion takes to long in 3.5") > TestFiles().check_filename(full_filename, check_names=True) tests/test_main.py:751: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = FunctionDef(name='transform_SubscriptAssign', args=arguments(posonlyargs=[], args=[], vararg=None, kwonlyargs=[], kw_d...(elt=Name(...), generators=[comprehension(...)]))], decorator_list=[], returns=None, type_comment=None, type_params=[]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='__classdict__', argrepr='__classdict__', offset=30, s...number=10, label=None, positions=Positions(lineno=10, end_lineno=14, col_offset=4, end_col_offset=42), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/load_deref.py VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (__classdict__) node: FunctionDef(name='transform_SubscriptAssign', args=arguments(), body=[FunctionDef(name='__convert_index', args=arguments(), body=[Pass(lineno=13, col_offset=12, end_lineno=13, end_col_offset=16)], lineno=12, col_offset=8, end_lineno=13, end_col_offset=16), Expr(value=ListComp(elt=Name(id='__convert_index', ctx=Load(), lineno=14, col_offset=9, end_lineno=14, end_col_offset=24), generators=[comprehension(target=Name(id='x', ctx=Store(), lineno=14, col_offset=29, end_lineno=14, end_col_offset=30), iter=Name(id='indexes', ctx=Load(), lineno=14, col_offset=34, end_lineno=14, end_col_offset=41), is_async=0)], lineno=14, col_offset=8, end_lineno=14, end_col_offset=42), lineno=14, col_offset=8, end_lineno=14, end_col_offset=42)], lineno=10, col_offset=4, end_lineno=14, end_col_offset=42) parent node: ClassDef source code: 6: # node: Name(id='__convert_index', ctx=Load(), lineno=22, col_offset=9, end_lineno=22, end_col_offset=24) 7: 8: class TVMScriptParser: 9: 10: def transform_SubscriptAssign(): 11: 12: def __convert_index(): 13: pass 14: [__convert_index for x in indexes] None bytecode: ___________________ TestFiles.test_sample_files[_parser.py] ____________________ self = full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/_parser.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/_parser-py-3.14.json' @pytest.mark.parametrize("full_filename,result_filename", list(sample_files("samples"))) def test_sample_files(self, full_filename, result_filename): self.start_time = time.time() > result = self.check_filename(full_filename, check_names=True) tests/test_main.py:767: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = GeneratorExp(elt=Call(func=Name(id='chr', ctx=Load(...)), args=[Name(id='i', ctx=Load(...))], keywords=[]), generators...arget=Name(id='i', ctx=Store(...)), iter=Call(func=Name(...), args=[Constant(...)], keywords=[]), ifs=[], is_async=0)]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='.0', argrepr='.0', offset=6, start_offset=6, starts_l...umber=22, label=None, positions=Positions(lineno=22, end_lineno=22, col_offset=22, end_col_offset=49), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.GeneratorExp is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/_parser.py VerifierFailure: ast.GeneratorExp is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (.0) node: GeneratorExp(elt=Call(func=Name(id='chr', ctx=Load(), lineno=22, col_offset=23, end_lineno=22, end_col_offset=26), args=[Name(id='i', ctx=Load(), lineno=22, col_offset=27, end_lineno=22, end_col_offset=28)], lineno=22, col_offset=23, end_lineno=22, end_col_offset=29), generators=[comprehension(target=Name(id='i', ctx=Store(), lineno=22, col_offset=34, end_lineno=22, end_col_offset=35), iter=Call(func=Name(id='range', ctx=Load(), lineno=22, col_offset=39, end_lineno=22, end_col_offset=44), args=[Constant(value=32, lineno=22, col_offset=45, end_lineno=22, end_col_offset=47)], lineno=22, col_offset=39, end_lineno=22, end_col_offset=48), is_async=0)], lineno=22, col_offset=22, end_lineno=22, end_col_offset=49) parent node: Call source code: 18: match_to_number, 19: ) 20: from ._types import Key, ParseFloat, Pos 21: 22: ASCII_CTRL = frozenset(chr(i) for i in range(32)) | frozenset(chr(127)) 23: 24: # Neither of these sets include quotation mark or backslash. They are 25: # currently handled as separate cases in the parser functions. 26: ILLEGAL_BASIC_STR_CHARS = ASCII_CTRL - frozenset("\t") 27: ILLEGAL_MULTILINE_BASIC_STR_CHARS = ASCII_CTRL - frozenset("\t\n") None bytecode: _____________________ TestFiles.test_sample_files[bird.py] _____________________ self = full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/bird.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/bird-py-3.14.json' @pytest.mark.parametrize("full_filename,result_filename", list(sample_files("samples"))) def test_sample_files(self, full_filename, result_filename): self.start_time = time.time() > result = self.check_filename(full_filename, check_names=True) tests/test_main.py:767: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Subscript(value=Name(id='Iterable', ctx=Load()), slice=Name(id='Iteration', ctx=Load()), ctx=Load()) instruction = Instruction(opname='BINARY_OP', opcode=44, arg=26, argval=26, argrepr='[]', offset=928, start_offset=928, starts_line=...et=20, end_col_offset=39), cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( > ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): E KeyError: '[]' executing/_position_node_finder.py:661: KeyError ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/bird.py mapping failed '[]' search bytecode BINARY_OP 26 ([]) in file /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/bird.py at position Positions(lineno=810, end_lineno=810, col_offset=20, end_col_offset=39) source code: 806: } 807: } 808: 809: 810: class IterationList(Iterable[Iteration]): 811: """ 812: A list of Iterations, corresponding to a run of a loop. 813: If the loop has many iterations, only contains the first and last few 814: and any in the middle where unique nodes had values, so that 815: any node which appeared during this loop exists in at least some iterations. possible node 810 810 20 28 Name(id='Iterable', ctx=Load()) possible node 810 810 29 38 Name(id='Iteration', ctx=Load()) possible node 810 810 20 39 Subscript(value=Name(id='Iterable', ctx=Load()), slice=Name(id='Iteration', ctx=Load()), ctx=Load()) ________________ TestFiles.test_sample_files[configuration.py] _________________ self = full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/configuration.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/configuration-py-3.14.json' @pytest.mark.parametrize("full_filename,result_filename", list(sample_files("samples"))) def test_sample_files(self, full_filename, result_filename): self.start_time = time.time() > result = self.check_filename(full_filename, check_names=True) tests/test_main.py:767: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Name(id='builtins', ctx=Load()) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='builtins', argrepr='builtins', offset=2, start_offset...number=70, label=None, positions=Positions(lineno=70, end_lineno=70, col_offset=7, end_col_offset=15), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.Name is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/configuration.py VerifierFailure: ast.Name is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (builtins) node: Name(id='builtins', ctx=Load(), lineno=70, col_offset=7, end_lineno=70, end_col_offset=15) parent node: If source code: 66: 67: If you want a custom column, please open an issue to tell me what you're interested in! In the meantime, you can pass a list, where the elements are either strings or callables. The callables should take one argument, which will be an `Event` object. It has attributes `frame`, `event`, and `arg`, as specified in [`sys.settrace()`](https://docs.python.org/3/library/sys.html#sys.settrace), and other attributes which may change. 68: """ 69: 70: if builtins: 71: setattr(builtins_module, snoop, package.snoop) 72: setattr(builtins_module, pp, package.pp) 73: setattr(builtins_module, spy, package.spy) 74: config = Config( 75: out=out, None bytecode: ___________________ TestFiles.test_sample_files[datetime.py] ___________________ self = full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/datetime.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/datetime-py-3.14.json' @pytest.mark.parametrize("full_filename,result_filename", list(sample_files("samples"))) def test_sample_files(self, full_filename, result_filename): self.start_time = time.time() > result = self.check_filename(full_filename, check_names=True) tests/test_main.py:767: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Subscript(value=Name(id='_DAYS_IN_MONTH', ctx=Load()), slice=Slice(lower=Constant(value=1, kind=None), upper=None, step=None), ctx=Load()) instruction = Instruction(opname='BINARY_OP', opcode=44, arg=26, argval=26, argrepr='[]', offset=86, start_offset=86, starts_line=Fa...et=11, end_col_offset=29), cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( > ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): E KeyError: '[]' executing/_position_node_finder.py:661: KeyError ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/datetime.py mapping failed '[]' search bytecode BINARY_OP 26 ([]) in file /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/datetime.py at position Positions(lineno=37, end_lineno=37, col_offset=11, end_col_offset=29) source code: 33: _DAYS_IN_MONTH = [-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] 34: 35: _DAYS_BEFORE_MONTH = [-1] # -1 is a placeholder for indexing purposes. 36: dbm = 0 37: for dim in _DAYS_IN_MONTH[1:]: 38: _DAYS_BEFORE_MONTH.append(dbm) 39: dbm += dim 40: del dbm, dim 41: 42: def _is_leap(year): possible node 37 37 26 27 Constant(value=1) possible node 37 37 26 28 Slice(lower=Constant(value=1)) possible node 37 37 11 25 Name(id='_DAYS_IN_MONTH', ctx=Load()) possible node 37 37 11 29 Subscript(value=Name(id='_DAYS_IN_MONTH', ctx=Load()), slice=Slice(lower=Constant(value=1)), ctx=Load()) ______________________ TestFiles.test_sample_files[db.py] ______________________ self = full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/db.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/db-py-3.14.json' @pytest.mark.parametrize("full_filename,result_filename", list(sample_files("samples"))) def test_sample_files(self, full_filename, result_filename): self.start_time = time.time() > result = self.check_filename(full_filename, check_names=True) tests/test_main.py:767: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = FunctionDef(name='provide_session', args=arguments(posonlyargs=[], args=[arg(arg='self', annotation=None, type_comment...l(func=Name(...), args=[Name(...)], keywords=[]))], decorator_list=[], returns=None, type_comment=None, type_params=[]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='__classdict__', argrepr='__classdict__', offset=74, s...ber=225, label=None, positions=Positions(lineno=225, end_lineno=231, col_offset=4, end_col_offset=32), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/db.py VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (__classdict__) node: FunctionDef(name='provide_session', args=arguments(args=[arg(arg='self', lineno=225, col_offset=24, end_lineno=225, end_col_offset=28), arg(arg='func', lineno=225, col_offset=30, end_lineno=225, end_col_offset=34)]), body=[FunctionDef(name='wrapper', args=arguments(vararg=arg(arg='args', lineno=227, col_offset=21, end_lineno=227, end_col_offset=25), kwarg=arg(arg='kwargs', lineno=227, col_offset=29, end_lineno=227, end_col_offset=35)), body=[With(items=[withitem(context_expr=Call(func=Attribute(value=Name(id='self', ctx=Load(), lineno=228, col_offset=17, end_lineno=228, end_col_offset=21), attr='session_scope', ctx=Load(), lineno=228, col_offset=17, end_lineno=228, end_col_offset=35), lineno=228, col_offset=17, end_lineno=228, end_col_offset=37), optional_vars=Name(id='session', ctx=Store(), lineno=228, col_offset=41, end_lineno=228, end_col_offset=48))], body=[Return(value=Call(func=Name(id='func', ctx=Load(), lineno=229, col_offset=23, end_lineno=229, end_col_offset=27), args=[Name(id='session', ctx=Load(), lineno=229, col_offset=28, end_lineno=229, end_col_offset=35), Starred(value=Name(id='args', ctx=Load(), lineno=229, col_offset=38, end_lineno=229, end_col_offset=42), ctx=Load(), lineno=229, col_offset=37, end_lineno=229, end_col_offset=42)], keywords=[keyword(value=Name(id='kwargs', ctx=Load(), lineno=229, col_offset=46, end_lineno=229, end_col_offset=52), lineno=229, col_offset=44, end_lineno=229, end_col_offset=52)], lineno=229, col_offset=23, end_lineno=229, end_col_offset=53), lineno=229, col_offset=16, end_lineno=229, end_col_offset=53)], lineno=228, col_offset=12, end_lineno=229, end_col_offset=53)], decorator_list=[Call(func=Attribute(value=Name(id='functools', ctx=Load(), lineno=226, col_offset=9, end_lineno=226, end_col_offset=18), attr='wraps', ctx=Load(), lineno=226, col_offset=9, end_lineno=226, end_col_offset=24), args=[Name(id='func', ctx=Load(), lineno=226, col_offset=25, end_lineno=226, end_col_offset=29)], lineno=226, col_offset=9, end_lineno=226, end_col_offset=30)], lineno=227, col_offset=8, end_lineno=229, end_col_offset=53), Return(value=Call(func=Name(id='retry_db', ctx=Load(), lineno=231, col_offset=15, end_lineno=231, end_col_offset=23), args=[Name(id='wrapper', ctx=Load(), lineno=231, col_offset=24, end_lineno=231, end_col_offset=31)], lineno=231, col_offset=15, end_lineno=231, end_col_offset=32), lineno=231, col_offset=8, end_lineno=231, end_col_offset=32)], lineno=225, col_offset=4, end_lineno=231, end_col_offset=32) parent node: ClassDef source code: 221: raise 222: finally: 223: session.close() 224: 225: def provide_session(self, func): 226: @functools.wraps(func) 227: def wrapper(*args, **kwargs): 228: with self.session_scope() as session: 229: return func(session, *args, **kwargs) 230: 231: return retry_db(wrapper) 232: 233: 234: # Based on https://docs.sqlalchemy.org/en/latest/errors.html#error-dbapi 235: retry_db = retry(3, (InterfaceError, OperationalError, InternalError, ProgrammingError)) None bytecode: __________________ TestFiles.test_sample_files[executing.py] ___________________ self = full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/executing.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/executing-py-3.14.json' @pytest.mark.parametrize("full_filename,result_filename", list(sample_files("samples"))) def test_sample_files(self, full_filename, result_filename): self.start_time = time.time() > result = self.check_filename(full_filename, check_names=True) tests/test_main.py:767: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Subscript(value=Attribute(value=Name(id='sys', ctx=Load(...)), attr='version_info', ctx=Load()), slice=Constant(value=0, kind=None), ctx=Load()) instruction = Instruction(opname='BINARY_OP', opcode=44, arg=26, argval=26, argrepr='[]', offset=168, start_offset=168, starts_line=...set=6, end_col_offset=25), cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( > ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): E KeyError: '[]' executing/_position_node_finder.py:661: KeyError ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/executing.py mapping failed '[]' search bytecode BINARY_OP 26 ([]) in file /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/executing.py at position Positions(lineno=26, end_lineno=26, col_offset=6, end_col_offset=25) source code: 22: from threading import RLock 23: 24: __all__ = ["Source"] 25: 26: PY3 = sys.version_info[0] == 3 27: 28: if PY3: 29: # noinspection PyUnresolvedReferences 30: from functools import lru_cache 31: # noinspection PyUnresolvedReferences possible node 26 26 23 24 Constant(value=0) possible node 26 26 6 9 Name(id='sys', ctx=Load()) possible node 26 26 6 22 Attribute(value=Name(id='sys', ctx=Load()), attr='version_info', ctx=Load()) possible node 26 26 6 25 Subscript(value=Attribute(value=Name(id='sys', ctx=Load()), attr='version_info', ctx=Load()), slice=Constant(value=0), ctx=Load()) possible node 26 26 6 30 Compare(left=Subscript(value=Attribute(value=Name(id='sys', ctx=Load()), attr='version_info', ctx=Load()), slice=Constant(value=0), ctx=Load()), ops=[Eq()], comparators=[Constant(value=3)]) possible node 26 26 0 30 Assign(targets=[Name(id='PY3', ctx=Store())], value=Compare(left=Subscript(value=Attribute(value=Name(id='sys', ctx=Load()), attr='version_info', ctx=Load()), slice=Constant(value=0), ctx=Load()), ops=[Eq()], comparators=[Constant(value=3)])) _________________ TestFiles.test_sample_files[import_hook.py] __________________ self = full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/import_hook.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/import_hook-py-3.14.json' @pytest.mark.parametrize("full_filename,result_filename", list(sample_files("samples"))) def test_sample_files(self, full_filename, result_filename): self.start_time = time.time() > result = self.check_filename(full_filename, check_names=True) tests/test_main.py:767: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = FunctionDef(name='is_package', args=arguments(posonlyargs=[], args=[arg(arg='self', annotation=None, type_comment=None...c=Attribute(...), args=[Name(...)], keywords=[]))], decorator_list=[], returns=None, type_comment=None, type_params=[]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='__classdict__', argrepr='__classdict__', offset=54, s...number=33, label=None, positions=Positions(lineno=33, end_lineno=34, col_offset=4, end_col_offset=53), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/import_hook.py VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (__classdict__) node: FunctionDef(name='is_package', args=arguments(args=[arg(arg='self', lineno=33, col_offset=19, end_lineno=33, end_col_offset=23), arg(arg='fullname', lineno=33, col_offset=25, end_lineno=33, end_col_offset=33)]), body=[Return(value=Call(func=Attribute(value=Attribute(value=Attribute(value=Name(id='self', ctx=Load(), lineno=34, col_offset=15, end_lineno=34, end_col_offset=19), attr='_spec', ctx=Load(), lineno=34, col_offset=15, end_lineno=34, end_col_offset=25), attr='loader', ctx=Load(), lineno=34, col_offset=15, end_lineno=34, end_col_offset=32), attr='is_package', ctx=Load(), lineno=34, col_offset=15, end_lineno=34, end_col_offset=43), args=[Name(id='fullname', ctx=Load(), lineno=34, col_offset=44, end_lineno=34, end_col_offset=52)], lineno=34, col_offset=15, end_lineno=34, end_col_offset=53), lineno=34, col_offset=8, end_lineno=34, end_col_offset=53)], lineno=33, col_offset=4, end_lineno=34, end_col_offset=53) parent node: ClassDef source code: 29: 30: def get_filename(self, fullname): 31: return self._spec.loader.get_filename(fullname) 32: 33: def is_package(self, fullname): 34: return self._spec.loader.is_package(fullname) 35: 36: 37: class BirdsEyeFinder(object): 38: """Loads a module and looks for tracing inside, only providing a loader 39: if it finds some. None bytecode: ___________________ TestFiles.test_sample_files[ipython.py] ____________________ self = full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/ipython.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/ipython-py-3.14.json' @pytest.mark.parametrize("full_filename,result_filename", list(sample_files("samples"))) def test_sample_files(self, full_filename, result_filename): self.start_time = time.time() > result = self.check_filename(full_filename, check_names=True) tests/test_main.py:767: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = FunctionDef(name='p', args=arguments(posonlyargs=[], args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, ..., args=[Attribute(...), Name(...)], keywords=[]))], decorator_list=[], returns=None, type_comment=None, type_params=[]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='original', argrepr='original', offset=4, start_offset...number=24, label=None, positions=Positions(lineno=24, end_lineno=31, col_offset=4, end_col_offset=43), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/ipython.py VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (original) node: FunctionDef(name='p', args=arguments(), body=[Assign(targets=[Name(id='frame', ctx=Store(), lineno=25, col_offset=8, end_lineno=25, end_col_offset=13)], value=Call(func=Attribute(value=Name(id='inspect', ctx=Load(), lineno=25, col_offset=16, end_lineno=25, end_col_offset=23), attr='currentframe', ctx=Load(), lineno=25, col_offset=16, end_lineno=25, end_col_offset=36), lineno=25, col_offset=16, end_lineno=25, end_col_offset=38), lineno=25, col_offset=8, end_lineno=25, end_col_offset=38), While(test=Name(id='frame', ctx=Load(), lineno=26, col_offset=14, end_lineno=26, end_col_offset=19), body=[If(test=Compare(left=Attribute(value=Name(id='frame', ctx=Load(), lineno=27, col_offset=15, end_lineno=27, end_col_offset=20), attr='f_code', ctx=Load(), lineno=27, col_offset=15, end_lineno=27, end_col_offset=27), ops=[Eq()], comparators=[Attribute(value=Attribute(value=Name(id='ThreadingMixIn', ctx=Load(), lineno=27, col_offset=31, end_lineno=27, end_col_offset=45), attr='process_request_thread', ctx=Load(), lineno=27, col_offset=31, end_lineno=27, end_col_offset=68), attr='__code__', ctx=Load(), lineno=27, col_offset=31, end_lineno=27, end_col_offset=77)], lineno=27, col_offset=15, end_lineno=27, end_col_offset=77), body=[Return(value=Call(func=Name(id='fake_stream', ctx=Load(), lineno=28, col_offset=23, end_lineno=28, end_col_offset=34), lineno=28, col_offset=23, end_lineno=28, end_col_offset=36), lineno=28, col_offset=16, end_lineno=28, end_col_offset=36)], lineno=27, col_offset=12, end_lineno=28, end_col_offset=36), Assign(targets=[Name(id='frame', ctx=Store(), lineno=29, col_offset=12, end_lineno=29, end_col_offset=17)], value=Attribute(value=Name(id='frame', ctx=Load(), lineno=29, col_offset=20, end_lineno=29, end_col_offset=25), attr='f_back', ctx=Load(), lineno=29, col_offset=20, end_lineno=29, end_col_offset=32), lineno=29, col_offset=12, end_lineno=29, end_col_offset=32)], lineno=26, col_offset=8, end_lineno=29, end_col_offset=32), Return(value=Call(func=Attribute(value=Name(id='thread_proxies', ctx=Load(), lineno=30, col_offset=15, end_lineno=30, end_col_offset=29), attr='get', ctx=Load(), lineno=30, col_offset=15, end_lineno=30, end_col_offset=33), args=[Attribute(value=Call(func=Name(id='current_thread', ctx=Load(), lineno=30, col_offset=34, end_lineno=30, end_col_offset=48), lineno=30, col_offset=34, end_lineno=30, end_col_offset=50), attr='ident', ctx=Load(), lineno=30, col_offset=34, end_lineno=30, end_col_offset=56), Name(id='original', ctx=Load(), lineno=31, col_offset=34, end_lineno=31, end_col_offset=42)], lineno=30, col_offset=15, end_lineno=31, end_col_offset=43), lineno=30, col_offset=8, end_lineno=31, end_col_offset=43)], lineno=24, col_offset=4, end_lineno=31, end_col_offset=43) parent node: FunctionDef source code: 20: thread_proxies = {} 21: 22: 23: def stream_proxy(original): 24: def p(): 25: frame = inspect.currentframe() 26: while frame: 27: if frame.f_code == ThreadingMixIn.process_request_thread.__code__: 28: return fake_stream() 29: frame = frame.f_back 30: return thread_proxies.get(current_thread().ident, 31: original) 32: 33: return LocalProxy(p) 34: 35: 36: sys.stderr = stream_proxy(sys.stderr) None bytecode: ____________________ TestFiles.test_sample_files[server.py] ____________________ self = full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/server.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/server-py-3.14.json' @pytest.mark.parametrize("full_filename,result_filename", list(sample_files("samples"))) def test_sample_files(self, full_filename, result_filename): self.start_time = time.time() > result = self.check_filename(full_filename, check_names=True) tests/test_main.py:767: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Subscript(value=Attribute(value=Name(id='sys', ctx=Load(...)), attr='argv', ctx=Load()), slice=Slice(lower=Constant(value=1, kind=None), upper=None, step=None), ctx=Load()) instruction = Instruction(opname='BINARY_OP', opcode=44, arg=26, argval=26, argrepr='[]', offset=1278, start_offset=1278, starts_lin...et=14, end_col_offset=26), cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( > ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): E KeyError: '[]' executing/_position_node_finder.py:661: KeyError ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/server.py mapping failed '[]' search bytecode BINARY_OP 26 ([]) in file /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/server.py at position Positions(lineno=262, end_lineno=262, col_offset=14, end_col_offset=26) source code: 258: for h, count in query 259: ]) 260: 261: 262: def main(argv=sys.argv[1:]): 263: # Support legacy CLI where there was just one positional argument: the port 264: if len(argv) == 1 and argv[0].isdigit(): 265: argv.insert(0, '--port') 266: 267: parser = argparse.ArgumentParser(description="Bird's Eye: A graphical Python debugger") possible node 262 262 23 24 Constant(value=1) possible node 262 262 23 25 Slice(lower=Constant(value=1)) possible node 262 262 14 17 Name(id='sys', ctx=Load()) possible node 262 262 14 22 Attribute(value=Name(id='sys', ctx=Load()), attr='argv', ctx=Load()) possible node 262 262 14 26 Subscript(value=Attribute(value=Name(id='sys', ctx=Load()), attr='argv', ctx=Load()), slice=Slice(lower=Constant(value=1)), ctx=Load()) ____________________ TestFiles.test_sample_files[tests.py] _____________________ self = full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/tests.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/tests-py-3.14.json' @pytest.mark.parametrize("full_filename,result_filename", list(sample_files("samples"))) def test_sample_files(self, full_filename, result_filename): self.start_time = time.time() > result = self.check_filename(full_filename, check_names=True) tests/test_main.py:767: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Subscript(value=Name(id='tester', ctx=Load()), slice=Constant(value=19, kind=None), ctx=Load()) instruction = Instruction(opname='BINARY_OP', opcode=44, arg=26, argval=26, argrepr='[]', offset=382, start_offset=382, starts_line=...set=7, end_col_offset=17), cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( > ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): E KeyError: '[]' executing/_position_node_finder.py:661: KeyError ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/tests.py mapping failed '[]' search bytecode BINARY_OP 26 ([]) in file /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/tests.py at position Positions(lineno=418, end_lineno=418, col_offset=7, end_col_offset=17) source code: 414: 415: assert tester([1, 2, 3]) == [1, 2, 3] 416: 417: assert tester.asd is tester 418: assert tester[19] is tester 419: assert tester ** 4 is tester 420: assert tester * 3 is tester 421: assert tester - 2 is tester 422: assert tester + 1 is tester 423: assert -tester is tester possible node 418 418 14 16 Constant(value=19) possible node 418 418 7 13 Name(id='tester', ctx=Load()) possible node 418 418 7 17 Subscript(value=Name(id='tester', ctx=Load()), slice=Constant(value=19), ctx=Load()) possible node 418 418 7 27 Compare(left=Subscript(value=Name(id='tester', ctx=Load()), slice=Constant(value=19), ctx=Load()), ops=[Is()], comparators=[Name(id='tester', ctx=Load())]) possible node 418 418 0 27 Assert(test=Compare(left=Subscript(value=Name(id='tester', ctx=Load()), slice=Constant(value=19), ctx=Load()), ops=[Is()], comparators=[Name(id='tester', ctx=Load())])) ____________________ TestFiles.test_sample_files[tracer.py] ____________________ self = full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/tracer.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/tracer-py-3.14.json' @pytest.mark.parametrize("full_filename,result_filename", list(sample_files("samples"))) def test_sample_files(self, full_filename, result_filename): self.start_time = time.time() > result = self.check_filename(full_filename, check_names=True) tests/test_main.py:767: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Subscript(value=Name(id='Union', ctx=Load()), slice=Tuple(elts=[Attribute(value=Name(...), attr='expr', ctx=Load(...)), Attribute(value=Name(...), attr='stmt', ctx=Load(...))], ctx=Load()), ctx=Load()) instruction = Instruction(opname='BINARY_OP', opcode=44, arg=26, argval=26, argrepr='[]', offset=366, start_offset=366, starts_line=...et=27, end_col_offset=52), cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( > ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): E KeyError: '[]' executing/_position_node_finder.py:661: KeyError ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/tracer.py mapping failed '[]' search bytecode BINARY_OP 26 ([]) in file /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/tracer.py at position Positions(lineno=131, end_lineno=131, col_offset=27, end_col_offset=52) source code: 127: # Argument of TreeTracerBase.enter_call 128: EnterCallInfo = NamedTuple('EnterCallInfo', [ 129: 130: # Node from where the call was made 131: ('call_node', Optional[Union[ast.expr, ast.stmt]]), 132: 133: # Node where the call begins 134: ('enter_node', ast.AST), 135: 136: # Frame from which the call was made possible node 131 131 33 36 Name(id='ast', ctx=Load()) possible node 131 131 43 46 Name(id='ast', ctx=Load()) possible node 131 131 27 32 Name(id='Union', ctx=Load()) possible node 131 131 33 41 Attribute(value=Name(id='ast', ctx=Load()), attr='expr', ctx=Load()) possible node 131 131 43 51 Attribute(value=Name(id='ast', ctx=Load()), attr='stmt', ctx=Load()) possible node 131 131 33 51 Tuple(elts=[Attribute(value=Name(id='ast', ctx=Load()), attr='expr', ctx=Load()), Attribute(value=Name(id='ast', ctx=Load()), attr='stmt', ctx=Load())], ctx=Load()) possible node 131 131 27 52 Subscript(value=Name(id='Union', ctx=Load()), slice=Tuple(elts=[Attribute(value=Name(id='ast', ctx=Load()), attr='expr', ctx=Load()), Attribute(value=Name(id='ast', ctx=Load()), attr='stmt', ctx=Load())], ctx=Load()), ctx=Load()) possible node 131 131 18 53 Subscript(value=Name(id='Optional', ctx=Load()), slice=Subscript(value=Name(id='Union', ctx=Load()), slice=Tuple(elts=[Attribute(value=Name(id='ast', ctx=Load()), attr='expr', ctx=Load()), Attribute(value=Name(id='ast', ctx=Load()), attr='stmt', ctx=Load())], ctx=Load()), ctx=Load()), ctx=Load()) possible node 131 131 4 54 Tuple(elts=[Constant(value='call_node'), Subscript(value=Name(id='Optional', ctx=Load()), slice=Subscript(value=Name(id='Union', ctx=Load()), slice=Tuple(elts=[Attribute(value=Name(id='ast', ctx=Load()), attr='expr', ctx=Load()), Attribute(value=Name(id='ast', ctx=Load()), attr='stmt', ctx=Load())], ctx=Load()), ctx=Load()), ctx=Load())], ctx=Load()) ___________________ TestFiles.test_sample_files[tracer2.py] ____________________ self = full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/tracer2.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/tracer2-py-3.14.json' @pytest.mark.parametrize("full_filename,result_filename", list(sample_files("samples"))) def test_sample_files(self, full_filename, result_filename): self.start_time = time.time() > result = self.check_filename(full_filename, check_names=True) tests/test_main.py:767: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = FunctionDef(name='get_local_reprs', args=arguments(posonlyargs=[], args=[arg(arg='self', annotation=None, type_comment...ype_comment=None)], orelse=[], type_comment=None)], decorator_list=[], returns=None, type_comment=None, type_params=[]) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='__classdict__', argrepr='__classdict__', offset=42, s...number=71, label=None, positions=Positions(lineno=71, end_lineno=94, col_offset=4, end_col_offset=34), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/tracer2.py VerifierFailure: ast.FunctionDef is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (__classdict__) node: FunctionDef(name='get_local_reprs', args=arguments(args=[arg(arg='self', lineno=71, col_offset=24, end_lineno=71, end_col_offset=28), arg(arg='watch', lineno=71, col_offset=30, end_lineno=71, end_col_offset=35), arg(arg='watch_extras', lineno=71, col_offset=37, end_lineno=71, end_col_offset=49)]), body=[Assign(targets=[Name(id='frame', ctx=Store(), lineno=72, col_offset=8, end_lineno=72, end_col_offset=13)], value=Attribute(value=Name(id='self', ctx=Load(), lineno=72, col_offset=16, end_lineno=72, end_col_offset=20), attr='frame', ctx=Load(), lineno=72, col_offset=16, end_lineno=72, end_col_offset=26), lineno=72, col_offset=8, end_lineno=72, end_col_offset=26), Assign(targets=[Name(id='code', ctx=Store(), lineno=73, col_offset=8, end_lineno=73, end_col_offset=12)], value=Attribute(value=Name(id='frame', ctx=Load(), lineno=73, col_offset=15, end_lineno=73, end_col_offset=20), attr='f_code', ctx=Load(), lineno=73, col_offset=15, end_lineno=73, end_col_offset=27), lineno=73, col_offset=8, end_lineno=73, end_col_offset=27), Assign(targets=[Name(id='vars_order', ctx=Store(), lineno=74, col_offset=8, end_lineno=74, end_col_offset=18)], value=BinOp(left=BinOp(left=BinOp(left=Attribute(value=Name(id='code', ctx=Load(), lineno=74, col_offset=21, end_lineno=74, end_col_offset=25), attr='co_varnames', ctx=Load(), lineno=74, col_offset=21, end_lineno=74, end_col_offset=37), op=Add(), right=Attribute(value=Name(id='code', ctx=Load(), lineno=74, col_offset=40, end_lineno=74, end_col_offset=44), attr='co_cellvars', ctx=Load(), lineno=74, col_offset=40, end_lineno=74, end_col_offset=56), lineno=74, col_offset=21, end_lineno=74, end_col_offset=56), op=Add(), right=Attribute(value=Name(id='code', ctx=Load(), lineno=74, col_offset=59, end_lineno=74, end_col_offset=63), attr='co_freevars', ctx=Load(), lineno=74, col_offset=59, end_lineno=74, end_col_offset=75), lineno=74, col_offset=21, end_lineno=74, end_col_offset=75), op=Add(), right=Call(func=Name(id='tuple', ctx=Load(), lineno=74, col_offset=78, end_lineno=74, end_col_offset=83), args=[Call(func=Attribute(value=Attribute(value=Name(id='frame', ctx=Load(), lineno=74, col_offset=84, end_lineno=74, end_col_offset=89), attr='f_locals', ctx=Load(), lineno=74, col_offset=84, end_lineno=74, end_col_offset=98), attr='keys', ctx=Load(), lineno=74, col_offset=84, end_lineno=74, end_col_offset=103), lineno=74, col_offset=84, end_lineno=74, end_col_offset=105)], lineno=74, col_offset=78, end_lineno=74, end_col_offset=106), lineno=74, col_offset=21, end_lineno=74, end_col_offset=106), lineno=74, col_offset=8, end_lineno=74, end_col_offset=106), Assign(targets=[Name(id='result_items', ctx=Store(), lineno=76, col_offset=8, end_lineno=76, end_col_offset=20)], value=Call(func=Name(id='sorted', ctx=Load(), lineno=76, col_offset=23, end_lineno=76, end_col_offset=29), args=[Call(func=Attribute(value=Attribute(value=Name(id='frame', ctx=Load(), lineno=77, col_offset=12, end_lineno=77, end_col_offset=17), attr='f_locals', ctx=Load(), lineno=77, col_offset=12, end_lineno=77, end_col_offset=26), attr='items', ctx=Load(), lineno=77, col_offset=12, end_lineno=77, end_col_offset=32), lineno=77, col_offset=12, end_lineno=77, end_col_offset=34)], keywords=[keyword(arg='key', value=Lambda(args=arguments(args=[arg(arg='key_value', lineno=78, col_offset=23, end_lineno=78, end_col_offset=32)]), body=Call(func=Attribute(value=Name(id='vars_order', ctx=Load(), lineno=78, col_offset=34, end_lineno=78, end_col_offset=44), attr='index', ctx=Load(), lineno=78, col_offset=34, end_lineno=78, end_col_offset=50), args=[Subscript(value=Name(id='key_value', ctx=Load(), lineno=78, col_offset=51, end_lineno=78, end_col_offset=60), slice=Constant(value=0, lineno=78, col_offset=61, end_lineno=78, end_col_offset=62), ctx=Load(), lineno=78, col_offset=51, end_lineno=78, end_col_offset=63)], lineno=78, col_offset=34, end_lineno=78, end_col_offset=64), lineno=78, col_offset=16, end_lineno=78, end_col_offset=64), lineno=78, col_offset=12, end_lineno=78, end_col_offset=64)], lineno=76, col_offset=23, end_lineno=79, end_col_offset=9), lineno=76, col_offset=8, end_lineno=79, end_col_offset=9), For(target=Name(id='variable', ctx=Store(), lineno=81, col_offset=12, end_lineno=81, end_col_offset=20), iter=Name(id='watch', ctx=Load(), lineno=81, col_offset=24, end_lineno=81, end_col_offset=29), body=[AugAssign(target=Name(id='result_items', ctx=Store(), lineno=82, col_offset=12, end_lineno=82, end_col_offset=24), op=Add(), value=Call(func=Name(id='sorted', ctx=Load(), lineno=82, col_offset=28, end_lineno=82, end_col_offset=34), args=[Call(func=Attribute(value=Name(id='variable', ctx=Load(), lineno=82, col_offset=35, end_lineno=82, end_col_offset=43), attr='items', ctx=Load(), lineno=82, col_offset=35, end_lineno=82, end_col_offset=49), args=[Name(id='frame', ctx=Load(), lineno=82, col_offset=50, end_lineno=82, end_col_offset=55)], lineno=82, col_offset=35, end_lineno=82, end_col_offset=56)], lineno=82, col_offset=28, end_lineno=82, end_col_offset=57), lineno=82, col_offset=12, end_lineno=82, end_col_offset=57)], lineno=81, col_offset=8, end_lineno=82, end_col_offset=57), For(target=Tuple(elts=[Name(id='source', ctx=Store(), lineno=84, col_offset=12, end_lineno=84, end_col_offset=18), Name(id='value', ctx=Store(), lineno=84, col_offset=20, end_lineno=84, end_col_offset=25)], ctx=Store(), lineno=84, col_offset=12, end_lineno=84, end_col_offset=25), iter=Name(id='result_items', ctx=Load(), lineno=84, col_offset=29, end_lineno=84, end_col_offset=41), body=[Expr(value=Yield(value=Tuple(elts=[Name(id='source', ctx=Load(), lineno=85, col_offset=18, end_lineno=85, end_col_offset=24), Name(id='value', ctx=Load(), lineno=85, col_offset=26, end_lineno=85, end_col_offset=31)], ctx=Load(), lineno=85, col_offset=18, end_lineno=85, end_col_offset=31), lineno=85, col_offset=12, end_lineno=85, end_col_offset=31), lineno=85, col_offset=12, end_lineno=85, end_col_offset=31), For(target=Name(id='extra', ctx=Store(), lineno=86, col_offset=16, end_lineno=86, end_col_offset=21), iter=Name(id='watch_extras', ctx=Load(), lineno=86, col_offset=25, end_lineno=86, end_col_offset=37), body=[Try(body=[Assign(targets=[Name(id='pair', ctx=Store(), lineno=88, col_offset=20, end_lineno=88, end_col_offset=24)], value=Call(func=Name(id='extra', ctx=Load(), lineno=88, col_offset=27, end_lineno=88, end_col_offset=32), args=[Name(id='source', ctx=Load(), lineno=88, col_offset=33, end_lineno=88, end_col_offset=39), Name(id='value', ctx=Load(), lineno=88, col_offset=41, end_lineno=88, end_col_offset=46)], lineno=88, col_offset=27, end_lineno=88, end_col_offset=47), lineno=88, col_offset=20, end_lineno=88, end_col_offset=47)], handlers=[ExceptHandler(type=Name(id='Exception', ctx=Load(), lineno=89, col_offset=23, end_lineno=89, end_col_offset=32), body=[Pass(lineno=90, col_offset=20, end_lineno=90, end_col_offset=24)], lineno=89, col_offset=16, end_lineno=90, end_col_offset=24)], orelse=[If(test=Compare(left=Name(id='pair', ctx=Load(), lineno=92, col_offset=23, end_lineno=92, end_col_offset=27), ops=[IsNot()], comparators=[Constant(value=None, lineno=92, col_offset=35, end_lineno=92, end_col_offset=39)], lineno=92, col_offset=23, end_lineno=92, end_col_offset=39), body=[Assert(test=Compare(left=Call(func=Name(id='len', ctx=Load(), lineno=93, col_offset=31, end_lineno=93, end_col_offset=34), args=[Name(id='pair', ctx=Load(), lineno=93, col_offset=35, end_lineno=93, end_col_offset=39)], lineno=93, col_offset=31, end_lineno=93, end_col_offset=40), ops=[Eq()], comparators=[Constant(value=2, lineno=93, col_offset=44, end_lineno=93, end_col_offset=45)], lineno=93, col_offset=31, end_lineno=93, end_col_offset=45), msg=Constant(value='Watch extra must return pair or None', lineno=93, col_offset=47, end_lineno=93, end_col_offset=85), lineno=93, col_offset=24, end_lineno=93, end_col_offset=85), Expr(value=Yield(value=Name(id='pair', ctx=Load(), lineno=94, col_offset=30, end_lineno=94, end_col_offset=34), lineno=94, col_offset=24, end_lineno=94, end_col_offset=34), lineno=94, col_offset=24, end_lineno=94, end_col_offset=34)], lineno=92, col_offset=20, end_lineno=94, end_col_offset=34)], lineno=87, col_offset=16, end_lineno=94, end_col_offset=34)], lineno=86, col_offset=12, end_lineno=94, end_col_offset=34)], lineno=84, col_offset=8, end_lineno=94, end_col_offset=34)], lineno=71, col_offset=4, end_lineno=94, end_col_offset=34) parent node: ClassDef source code: 67: if name not in old_local_reprs or old_local_reprs[name] != value_repr: 68: variables.append((name, value_repr)) 69: return variables 70: 71: def get_local_reprs(self, watch, watch_extras): 72: frame = self.frame 73: code = frame.f_code 74: vars_order = code.co_varnames + code.co_cellvars + code.co_freevars + tuple(frame.f_locals.keys()) 75: 76: result_items = sorted( 77: frame.f_locals.items(), 78: key=lambda key_value: vars_order.index(key_value[0]) 79: ) 80: 81: for variable in watch: 82: result_items += sorted(variable.items(frame)) 83: 84: for source, value in result_items: 85: yield source, value 86: for extra in watch_extras: 87: try: 88: pair = extra(source, value) 89: except Exception: 90: pass 91: else: 92: if pair is not None: 93: assert len(pair) == 2, "Watch extra must return pair or None" 94: yield pair 95: 96: 97: thread_global = threading.local() 98: internal_directories = (os.path.dirname((lambda: 0).__code__.co_filename),) 99: None bytecode: ____________________ TestFiles.test_sample_files[utils.py] _____________________ self = full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/utils.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/utils-py-3.14.json' @pytest.mark.parametrize("full_filename,result_filename", list(sample_files("samples"))) def test_sample_files(self, full_filename, result_filename): self.start_time = time.time() > result = self.check_filename(full_filename, check_names=True) tests/test_main.py:767: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1448: in check_code for x in self.check_code(inst.argval, nodes, decorators, check_names=check_names): tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Name(id='path', ctx=Load()) instruction = Instruction(opname='LOAD_FAST_BORROW', opcode=86, arg=0, argval='path', argrepr='path', offset=34, start_offset=34, st...umber=51, label=None, positions=Positions(lineno=51, end_lineno=51, col_offset=30, end_col_offset=34), cache_info=None) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): # a+=5 return if node_match(ast.Attribute, ctx=ast.Del) and inst_match( "DELETE_ATTR", argval=mangled_name(node) ): return if inst_match( ( "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", ) ) and node_match(ast.BoolOp): # and/or short circuit return if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del): return if ( node_match(ast.Name, ctx=ast.Load) or ( node_match(ast.Name, ctx=ast.Store) and isinstance(node.parent, ast.AugAssign) ) ) and inst_match( ( "LOAD_NAME", "LOAD_FAST", "LOAD_FAST_CHECK", "LOAD_GLOBAL", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF", ), argval=mangled_name(node), ): return if node_match(ast.Name, ctx=ast.Del) and inst_match( ("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"), argval=mangled_name(node) ): return if node_match(ast.Constant) and inst_match( "LOAD_CONST", argval=cast(ast.Constant, node).value ): return if node_match( (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For) ) and inst_match(("GET_ITER", "FOR_ITER")): return if sys.version_info >= (3, 12): if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE" ): return if node_match(ast.Subscript) and inst_match("BINARY_SLICE"): return if node_match(ast.ImportFrom) and inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR" ): return if ( node_match(ast.Yield) or isinstance(node.parent, ast.GeneratorExp) ) and inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_ASYNC_GEN_WRAP"): return if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match(ast.TypeVar) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR") or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND" ) or inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS" ) or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=mangled_name(node)) ): return if node_match(ast.TypeVarTuple) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name) ): return if node_match(ast.ParamSpec) and ( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC") or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)): return if node_match(ast.TypeAlias): if( inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEALIAS") or inst_match( ("STORE_NAME", "STORE_FAST", "STORE_DEREF"), argrepr=node.name.id ) or inst_match("CALL") ): return if node_match(ast.ClassDef) and node.type_params: if inst_match( ("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"), argrepr=".type_params", ): return if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"): return if inst_match( "CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC" ): return if inst_match("LOAD_DEREF",argval="__classdict__"): return if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params: if inst_match("CALL"): return if inst_match( "CALL_INTRINSIC_2", argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS" ): return if inst_match("LOAD_FAST",argval=".defaults"): return if inst_match("LOAD_FAST",argval=".kwdefaults"): return if inst_match("STORE_NAME", argval="__classdictcell__"): # this is a general thing return # f-strings if node_match(ast.JoinedStr) and ( inst_match("LOAD_ATTR", argval="join") or inst_match(("LIST_APPEND", "CALL")) ): return if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"): return if sys.version_info >= (3, 13): if inst_match("NOP"): return if inst_match("TO_BOOL") and node_match(ast.BoolOp): return if inst_match("CALL_KW") and node_match((ast.Call, ast.ClassDef)): return if inst_match("LOAD_FAST", argval=".type_params"): return if inst_match("LOAD_FAST", argval="__classdict__"): return if inst_match("LOAD_FAST") and node_match( ( ast.FunctionDef, ast.ClassDef, ast.TypeAlias, ast.TypeVar, ast.Lambda, ast.AsyncFunctionDef, ) ): # These are loads for closure variables. # It is difficult to check that this is actually closure variable, see: # https://github.com/alexmojaki/executing/pull/80#discussion_r1716027317 return if ( inst_match("LOAD_FAST") and node_match(ast.TypeAlias) and node.name.id == instruction.argval ): return if inst_match("STORE_NAME",argval="__static_attributes__"): # the node is the first node in the body return if inst_match("LOAD_FAST") and isinstance(node.parent,ast.TypeVar): return # old verifier typ: Type = type(None) op_type: Type = type(None) if op_name.startswith(("BINARY_SUBSCR", "SLICE+")): typ = ast.Subscript ctx = ast.Load elif op_name.startswith("BINARY_"): typ = ast.BinOp op_type = op_type_map[instruction.argrepr] extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type) elif op_name.startswith("UNARY_"): typ = ast.UnaryOp op_type = dict( UNARY_POSITIVE=ast.UAdd, UNARY_NEGATIVE=ast.USub, UNARY_NOT=ast.Not, UNARY_INVERT=ast.Invert, )[op_name] extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type) elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD","LOAD_SUPER_ATTR"): typ = ast.Attribute ctx = ast.Load extra_filter = lambda e: mangled_name(e) == instruction.argval elif op_name in ( "LOAD_NAME", "LOAD_GLOBAL", "LOAD_FAST", "LOAD_DEREF", "LOAD_CLASSDEREF", ): typ = ast.Name ctx = ast.Load extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"): typ = ast.Compare extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1 elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")): ctx = ast.Store typ = ast.Subscript elif op_name.startswith("STORE_ATTR"): ctx = ast.Store typ = ast.Attribute extra_filter = lambda e: mangled_name(e) == instruction.argval node_ctx = getattr(node, "ctx", None) ctx_match = ( ctx is not type(None) or not hasattr(node, "ctx") or isinstance(node_ctx, ctx) ) # check for old verifier if isinstance(node, typ) and ctx_match and extra_filter(node): return # generate error title = "ast.%s is not created from %s" % ( type(node).__name__, instruction.opname, ) > raise VerifierFailure(title, node, instruction) E executing._exceptions.VerifierFailure: ast.Name is not created from LOAD_FAST_BORROW executing/_position_node_finder.py:938: VerifierFailure ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/utils.py VerifierFailure: ast.Name is not created from LOAD_FAST_BORROW instruction: LOAD_FAST_BORROW 0 (path) node: Name(id='path', ctx=Load(), lineno=51, col_offset=30, end_lineno=51, end_col_offset=34) parent node: Call source code: 47: 48: def path_leaf(path): 49: # type: (str) -> str 50: # http://stackoverflow.com/a/8384788/2482744 51: head, tail = ntpath.split(path) 52: return tail or ntpath.basename(head) 53: 54: 55: def common_ancestor(paths): 56: # type: (List[str]) -> str None bytecode: ____________________ TestFiles.test_sample_files[utils2.py] ____________________ self = full_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/utils2.py' result_filename = '/builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/sample_results/utils2-py-3.14.json' @pytest.mark.parametrize("full_filename,result_filename", list(sample_files("samples"))) def test_sample_files(self, full_filename, result_filename): self.start_time = time.time() > result = self.check_filename(full_filename, check_names=True) tests/test_main.py:767: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Subscript(value=Attribute(value=Name(id='sys', ctx=Load(...)), attr='version_info', ctx=Load()), slice=Slice(lower=None, upper=Constant(value=2, kind=None), step=None), ctx=Load()) instruction = Instruction(opname='BINARY_OP', opcode=44, arg=26, argval=26, argrepr='[]', offset=168, start_offset=168, starts_line=...et=11, end_col_offset=31), cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( > ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): E KeyError: '[]' executing/_position_node_finder.py:661: KeyError ----------------------------- Captured stdout call ----------------------------- check /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/utils2.py mapping failed '[]' search bytecode BINARY_OP 26 ([]) in file /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/samples/utils2.py at position Positions(lineno=12, end_lineno=12, col_offset=11, end_col_offset=31) source code: 8: from cheap_repr import cheap_repr, try_register_repr 9: 10: NO_ASTTOKENS = ( 11: 'pypy' in sys.version.lower() 12: or sys.version_info[:2] in [(3, 4), (3, 8)] 13: ) 14: 15: file_reading_errors = ( 16: IOError, 17: OSError, possible node 12 12 29 30 Constant(value=2) possible node 12 12 28 30 Slice(upper=Constant(value=2)) possible node 12 12 11 14 Name(id='sys', ctx=Load()) possible node 12 12 11 27 Attribute(value=Name(id='sys', ctx=Load()), attr='version_info', ctx=Load()) possible node 12 12 11 31 Subscript(value=Attribute(value=Name(id='sys', ctx=Load()), attr='version_info', ctx=Load()), slice=Slice(upper=Constant(value=2)), ctx=Load()) possible node 12 12 11 51 Compare(left=Subscript(value=Attribute(value=Name(id='sys', ctx=Load()), attr='version_info', ctx=Load()), slice=Slice(upper=Constant(value=2)), ctx=Load()), ops=[In()], comparators=[List(elts=[Tuple(elts=[Constant(value=3), Constant(value=4)], ctx=Load()), Tuple(elts=[Constant(value=3), Constant(value=8)], ctx=Load())], ctx=Load())]) _________________________ TestFiles.test_module_files __________________________ self = def test_module_files(self): self.start_time = time.time() modules = list(sys.modules.values()) shuffle(modules) for module in modules: try: filename = inspect.getsourcefile(module) except TypeError: continue except AttributeError as error: if str(error)== "'_SixMetaPathImporter' object has no attribute '_path'": # work around for https://github.com/benjaminp/six/issues/376 continue raise if not filename: continue filename = os.path.abspath(filename) if ( # The sentinel actually appearing in code messes things up 'executing' in filename # because of: {t[0] for t in lines2} - {t[0] for t in lines1} or 'pytester.py' in filename # A file that's particularly slow or 'errorcodes.py' in filename # Contains unreachable code which pypy removes or PYPY and ( 'sysconfig.py' in filename or 'pyparsing.py' in filename or 'enum' in filename ) or sys.version_info < (3,11) and ( 'python.py' in filename ) ): continue with open(filename) as source: source_text = source.read() if PYPY and "__debug__" in source_text: continue try: > self.check_filename(filename, check_names=False) tests/test_main.py:826: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_main.py:888: in check_filename result = list(self.check_code(code, nodes, decorators, check_names=check_names)) tests/test_main.py:1243: in check_code ex = Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Subscript(value=Name(id='Callable', ctx=Load()), slice=Tuple(elts=[Constant(value=Ellipsis, kind=None), Name(id='object', ctx=Load(...))], ctx=Load()), ctx=Load()) instruction = Instruction(opname='BINARY_OP', opcode=44, arg=26, argval=26, argrepr='[]', offset=958, start_offset=958, starts_line=...et=51, end_col_offset=72), cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( > ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): E KeyError: '[]' executing/_position_node_finder.py:661: KeyError ----------------------------- Captured stdout call ----------------------------- check /usr/lib64/python3.14/asyncio/base_tasks.py check /usr/lib64/python3.14/importlib/resources/__init__.py check /usr/lib/python3.14/site-packages/_pytest/fixtures.py mapping failed '[]' search bytecode BINARY_OP 26 ([]) in file /usr/lib/python3.14/site-packages/_pytest/fixtures.py at position Positions(lineno=91, end_lineno=91, col_offset=51, end_col_offset=72) source code: 87: 88: # The value of the fixture -- return/yield of the fixture function (type variable). 89: FixtureValue = TypeVar("FixtureValue") 90: # The type of the fixture function (type variable). 91: FixtureFunction = TypeVar("FixtureFunction", bound=Callable[..., object]) 92: # The type of a fixture function (type alias generic in fixture value). 93: _FixtureFunc = Union[ 94: Callable[..., FixtureValue], Callable[..., Generator[FixtureValue, None, None]] 95: ] 96: # The type of FixtureDef.cached_result (type alias generic in fixture value). possible node 91 91 60 63 Constant(value=Ellipsis) possible node 91 91 65 71 Name(id='object', ctx=Load()) possible node 91 91 51 59 Name(id='Callable', ctx=Load()) possible node 91 91 60 71 Tuple(elts=[Constant(value=Ellipsis), Name(id='object', ctx=Load())], ctx=Load()) possible node 91 91 51 72 Subscript(value=Name(id='Callable', ctx=Load()), slice=Tuple(elts=[Constant(value=Ellipsis), Name(id='object', ctx=Load())], ctx=Load()), ctx=Load()) possible node 91 91 45 72 keyword(arg='bound', value=Subscript(value=Name(id='Callable', ctx=Load()), slice=Tuple(elts=[Constant(value=Ellipsis), Name(id='object', ctx=Load())], ctx=Load()), ctx=Load())) possible node 91 91 18 73 Call(func=Name(id='TypeVar', ctx=Load()), args=[Constant(value='FixtureFunction')], keywords=[keyword(arg='bound', value=Subscript(value=Name(id='Callable', ctx=Load()), slice=Tuple(elts=[Constant(value=Ellipsis), Name(id='object', ctx=Load())], ctx=Load()), ctx=Load()))]) possible node 91 91 0 73 Assign(targets=[Name(id='FixtureFunction', ctx=Store())], value=Call(func=Name(id='TypeVar', ctx=Load()), args=[Constant(value='FixtureFunction')], keywords=[keyword(arg='bound', value=Subscript(value=Name(id='Callable', ctx=Load()), slice=Tuple(elts=[Constant(value=Ellipsis), Name(id='object', ctx=Load())], ctx=Load()), ctx=Load()))])) ___________________________ test_global_tester_calls ___________________________ def test_global_tester_calls(): # tester calls should be tested at global scope > from . import global_tester_calls tests/test_main.py:1550: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/global_tester_calls.py:8: in assert tester[1 + 2] is tester tests/utils.py:90: in __getitem__ node = self.get_node(ast.Subscript) tests/utils.py:35: in get_node ex = self.get_executing(inspect.currentframe().f_back.f_back) tests/utils.py:42: in get_executing return Source.executing(frame) executing/executing.py:273: in executing node_finder = NodeFinder(frame, stmts, tree, lasti, source) executing/_position_node_finder.py:170: in __init__ self.verify(self.result, instruction) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = node = Subscript(value=Name(id='tester', ctx=Load()), slice=BinOp(left=Constant(value=1, kind=None), op=Add(), right=Constant(value=2, kind=None)), ctx=Load()) instruction = Instruction(opname='BINARY_OP', opcode=44, arg=26, argval=26, argrepr='[]', offset=92, start_offset=92, starts_line=Fa...set=7, end_col_offset=20), cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]) def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None: """ checks if this node could gererate this instruction """ op_name = instruction.opname extra_filter: Callable[[EnhancedAST], bool] = lambda e: True ctx: Type = type(None) def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool: """ match instruction Parameters: opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname` **kwargs: every arg has to match inst.arg Returns: True if all conditions match the instruction """ if isinstance(opnames, str): opnames = [opnames] return instruction.opname in opnames and kwargs == { k: getattr(instruction, k) for k in kwargs } def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool: """ match the ast-node Parameters: node_type: type of the node **kwargs: every `arg` has to be equal `node.arg` or `node.arg` has to be an instance of `arg` if it is a type. """ return isinstance(node, node_type) and all( isinstance(getattr(node, k), v) if isinstance(v, type) else getattr(node, k) == v for k, v in kwargs.items() ) if op_name == "CACHE": return if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)): # call to context.__exit__ return if inst_match(("CALL", "LOAD_FAST")) and node_match( (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp) ): # call to the generator function return if ( sys.version_info >= (3, 12) and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST")) and node_match((ast.ListComp, ast.SetComp, ast.DictComp)) ): return if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match( (ast.ClassDef, ast.Call) ): return if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match( ast.Compare ): return if inst_match("LOAD_NAME", argval="__annotations__") and node_match( ast.AnnAssign ): return if ( ( inst_match("LOAD_METHOD", argval="join") or inst_match("LOAD_ATTR", argval="join") # 3.12 or inst_match(("CALL", "BUILD_STRING")) ) and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod) and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str) ): # "..."%(...) uses "".join return if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign): # data: int return if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match( ast.Name, id=instruction.argval, ctx=ast.Del ): return if inst_match("BUILD_STRING") and ( node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod) ): return if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With): return if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match( ast.Constant ): # store docstrings return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF")) and node_match(ast.ExceptHandler) and instruction.argval == mangled_name(node) ): # store exception in variable return if ( inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL")) and node_match((ast.Import, ast.ImportFrom)) and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names) ): # store imported module in variable return if ( inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL")) and ( node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)) or node_match( ast.Name, ctx=ast.Store, ) ) and instruction.argval == mangled_name(node) ): return if False: # TODO: match expressions are not supported for now if inst_match(("STORE_FAST", "STORE_NAME")) and node_match( ast.MatchAs, name=instruction.argval ): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence): return if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue): return if inst_match("BINARY_OP") and node_match( > ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")] ): E KeyError: '[]' executing/_position_node_finder.py:661: KeyError ______________________________ test_mangled_name _______________________________ def test_mangled_name(): def result(*code_levels): code = "" for i, level in enumerate(code_levels): code += indent(level, " " * i) + "\n" tree = ast.parse(code) for parent in ast.walk(tree): for child in ast.iter_child_nodes(parent): child.parent = parent tree_names = { mangled_name(n) for n in ast.walk(tree) if isinstance( n, ( ast.Name, ast.Attribute, ast.alias, ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef, ast.ExceptHandler, ), ) } def collect_names(code): for instruction in dis.get_instructions(code): if instruction.opname in ( "STORE_NAME", "LOAD_NAME", "LOAD_GLOBAL", "STORE_FAST", "LOAD_FAST", "LOAD_ATTR", "STORE_ATTR", ): # TODO: "IMPORT_FROM" gets also mangled but is currently not handled by executing # # class Test: # from __mangle11c.__suc11c import __submodule11c as __subc11 # IMPORT_FROM(_Test__submodule11c) # STORE_NAME(_Test__subc11) name = instruction.argval if name in ("__module__", "__qualname__", "__name__","__static_attributes__","__firstlineno__"): continue yield name for const in code.co_consts: if isinstance(const, type(code)): for name in collect_names(const): yield name code_names = set(collect_names(compile(tree, "", "exec"))) assert code_names == tree_names return tree_names code = "from __mangle11c.__suc11c import __submodule11c as __subc11" assert result(code) == {"__subc11"} assert result("class Test:", code) == {"Test", "_Test__subc11"} > assert result("class Test:", "def func():", code) == { "Test", "func", "_Test__subc11", } tests/test_pytest.py:245: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ code_levels = ('class Test:', 'def func():', 'from __mangle11c.__suc11c import __submodule11c as __subc11') code = 'class Test:\n def func():\n from __mangle11c.__suc11c import __submodule11c as __subc11\n' i = 2, level = 'from __mangle11c.__suc11c import __submodule11c as __subc11' def result(*code_levels): code = "" for i, level in enumerate(code_levels): code += indent(level, " " * i) + "\n" tree = ast.parse(code) for parent in ast.walk(tree): for child in ast.iter_child_nodes(parent): child.parent = parent tree_names = { mangled_name(n) for n in ast.walk(tree) if isinstance( n, ( ast.Name, ast.Attribute, ast.alias, ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef, ast.ExceptHandler, ), ) } def collect_names(code): for instruction in dis.get_instructions(code): if instruction.opname in ( "STORE_NAME", "LOAD_NAME", "LOAD_GLOBAL", "STORE_FAST", "LOAD_FAST", "LOAD_ATTR", "STORE_ATTR", ): # TODO: "IMPORT_FROM" gets also mangled but is currently not handled by executing # # class Test: # from __mangle11c.__suc11c import __submodule11c as __subc11 # IMPORT_FROM(_Test__submodule11c) # STORE_NAME(_Test__subc11) name = instruction.argval if name in ("__module__", "__qualname__", "__name__","__static_attributes__","__firstlineno__"): continue yield name for const in code.co_consts: if isinstance(const, type(code)): for name in collect_names(const): yield name code_names = set(collect_names(compile(tree, "", "exec"))) > assert code_names == tree_names E AssertionError: assert {'Test', '_Te...ll__', 'func'} == {'Test', '_Te...bc11', 'func'} E E Extra items in the left set: E '__classdictcell__' E Use -v to get more diff tests/test_pytest.py:235: AssertionError =============================== warnings summary =============================== tests/test_main.py::test_small_samples[4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5.py] /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0/tests/small_samples/4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5.py:16: SyntaxWarning: "is" with 'int' literal. Did you mean "=="? if 1 < 1 > 1 == 1 >= 1 <= 1 != 1 in 1 not in 1 is 1 is not 1: -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html ================== 78 failed, 131 passed, 1 warning in 10.51s ================== py314: exit 1 (11.23 seconds) /builddir/build/BUILD/python-executing-2.2.0-build/executing-2.2.0> pytest tests -rs pid=296 py314: FAIL code 1 (11.23 seconds) evaluation failed :( (11.29 seconds) error: Bad exit status from /var/tmp/rpm-tmp.bvLS8T (%check) Bad exit status from /var/tmp/rpm-tmp.bvLS8T (%check) RPM build errors: Finish: rpmbuild python-executing-2.2.0-2.fc43.src.rpm Finish: build phase for python-executing-2.2.0-2.fc43.src.rpm INFO: chroot_scan: 1 files copied to /var/lib/copr-rpmbuild/results/chroot_scan INFO: /var/lib/mock/fedora-rawhide-x86_64-1747249355.591554/root/var/log/dnf5.log INFO: chroot_scan: creating tarball /var/lib/copr-rpmbuild/results/chroot_scan.tar.gz /bin/tar: Removing leading `/' from member names ERROR: Exception(/var/lib/copr-rpmbuild/results/python-executing-2.2.0-2.fc43.src.rpm) Config(fedora-rawhide-x86_64) 0 minutes 26 seconds INFO: Results and/or logs in: /var/lib/copr-rpmbuild/results INFO: Cleaning up build root ('cleanup_on_failure=True') Start: clean chroot INFO: unmounting tmpfs. Finish: clean chroot ERROR: Command failed: # /usr/bin/systemd-nspawn -q -M 156afb50373f4d3d912fed70e2e3a8cc -D /var/lib/mock/fedora-rawhide-x86_64-1747249355.591554/root -a -u mockbuild --capability=cap_ipc_lock --rlimit=RLIMIT_NOFILE=10240 --capability=cap_ipc_lock --bind=/tmp/mock-resolv._pv79qsv:/etc/resolv.conf --bind=/dev/btrfs-control --bind=/dev/mapper/control --bind=/dev/fuse --bind=/dev/loop-control --bind=/dev/loop0 --bind=/dev/loop1 --bind=/dev/loop2 --bind=/dev/loop3 --bind=/dev/loop4 --bind=/dev/loop5 --bind=/dev/loop6 --bind=/dev/loop7 --bind=/dev/loop8 --bind=/dev/loop9 --bind=/dev/loop10 --bind=/dev/loop11 --console=pipe --setenv=TERM=vt100 --setenv=SHELL=/bin/bash --setenv=HOME=/builddir --setenv=HOSTNAME=mock --setenv=PATH=/usr/bin:/bin:/usr/sbin:/sbin '--setenv=PROMPT_COMMAND=printf "\033]0;\007"' '--setenv=PS1= \s-\v\$ ' --setenv=LANG=C.UTF-8 --resolv-conf=off bash --login -c '/usr/bin/rpmbuild -ba --noprep --target x86_64 --nodeps /builddir/build/originals/python-executing.spec' Copr build error: Build failed