* Package: dev-db/mycli-1.22.2_p20201026 * Repository: gentoo * Maintainer: grknight@gentoo.org * USE: abi_x86_64 amd64 elibc_glibc kernel_linux python_single_target_python3_8 test userland_GNU * FEATURES: network-sandbox preserve-libs sandbox test userpriv usersandbox @@@@@ PLEASE PAY ATTENTION HERE!!! @@@@@ This information may help you to understand if this is a duplicate or if this bug exists after you pushed a fix; This ebuild was merged at the following commit: https://github.com/gentoo/gentoo/commit/acafc56974395ed442f8a4394c836f434763b667 (Sun May 23 10:48:07 UTC 2021) @@@@@ END @@@@@ @@@@@ PLEASE PAY ATTENTION HERE!!! @@@@@ This ebuild was merged (directly or as a dependency) because of the following commit: https://github.com/gentoo/gentoo/commit/67ed3e80d6bd581b0066e2c5e6948fd19edf3a03 @@@@@ END @@@@@ ################## # emerge --info: # ################## Portage 3.0.18 (python 3.9.5-final-0, default/linux/amd64/17.1, gcc-11.1.0, glibc-2.33, 5.4.0-1048-aws x86_64) ================================================================= System uname: Linux-5.4.0-1048-aws-x86_64-Intel-R-_Xeon-R-_Platinum_8259CL_CPU_@_2.50GHz-with-glibc2.33 KiB Mem: 65048036 total, 47845128 free KiB Swap: 0 total, 0 free sh bash 5.1_p8 ld GNU ld (Gentoo 2.36.1 p3) 2.36.1 app-shells/bash: 5.1_p8::gentoo dev-lang/perl: 5.34.0::gentoo dev-lang/python: 2.7.18_p10::gentoo, 3.7.10_p4::gentoo, 3.8.10_p1::gentoo, 3.9.5_p1::gentoo, 3.10.0_beta1::gentoo dev-lang/rust: 1.52.1::gentoo dev-util/cmake: 3.20.2::gentoo dev-util/pkgconfig: 0.29.2::gentoo sys-apps/baselayout: 2.7-r2::gentoo sys-apps/openrc: 0.43.3::gentoo sys-apps/sandbox: 2.24::gentoo sys-devel/autoconf: 2.13-r1::gentoo, 2.69-r5::gentoo sys-devel/automake: 1.16.3-r1::gentoo sys-devel/binutils: 2.36.1-r1::gentoo sys-devel/gcc: 11.1.0::gentoo sys-devel/gcc-config: 2.4::gentoo sys-devel/libtool: 2.4.6-r6::gentoo sys-devel/make: 4.3::gentoo sys-kernel/linux-headers: 5.12::gentoo (virtual/os-headers) sys-libs/glibc: 2.33::gentoo Repositories: gentoo location: /usr/portage sync-type: rsync sync-uri: rsync://rsync.gentoo.org/gentoo-portage priority: -1000 sync-rsync-extra-opts: sync-rsync-verify-max-age: 24 sync-rsync-verify-jobs: 1 sync-rsync-verify-metamanifest: yes ACCEPT_KEYWORDS="amd64 ~amd64" ACCEPT_LICENSE="* BSD MIT" CBUILD="x86_64-pc-linux-gnu" CFLAGS="-O2 -pipe -march=x86-64 -frecord-gcc-switches" CHOST="x86_64-pc-linux-gnu" CONFIG_PROTECT="/etc /usr/share/gnupg/qualified.txt" CONFIG_PROTECT_MASK="/etc/ca-certificates.conf /etc/env.d /etc/gconf /etc/gentoo-release /etc/revdep-rebuild /etc/sandbox.d /etc/terminfo" CXXFLAGS="-O2 -pipe -march=x86-64 -frecord-gcc-switches" DISTDIR="/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/distdir" EMERGE_DEFAULT_OPTS="--with-bdeps=y -1 -k -b" ENV_UNSET="CARGO_HOME DBUS_SESSION_BUS_ADDRESS DISPLAY GOBIN GOPATH PERL5LIB PERL5OPT PERLPREFIX PERL_CORE PERL_MB_OPT PERL_MM_OPT XAUTHORITY XDG_CACHE_HOME XDG_CONFIG_HOME XDG_DATA_HOME XDG_RUNTIME_DIR" FCFLAGS="-O2 -pipe -march=x86-64 -frecord-gcc-switches" FEATURES="assume-digests binpkg-docompress binpkg-dostrip binpkg-logs binpkg-multi-instance buildpkg config-protect-if-modified distlocks ebuild-locks fixlafiles ipc-sandbox merge-sync multilib-strict network-sandbox news parallel-fetch pid-sandbox preserve-libs protect-owned qa-unresolved-soname-deps sandbox sfperms sign split-log strict test unknown-features-warn unmerge-logs unmerge-orphans userfetch userpriv usersandbox usersync xattr" FFLAGS="-O2 -pipe -march=x86-64 -frecord-gcc-switches" GENTOO_MIRRORS="http://distfiles.gentoo.org" LANG="en_US.utf8" LDFLAGS="-Wl,-O1 -Wl,--as-needed -Wl,--defsym=__gentoo_check_ldflags__=0" MAKEOPTS="-j16" PKGDIR="/root/.packages" PORTAGE_CONFIGROOT="/" PORTAGE_RSYNC_OPTS="--recursive --links --safe-links --perms --times --omit-dir-times --compress --force --whole-file --delete --stats --human-readable --timeout=180 --exclude=/distfiles --exclude=/local --exclude=/packages --exclude=/.git" PORTAGE_TMPDIR="/var/tmp" USE="acl amd64 berkdb bzip2 cli crypt dri elogind fortran gdbm iconv ipv6 jumbo-build libglvnd libtirpc multilib native-symlinks ncurses nls nptl openmp pam pcre readline seccomp split-usr ssl tcpd test unicode xattr zlib" ABI_X86="64" ELIBC="glibc" KERNEL="linux" PYTHON_SINGLE_TARGET="python3_8" USERLAND="GNU" Unset: CC, CPPFLAGS, CTARGET, CXX, INSTALL_MASK, LC_ALL, LINGUAS, PORTAGE_BINHOST, PORTAGE_BUNZIP2_COMMAND, PORTAGE_COMPRESS, PORTAGE_COMPRESS_FLAGS, PORTAGE_RSYNC_EXTRA_OPTS, RUSTFLAGS ############################## # emerge history (qlop -mv): # ############################## 2021-05-23T13:57:43 >>> dev-python/six-1.16.0 2021-05-23T13:57:42 >>> dev-python/pygments-2.9.0 2021-05-23T13:57:42 >>> dev-python/wcwidth-0.2.5-r1 2021-05-23T13:57:43 >>> dev-python/pymysql-1.0.2 2021-05-23T13:57:44 >>> dev-python/sqlparse-0.4.1 2021-05-23T13:57:44 >>> dev-python/ply-3.11-r1 2021-05-23T13:57:44 >>> dev-python/typing-extensions-3.10.0.0 2021-05-23T13:57:45 >>> dev-python/zipp-3.4.1 2021-05-23T13:57:45 >>> dev-python/terminaltables-3.1.0 2021-05-23T13:57:54 >>> dev-python/configobj-5.0.6-r1 2021-05-23T13:57:59 >>> dev-python/prompt_toolkit-3.0.18 2021-05-23T13:57:59 >>> dev-python/tabulate-0.8.9 2021-05-23T13:58:05 >>> dev-python/pycparser-2.20-r1 2021-05-23T13:58:09 >>> dev-python/importlib_metadata-4.0.0 2021-05-23T13:58:24 >>> dev-python/cffi-1.14.5 2021-05-23T13:58:26 >>> dev-python/click-8.0.1 2021-05-23T13:58:30 >>> dev-python/cryptography-3.4.7-r1 2021-05-23T13:58:22 >>> dev-python/cli_helpers-2.1.0 2021-05-23T13:58:40 >>> dev-db/mycli-1.22.2_p20201026 2021-05-23T13:58:55 >>> dev-python/mock-4.0.3 2021-05-23T13:58:56 >>> dev-python/iniconfig-1.1.1 2021-05-23T13:58:56 >>> dev-python/more-itertools-8.8.0 2021-05-23T13:58:57 >>> dev-python/py-1.10.0 2021-05-23T13:58:57 >>> dev-python/pyparsing-2.4.7-r1 2021-05-23T13:58:58 >>> dev-python/pluggy-0.13.1-r1 2021-05-23T13:58:59 >>> dev-python/namespace-zope-1-r1 2021-05-23T13:59:12 >>> dev-python/packaging-20.9 2021-05-23T13:59:15 >>> dev-python/zope-interface-5.4.0 2021-05-23T13:59:21 >>> dev-python/attrs-21.2.0 2021-05-23T13:59:24 >>> dev-python/pytest-6.2.4 ####################################### # installed packages (qlist -ICvUSS): # ####################################### acct-group/audio-0-r1:0 acct-group/cdrom-0-r1:0 acct-group/dialout-0-r1:0 acct-group/disk-0-r1:0 acct-group/input-0-r1:0 acct-group/kmem-0-r1:0 acct-group/kvm-0-r1:0 acct-group/lp-0-r1:0 acct-group/man-0-r1:0 acct-group/messagebus-0-r1:0 acct-group/polkitd-0-r1:0 acct-group/portage-0:0 acct-group/render-0-r1:0 acct-group/sshd-0-r1:0 acct-group/tape-0-r1:0 acct-group/tty-0-r1:0 acct-group/video-0-r1:0 acct-user/man-1-r1:0 acct-user/messagebus-0-r1:0 acct-user/polkitd-0-r1:0 acct-user/portage-0:0 acct-user/sshd-0-r1:0 app-admin/eselect-1.4.17:0 -doc -emacs -vim-syntax app-admin/perl-cleaner-2.30:0 app-arch/bzip2-1.0.8-r1:0/1 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 split-usr -static -static-libs app-arch/gzip-1.10:0 -pic -static app-arch/libarchive-3.5.1:0/13 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 acl -blake2 bzip2 e2fsprogs -expat iconv -lz4 lzma -lzo -nettle -static-libs threads xattr zlib -zstd app-arch/tar-1.34:0 acl -minimal nls -selinux xattr app-arch/unzip-6.0_p26:0 bzip2 -natspec unicode app-arch/xz-utils-5.2.5:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 extra-filters nls split-usr -static-libs threads app-arch/zstd-1.5.0:0/1 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -lz4 -static-libs threads app-crypt/gnupg-2.2.27:0 bzip2 -doc -ldap nls readline -scd-shared-access -selinux smartcard ssl -tofu -tools -usb -user-socket -wks-server app-crypt/gpgme-1.15.1:1/11 -common-lisp cxx -python python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -qt5 -static-libs app-crypt/libb2-0.98.1-r3:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -native-cflags openmp -static-libs app-crypt/openpgp-keys-gentoo-release-20200704:0 -test app-crypt/pinentry-1.1.1-r1:0 -caps -efl -emacs -gnome-keyring -gtk ncurses -qt5 app-crypt/rhash-1.4.1:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -debug nls ssl -static-libs app-editors/nano-5.7:0 -debug -justify -magic -minimal ncurses nls spell split-usr -static unicode app-eselect/eselect-iptables-20200508:0 app-eselect/eselect-lib-bin-symlink-0.1.1-r1:0 app-eselect/eselect-pinentry-0.7.2:0 app-eselect/eselect-python-20200719:0 app-eselect/eselect-rust-20200419:0 app-i18n/man-pages-it-5.06:0 app-i18n/man-pages-ja-20180315:0 app-i18n/man-pages-l10n-4.2.0-r1:0 l10n_de l10n_fr l10n_nl l10n_pl l10n_pt-BR l10n_ro app-i18n/man-pages-ru-5.03.2390.2390.20191017:0 app-i18n/man-pages-zh_CN-1.6.3.2:0 app-misc/c_rehash-1.7-r1:0 app-misc/ca-certificates-20210119.3.64:0 -cacert app-misc/editor-wrapper-4-r1:0 app-misc/mime-types-9:0 app-misc/pax-utils-1.3.1:0 -caps -debug -python -python_single_target_python3_7 python_single_target_python3_8 -python_single_target_python3_9 seccomp app-misc/tmux-3.2-r1:0 -debug -selinux -utempter -vim-syntax app-portage/eix-0.34.12:0 -debug -doc nls -sqlite app-portage/elt-patches-20201205:0 app-portage/gemato-16.2:0 gpg python_targets_pypy3 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test -tools app-portage/gentoolkit-0.5.1:0 python_targets_pypy3 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test app-portage/portage-utils-0.91:0 nls openmp qmanifest qtegrity -static app-shells/bash-5.1_p8:0 -afs -bashlogger -examples -mem-scramble net nls -plugins readline app-shells/push-3.4:0 app-shells/quoter-4.2:0 app-text/ansifilter-2.18:0 -qt5 app-text/build-docbook-catalog-1.21:0 app-text/docbook-xml-dtd-4.5-r2:4.5 app-text/docbook-xml-dtd-4.4-r3:4.4 app-text/docbook-xml-dtd-4.2-r3:4.2 app-text/docbook-xml-dtd-4.1.2-r7:4.1.2 app-text/docbook-xsl-stylesheets-1.79.1-r2:0 -ruby app-text/manpager-1:0 app-text/opensp-1.5.2-r6:0 -doc nls -static-libs -test app-text/po4a-0.63:0 -test app-text/sgml-common-0.6.3-r7:0 app-text/xmlto-0.0.28-r6:0 -latex -text dev-db/mycli-1.22.2_p20201026:0 -python_single_target_python3_7 python_single_target_python3_8 -python_single_target_python3_9 -ssh -test dev-db/sqlite-3.35.5:3 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -debug -doc -icu readline -secure-delete -static-libs -tcl -test -tools dev-lang/perl-5.34.0:0/5.34 berkdb -debug -doc gdbm -ithreads -minimal dev-lang/python-3.10.0_beta1:3.10 -bluetooth -build -examples gdbm -hardened ipv6 ncurses readline sqlite ssl -test -tk -verify-sig -wininst xml dev-lang/python-3.9.5_p1:3.9 -bluetooth -build -examples gdbm -hardened ipv6 ncurses readline sqlite ssl -test -tk -verify-sig -wininst xml dev-lang/python-3.8.10_p1:3.8 -bluetooth -build -examples gdbm -hardened ipv6 ncurses readline sqlite ssl -test -tk -verify-sig -wininst xml dev-lang/python-3.7.10_p4:3.7/3.7m -bluetooth -build -examples gdbm -hardened ipv6 ncurses readline sqlite ssl -test -tk -verify-sig -wininst xml dev-lang/python-2.7.18_p10:2.7 -berkdb -bluetooth -build -examples gdbm -hardened ipv6 ncurses readline sqlite ssl threads -tk -verify-sig wide-unicode -wininst xml dev-lang/python-exec-2.4.6-r4:2 native-symlinks python_targets_pypy3 python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 dev-lang/python-exec-conf-2.4.6:2 python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 dev-lang/rust-1.52.1:stable/1.52 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -clippy cpu_flags_x86_sse2 -debug -doc -llvm_targets_AArch64 -llvm_targets_AMDGPU -llvm_targets_ARM -llvm_targets_AVR -llvm_targets_BPF -llvm_targets_Hexagon -llvm_targets_Lanai -llvm_targets_Mips -llvm_targets_MSP430 -llvm_targets_NVPTX -llvm_targets_PowerPC -llvm_targets_RISCV -llvm_targets_Sparc -llvm_targets_SystemZ -llvm_targets_WebAssembly llvm_targets_X86 -llvm_targets_XCore -miri -nightly -parallel-compiler -rls -rustfmt -system-bootstrap -system-llvm -test -verify-sig -wasm dev-lang/spidermonkey-78.10.1:78 -clang -cpu_flags_arm_neon -debug jit -lto -test dev-lang/tcl-8.6.11:0/8.6 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -debug threads dev-libs/elfutils-0.184:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 bzip2 -lzma nls -static-libs -test -threads utils -valgrind -zstd dev-libs/expat-2.3.0:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -examples split-usr -static-libs unicode dev-libs/glib-2.68.2:2 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -dbus -debug elf -fam -gtk-doc mime -selinux -static-libs -sysprof -systemtap -test -utils xattr dev-libs/gmp-6.2.1-r1:0/10.4 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 asm cxx -doc -pic -static-libs dev-libs/gobject-introspection-1.68.0:0 -doctool -gtk-doc -python_single_target_python3_7 python_single_target_python3_8 -python_single_target_python3_9 -test dev-libs/gobject-introspection-common-1.68.0:0 dev-libs/icu-69.1:0/69.1 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -debug -doc -examples -static-libs dev-libs/isl-0.24:0/23 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -static-libs dev-libs/jsoncpp-1.9.4:0/24 -doc -test dev-libs/libassuan-2.5.5:0 dev-libs/libevent-2.1.12:0/2.1-7 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 clock-gettime -debug -malloc-replacement ssl -static-libs -test threads -verbose-debug dev-libs/libffi-3.3-r2:0/7 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -debug -pax_kernel -static-libs -test dev-libs/libgcrypt-1.9.3:0/20 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 asm -cpu_flags_arm_neon -cpu_flags_x86_aes -cpu_flags_x86_avx -cpu_flags_x86_avx2 -cpu_flags_x86_padlock -cpu_flags_x86_sha -cpu_flags_x86_sse4_1 -doc -o-flag-munging -static-libs dev-libs/libgpg-error-1.42:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -common-lisp nls -static-libs dev-libs/libksba-1.5.1:0 -static-libs dev-libs/libltdl-2.4.6:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -static-libs dev-libs/libpcre-8.44:3 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 bzip2 cxx jit -libedit pcre16 pcre32 readline recursion-limit split-usr -static-libs unicode zlib dev-libs/libpcre2-10.36-r1:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 bzip2 jit -libedit pcre16 pcre32 readline recursion-limit split-usr -static-libs unicode zlib dev-libs/libpipeline-1.5.3:0 -static-libs -test dev-libs/libtasn1-4.17.0:0/6 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -doc -static-libs -test -valgrind dev-libs/libunistring-0.9.10-r1:0/2 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -doc -static-libs dev-libs/libuv-1.41.0:0/1 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 dev-libs/libxml2-2.9.12-r1:2 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -debug -examples -icu ipv6 -lzma python python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 readline -static-libs -test -verify-sig dev-libs/libxslt-1.1.34-r1:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 crypt -debug -examples -static-libs -verify-sig dev-libs/mpc-1.2.1:0/3 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -static-libs dev-libs/mpfr-4.1.0:0/6 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -static-libs dev-libs/nettle-3.7.2:0/8-6 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 asm -cpu_flags_arm_neon -cpu_flags_x86_aes -cpu_flags_x86_sha -doc gmp -static-libs -test dev-libs/npth-1.6-r1:0 dev-libs/nspr-4.30:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -debug dev-libs/openssl-1.1.1k:0/1.1 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 asm -bindist cpu_flags_x86_sse2 -rfc3779 -sctp -sslv3 -static-libs -test -tls-heartbeat -vanilla zlib dev-libs/popt-1.18:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 nls -static-libs dev-perl/Encode-EUCJPASCII-0.30.0-r1:0 -test dev-perl/Encode-HanExtra-0.230.0-r3:0 dev-perl/Encode-Locale-1.50.0:0 -test dev-perl/File-Listing-6.70.0:0 -test dev-perl/HTML-Parser-3.720.0:0 -test dev-perl/HTML-Tagset-3.200.0-r1:0 dev-perl/HTTP-Cookies-6.40.0:0 -test dev-perl/HTTP-Date-6.20.0-r1:0 dev-perl/HTTP-Message-6.290.0:0 -test dev-perl/HTTP-Negotiate-6.10.0-r1:0 dev-perl/IO-HTML-1.1.0:0 -test dev-perl/IO-Socket-INET6-2.720.0-r1:0 dev-perl/IO-Socket-SSL-2.66.0:0 -examples -idn dev-perl/libwww-perl-6.530.0:0 ssl -test dev-perl/Locale-gettext-1.70.0:0 dev-perl/LWP-MediaTypes-6.20.0-r1:0 dev-perl/LWP-Protocol-https-6.70.0:0 -test dev-perl/MIME-Charset-1.12.2:0 l10n_ja l10n_zh dev-perl/Module-Build-0.422.400:0 -test dev-perl/Mozilla-CA-20999999:0 dev-perl/Net-HTTP-6.210.0:0 -minimal -test dev-perl/Net-SSLeay-1.880.0-r1:0 -examples -examples -minimal -test dev-perl/Pod-Parser-1.630.0-r1:0 -test dev-perl/SGMLSpm-1.1-r1:0 dev-perl/Socket6-0.280.0:0 dev-perl/Sub-Name-0.210.0:0 -suggested -test dev-perl/TermReadKey-2.370.0:0 -examples dev-perl/Text-CharWidth-0.40.0-r1:0 dev-perl/Text-WrapI18N-0.60.0-r1:0 dev-perl/Try-Tiny-0.300.0:0 -minimal -test dev-perl/Unicode-LineBreak-2019.1.0:0 dev-perl/URI-1.730.0:0 -test dev-perl/WWW-RobotRules-6.20.0-r1:0 dev-perl/XML-Parser-2.460.0:0 dev-perl/YAML-Tiny-1.730.0:0 -minimal -test dev-python/attrs-21.2.0:0 python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/certifi-10001-r1:0 python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/cffi-1.14.5:0/1.14.5 -doc -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/chardet-4.0.0:0 python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/cli_helpers-2.1.0:0 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/click-8.0.1:0 -doc -examples python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/configobj-5.0.6-r1:0 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/cryptography-3.4.7-r1:0 python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/idna-3.1:0 python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 dev-python/importlib_metadata-4.0.0:0 -doc python_targets_pypy3 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/iniconfig-1.1.1:0 python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/jinja-3.0.1:0 -doc -examples python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/markupsafe-2.0.1:0 python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/mock-4.0.3:0 python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 dev-python/more-itertools-8.8.0:0 -doc python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/namespace-zope-1-r1:0 python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 dev-python/packaging-20.9:0 python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/pluggy-0.13.1-r1:0 python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/ply-3.11-r1:0/3.11 -examples python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 dev-python/prompt_toolkit-3.0.18:0 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/py-1.10.0:0 -doc python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/pycparser-2.20-r1:0 python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 dev-python/pygments-2.9.0:0 -doc python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/pymysql-1.0.2:0 python_targets_pypy3 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/pyparsing-2.4.7-r1:0 -examples python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 dev-python/pypy3-7.3.4_p1:0/pypy37-pp73 bzip2 gdbm jit ncurses -sqlite -test -tk dev-python/pypy3-exe-7.3.4:7.3.4 bzip2 -cpu_flags_x86_sse2 jit -low-memory ncurses dev-python/PySocks-1.7.1-r1:0 python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 dev-python/pytest-6.2.4:0 python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/requests-2.25.1-r2:0 python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -socks5 -test dev-python/setuptools-57.0.0:0 python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/setuptools_scm-6.0.1-r1:0 python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/six-1.16.0:0 -doc python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/sqlparse-0.4.1:0 -doc -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/tabulate-0.8.9:0 python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/terminaltables-3.1.0:0 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/toml-0.10.2:0 python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test -test dev-python/typing-extensions-3.10.0.0:0 python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 dev-python/urllib3-1.26.4:0 -brotli python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/wcwidth-0.2.5-r1:0 python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/zipp-3.4.1:0 -doc python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-python/zope-interface-5.4.0:0 python_targets_pypy3 -python_targets_python3_10 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-util/cmake-3.20.2:0 -doc -emacs ncurses -qt5 -test -test dev-util/desktop-file-utils-0.26-r1:0 -emacs dev-util/glib-utils-2.68.2:0 -python_single_target_python3_7 python_single_target_python3_8 -python_single_target_python3_9 dev-util/gperf-3.1:0 dev-util/gtk-doc-am-1.33.2:0 dev-util/intltool-0.51.0-r2:0 dev-util/itstool-2.0.6-r1:0 -python_single_target_python3_7 python_single_target_python3_8 -python_single_target_python3_9 dev-util/meson-0.57.2:0 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -test dev-util/meson-format-array-0:0 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 dev-util/ninja-1.10.2-r1:0 -doc -emacs -test -vim-syntax dev-util/pkgconfig-0.29.2:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -hardened -internal-glib dev-util/re2c-2.1.1-r1:0 -debug dev-vcs/git-2.31.1:0 blksha1 -cgi curl -cvs -doc -emacs -gnome-keyring gpg -highlight iconv -mediawiki -mediawiki-experimental nls pcre -perforce -perl -ppcsha1 -python_single_target_python3_7 python_single_target_python3_8 -python_single_target_python3_9 -subversion -test threads -tk webdav -xinetd net-dns/libidn2-2.3.1:0/2 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -static-libs -verify-sig net-firewall/iptables-1.8.7:0/1.8.3 -conntrack ipv6 -netlink -nftables -pcap split-usr -static-libs net-libs/gnutls-3.7.1:0/30 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 cxx -dane -doc -examples -guile idn nls openssl -pkcs11 seccomp -sslv2 -sslv3 -static-libs -test -test-full tls-heartbeat -tools -valgrind net-libs/libmnl-1.0.4:0/0.2.0 -examples split-usr -static-libs net-libs/libnsl-1.3.0-r1:0/2 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 net-libs/libtirpc-1.3.2:0/3 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 ipv6 -kerberos split-usr -static-libs net-libs/nghttp2-1.43.0:0/1.14 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -cxx -debug -hpack-tools -jemalloc -static-libs -test threads -utils -xml net-misc/curl-7.76.1:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -adns -alt-svc -brotli -curl_ssl_gnutls -curl_ssl_mbedtls -curl_ssl_nss curl_ssl_openssl -curl_ssl_winssl ftp -gnutls -gopher -hsts http2 -idn imap ipv6 -kerberos -ldap -mbedtls -metalink -nghttp3 -nss openssl pop3 progress-meter -quiche -rtmp -samba smtp -ssh ssl -sslv3 -static-libs -telnet -test tftp -threads -winssl -zstd net-misc/iputils-20210202:0 arping -caps -clockdiff -doc filecaps -gcrypt -idn ipv6 -nettle nls -rarpd -rdisc ssl -static -tftpd -tracepath -traceroute6 net-misc/netifrc-0.7.3:0 net-misc/openssh-8.6_p1-r1:0 -abi_mips_n32 -audit -bindist -debug -hpn -kerberos -ldns -libedit -livecd pam pie scp -sctp -security-key -selinux ssl -static -test -X -X509 -xmss net-misc/rsync-3.2.3-r3:0 acl -examples iconv ipv6 -lz4 ssl -stunnel -system-zlib xattr -xxhash -zstd net-misc/wget-1.21.1:0 -cookie_check -debug -gnutls -idn ipv6 -metalink nls -ntlm pcre ssl -static -test -uuid zlib perl-core/File-Temp-0.231.100:0 sys-apps/acl-2.3.1:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 nls split-usr -static-libs sys-apps/attr-2.5.1:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -debug nls split-usr -static-libs sys-apps/baselayout-2.7-r2:0 -build split-usr sys-apps/busybox-1.33.0:0 -debug ipv6 -livecd -make-symlinks -math -mdev -pam -savedconfig -selinux -sep-usr static -syslog -systemd sys-apps/coreutils-8.32-r1:0 acl -caps -gmp -hostname -kill -multicall nls -selinux split-usr -static -test -vanilla xattr sys-apps/dbus-1.12.20-r1:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -debug -doc elogind -selinux -static-libs -systemd -test -test -user-session -X sys-apps/debianutils-4.11.2:0 installkernel -static sys-apps/diffutils-3.7-r1:0 nls -static sys-apps/file-5.40-r2:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 bzip2 -lzma -python python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -seccomp -static-libs zlib sys-apps/findutils-4.8.0:0 nls -selinux -static -test sys-apps/gawk-5.1.0:0 -mpfr nls readline sys-apps/gentoo-functions-0.14:0 sys-apps/grep-3.6:0 nls pcre -static sys-apps/groff-1.22.4:0 -examples -uchardet -X sys-apps/help2man-1.48.3:0 nls sys-apps/hwids-20201207:0 net pci udev usb sys-apps/install-xattr-0.8:0 sys-apps/iproute2-5.10.0-r1:0 -atm berkdb -caps -elf iptables ipv6 -libbsd -minimal -selinux sys-apps/kbd-2.4.0:0 nls pam -test sys-apps/kmod-29:0 -debug -doc lzma -pkcs7 -python python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -static-libs tools zlib -zstd sys-apps/less-586:0 pcre unicode sys-apps/man-db-2.9.4:0 berkdb gdbm manpager nls seccomp -selinux -static-libs zlib sys-apps/man-pages-5.11:0 l10n_de l10n_fr l10n_it l10n_ja l10n_nl l10n_pl l10n_pt-BR l10n_ro l10n_ru l10n_zh-CN sys-apps/man-pages-posix-2017a:0 sys-apps/net-tools-2.10:0 arp hostname ipv6 -nis nls -plipconfig -selinux -slattach -static sys-apps/openrc-0.43.3:0 -audit -bash -debug ncurses netifrc -newnet pam -prefix -selinux -sysv-utils unicode sys-apps/portage-3.0.18:0 -apidoc -build -doc -gentoo-dev ipc native-extensions python_targets_pypy3 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 rsync-verify -selinux -test xattr sys-apps/sandbox-2.24:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 abi_x86_32 abi_x86_64 -abi_x86_x32 sys-apps/sed-4.8:0 acl nls -selinux -static sys-apps/shadow-4.8.1-r3:0 acl -audit -bcrypt -cracklib nls pam -selinux -skey split-usr su xattr sys-apps/systemd-tmpfiles-246:0 -selinux -test sys-apps/sysvinit-2.99:0 -ibm -selinux -static sys-apps/texinfo-6.7:0 nls standalone -static sys-apps/util-linux-2.36.2:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -audit -build -caps cramfs -cryptsetup -fdformat -hardlink -kill logger -magic ncurses nls pam -python python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 readline -selinux -slang split-usr -static-libs -su suid -systemd -test -tty-helpers -udev unicode sys-apps/which-2.21:0 sys-auth/elogind-246.10:0 acl -audit -debug -doc pam policykit -selinux sys-auth/pambase-20210201.1:0 -caps -debug elogind -gnome-keyring -homed -minimal -mktemp nullok -pam_krb5 -pam_ssh passwdqc -pwhistory -pwquality -securetty -selinux sha512 -systemd sys-auth/passwdqc-2.0.2:0 sys-auth/polkit-0.118:0 elogind -examples -gtk introspection -jit -kde nls pam -selinux -systemd -test sys-devel/autoconf-2.69-r5:2.69 -emacs sys-devel/autoconf-2.13-r1:2.1 sys-devel/autoconf-archive-2021.02.19:0 sys-devel/autoconf-wrapper-15:0 sys-devel/automake-1.16.3-r1:1.16 -test sys-devel/automake-wrapper-11:0 sys-devel/binutils-2.36.1-r1:2.36 -cet -default-gold -doc gold -multitarget nls plugins -static-libs -test -vanilla sys-devel/binutils-config-5.4:0 native-symlinks sys-devel/bison-3.7.6:0 -examples nls -static -test sys-devel/flex-2.6.4-r1:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 nls -static -test sys-devel/gcc-11.1.0:11 -ada -custom-cflags cxx -d -debug -doc -fixed-point fortran -go graphite -hardened -jit -libssp lto multilib nls nptl -objc -objc++ -objc-gc openmp pch -pgo pie sanitize ssp -systemtap -test -valgrind -vanilla -vtv -zstd sys-devel/gcc-config-2.4:0 cc-wrappers native-symlinks sys-devel/gettext-0.21:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 acl -cvs cxx -doc -emacs -git -java -java ncurses nls openmp -static-libs sys-devel/gnuconfig-20210107:0 sys-devel/libtool-2.4.6-r6:2 -vanilla sys-devel/llvm-12.0.0:12 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -debug -doc -doc -exegesis -gold -libedit libffi -llvm_targets_AArch64 llvm_targets_AMDGPU -llvm_targets_ARC -llvm_targets_ARM -llvm_targets_AVR llvm_targets_BPF -llvm_targets_CSKY -llvm_targets_Hexagon -llvm_targets_Lanai -llvm_targets_Mips -llvm_targets_MSP430 llvm_targets_NVPTX -llvm_targets_PowerPC -llvm_targets_RISCV -llvm_targets_Sparc -llvm_targets_SystemZ -llvm_targets_VE -llvm_targets_WebAssembly llvm_targets_X86 -llvm_targets_XCore ncurses -test -xar -xml -z3 sys-devel/llvm-common-12.0.0:0 sys-devel/m4-1.4.18-r2:0 -examples sys-devel/make-4.3:0 -guile nls -static sys-devel/patch-2.7.6-r4:0 -static -test xattr sys-fs/e2fsprogs-1.46.2:0 -cron -fuse -lto nls split-usr -static-libs threads sys-fs/udev-248:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 acl kmod -selinux split-usr -static-libs sys-fs/udev-init-scripts-34:0 sys-kernel/installkernel-gentoo-3:0 sys-kernel/linux-headers-5.12:0 -headers-only sys-libs/db-6.0.35-r4:6.0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -cxx -doc -doc -examples -java -java -tcl -test -test sys-libs/e2fsprogs-libs-1.46.2:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 split-usr -static-libs sys-libs/gdbm-1.19:0/6 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 berkdb nls readline -static-libs sys-libs/glibc-2.33:2.2 -audit -caps -cet -compile-locales crypt -custom-cflags -doc -gd -headers-only multiarch multilib -multilib-bootstrap -nscd -profile -selinux ssp static-libs -static-pie -suid -systemtap -test -vanilla sys-libs/libcap-2.49:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 pam split-usr -static-libs sys-libs/libseccomp-2.5.1:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -python python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -static-libs sys-libs/ncurses-6.2_p20210123:0/6 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -ada cxx -debug -doc -gpm -minimal -profile split-usr -static-libs -test -threads tinfo -trace unicode sys-libs/pam-1.5.1:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -audit berkdb -debug filecaps -nis -selinux split-usr sys-libs/readline-8.1_p1:0/8 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 split-usr -static-libs unicode -utils sys-libs/timezone-data-2021a:0 -leaps-timezone nls -zic-slim sys-libs/zlib-1.2.11-r4:0/1 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 minizip split-usr -static-libs sys-process/procps-3.3.17:0/8 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 elogind kill -modern-top ncurses nls -selinux split-usr -static-libs -systemd -test unicode sys-process/psmisc-23.4-r1:0 ipv6 nls -selinux -X virtual/acl-0-r2:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -static-libs virtual/awk-1:0 virtual/dev-manager-0-r2:0 virtual/editor-0-r3:0 virtual/libc-1-r1:0 virtual/libcrypt-1-r1:0/1 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 static-libs virtual/libelf-3:0/1 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 virtual/libiconv-0-r2:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 virtual/libintl-0-r2:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 virtual/libudev-232-r3:0/1 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 -static-libs -systemd virtual/man-0-r4:0 virtual/os-headers-0-r2:0 virtual/package-manager-1:0 virtual/pager-0:0 virtual/perl-Carp-1.520.0-r1:0 virtual/perl-Compress-Raw-Bzip2-2.101.0:0 virtual/perl-Compress-Raw-Zlib-2.101.0:0 virtual/perl-CPAN-Meta-2.150.10-r5:0 virtual/perl-CPAN-Meta-Requirements-2.140.0-r7:0 virtual/perl-CPAN-Meta-YAML-0.18.0-r7:0 virtual/perl-Data-Dumper-2.179.0:0 virtual/perl-Digest-MD5-2.580.0:0 virtual/perl-Encode-3.80.0:0 virtual/perl-Exporter-5.760.0:0 virtual/perl-ExtUtils-CBuilder-0.280.236:0 virtual/perl-ExtUtils-Install-2.200.0:0 virtual/perl-ExtUtils-MakeMaker-7.620.0:0 virtual/perl-ExtUtils-Manifest-1.730.0:0 virtual/perl-ExtUtils-ParseXS-3.430.0:0 virtual/perl-File-Spec-3.800.0:0 virtual/perl-File-Temp-0.231.100:0 virtual/perl-Getopt-Long-2.520.0:0 virtual/perl-IO-1.460.0:0 virtual/perl-IO-Compress-2.102.0:0 virtual/perl-IO-Socket-IP-0.410.0:0 virtual/perl-JSON-PP-4.60.0:0 virtual/perl-libnet-3.130.0:0 ssl virtual/perl-MIME-Base64-3.160.0:0 virtual/perl-Module-Metadata-1.0.37-r1:0 virtual/perl-parent-0.238.0-r1:0 virtual/perl-Parse-CPAN-Meta-2.150.10-r5:0 virtual/perl-Perl-OSType-1.10.0-r5:0 virtual/perl-Pod-Parser-1.630.0-r8:0 virtual/perl-podlators-4.140.0-r2:0 virtual/perl-Scalar-List-Utils-1.550.0-r1:0 virtual/perl-Test-Harness-3.430.0:0 virtual/perl-Text-ParseWords-3.300.0-r8:0 virtual/perl-Time-Local-1.300.0:0 virtual/perl-version-0.992.800:0 virtual/perl-XSLoader-0.300.0-r4:0 virtual/pkgconfig-2:0 virtual/rust-1.52.1:0 -abi_mips_n32 -abi_mips_n64 -abi_mips_o32 -abi_s390_32 -abi_s390_64 -abi_x86_32 abi_x86_64 -abi_x86_x32 virtual/service-manager-1:0 virtual/ssh-0:0 -minimal virtual/tmpfiles-0-r1:0 virtual/udev-217-r2:0 virtual/yacc-0:0 www-client/pybugz-0.13:0 python_targets_python3_7 python_targets_python3_8 python_targets_python3_9 -zsh-completion x11-misc/shared-mime-info-2.1:0 ####################### # build.log # ####################### * Using python3.8 to build >>> Unpacking source... >>> Unpacking mycli-1.22.2_p20201026.tar.gz to /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work >>> Source unpacked in /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work >>> Preparing source in /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2 ... * Applying mycli-1.21.1-fix-test-install.patch ... [ ok ] * Applying mycli-1.22.2_p20201026.patch ... [ ok ] >>> Source prepared. >>> Configuring source in /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2 ... >>> Source configured. >>> Compiling source in /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2 ... python3.8 setup.py build -j 16 running build running build_py creating /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli copying mycli/sqlexecute.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli copying mycli/sqlcompleter.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli copying mycli/completion_refresher.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli copying mycli/__init__.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli copying mycli/compat.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli copying mycli/key_bindings.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli copying mycli/clibuffer.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli copying mycli/magic.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli copying mycli/lexer.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli copying mycli/config.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli copying mycli/clistyle.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli copying mycli/clitoolbar.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli copying mycli/main.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli creating /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli/packages copying mycli/packages/parseutils.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli/packages copying mycli/packages/__init__.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli/packages copying mycli/packages/prompt_utils.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli/packages copying mycli/packages/filepaths.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli/packages copying mycli/packages/completion_engine.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli/packages creating /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli/packages/special copying mycli/packages/special/utils.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli/packages/special copying mycli/packages/special/delimitercommand.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli/packages/special copying mycli/packages/special/__init__.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli/packages/special copying mycli/packages/special/favoritequeries.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli/packages/special copying mycli/packages/special/dbcommands.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli/packages/special copying mycli/packages/special/main.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli/packages/special copying mycli/packages/special/iocommands.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli/packages/special creating /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli/packages/paramiko_stub copying mycli/packages/paramiko_stub/__init__.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli/packages/paramiko_stub creating /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli/packages/tabular_output copying mycli/packages/tabular_output/__init__.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli/packages/tabular_output copying mycli/packages/tabular_output/sql_format.py -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli/packages/tabular_output copying mycli/myclirc -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli copying mycli/AUTHORS -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli copying mycli/SPONSORS -> /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2_python3.8/lib/mycli warning: build_py: byte-compiling is disabled, skipping. >>> Source compiled. >>> Test phase: dev-db/mycli-1.22.2_p20201026 python3.8 -m pytest -vv -ra -l --capture=sys --doctest-modules --doctest-ignore-import-errors --ignore=setup.py --ignore=mycli/magic.py --ignore=mycli/packages/parseutils.py --ignore=test/features --ignore=mycli/packages/paramiko_stub/__init__.py ============================= test session starts ============================== platform linux -- Python 3.8.10, pytest-6.2.4, py-1.10.0, pluggy-0.13.1 -- /usr/bin/python3.8 cachedir: .pytest_cache rootdir: /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2, configfile: setup.cfg collected 260 items / 2 errors / 258 selected ==================================== ERRORS ==================================== ________________________ ERROR collecting mycli/main.py ________________________ /usr/lib/python3.8/doctest.py:939: in find self._find(tests, obj, name, module, source_lines, globs, {}) extraglobs = None file = '/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/main.py' globs = {'AutoSuggestFromHistory': , 'CompleteStyle': , 'CompletionRefresher': , 'ConditionalProcessor': , 'DEFAULT_BUFFER': 'DEFAULT_BUFFER', 'Document': , 'DynamicCompleter': , 'EditingMode': , 'FIELD_TYPES': {0: , 1: , 2: , 3: , 4: , 5: , 6: , 7: , 8: , 9: , 10: , 11: , 12: , 13: , 15: , 16: , 246: , 249: , 250: , 251: , 252: , 253: , 254: }, 'FavoriteQueries': , 'FileHistory': , 'HasFocus': , 'HighlightMatchingBracketProcessor': , 'IsDone': at 0x7f26ad7b0310>, 'MyCli': , 'MyCliLexer': , 'NO_QUERY': 0, 'OperationalError': , 'PACKAGE_ROOT': '/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli', 'PromptSession': , 'PygmentsLexer': , 'Query': , 'SQLCompleter': , 'SQLExecute': , 'TabularOutputFormatter': , 'WIN': False, '__builtins__': {'ArithmeticError': , 'AssertionError': , 'AttributeError': , 'BaseException': , 'BlockingIOError': , 'BrokenPipeError': , 'BufferError': , 'BytesWarning': , 'ChildProcessError': , 'ConnectionAbortedError': , 'ConnectionError': , 'ConnectionRefusedError': , 'ConnectionResetError': , 'DeprecationWarning': , 'EOFError': , 'Ellipsis': Ellipsis, 'EnvironmentError': , 'Exception': , 'False': False, 'FileExistsError': , 'FileNotFoundError': , 'FloatingPointError': , 'FutureWarning': , 'GeneratorExit': , 'IOError': , 'ImportError': , 'ImportWarning': , 'IndentationError': , 'IndexError': , 'InterruptedError': , 'IsADirectoryError': , 'KeyError': , 'KeyboardInterrupt': , 'LookupError': , 'MemoryError': , 'ModuleNotFoundError': , 'NameError': , 'None': None, 'NotADirectoryError': , 'NotImplemented': NotImplemented, 'NotImplementedError': , 'OSError': , 'OverflowError': , 'PendingDeprecationWarning': , 'PermissionError': , 'ProcessLookupError': , 'RecursionError': , 'ReferenceError': , 'ResourceWarning': , 'RuntimeError': , 'RuntimeWarning': , 'StopAsyncIteration': , 'StopIteration': , 'SyntaxError': , 'SyntaxWarning': , 'SystemError': , 'SystemExit': , 'TabError': , 'TimeoutError': , 'True': True, 'TypeError': , 'UnboundLocalError': , 'UnicodeDecodeError': , 'UnicodeEncodeError': , 'UnicodeError': , 'UnicodeTranslateError': , 'UnicodeWarning': , 'UserWarning': , 'ValueError': , 'Warning': , 'ZeroDivisionError': , '__build_class__': , '__debug__': True, '__doc__': 'Built-in functions, exceptions, and other ' 'objects.\n' '\n' "Noteworthy: None is the `nil' object; Ellipsis " "represents `...' in slices.", '__import__': , '__loader__': , '__name__': 'builtins', '__package__': '', '__spec__': ModuleSpec(name='builtins', loader=), 'abs': , 'all': , 'any': , 'ascii': , 'bin': , 'bool': , 'breakpoint': , 'bytearray': , 'bytes': , 'callable': , 'chr': , 'classmethod': , 'compile': , 'complex': , 'copyright': Copyright (c) 2001-2021 Python Software Foundation. All Rights Reserved. Copyright (c) 2000 BeOpen.com. All Rights Reserved. Copyright (c) 1995-2001 Corporation for National Research Initiatives. All Rights Reserved. Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam. All Rights Reserved., 'credits': Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands for supporting Python development. See www.python.org for more information., 'delattr': , 'dict': , 'dir': , 'divmod': , 'enumerate': , 'eval': , 'exec': , 'exit': Use exit() or Ctrl-D (i.e. EOF) to exit, 'filter': , 'float': , 'format': , 'frozenset': , 'getattr': , 'globals': , 'hasattr': , 'hash': , 'help': Type help() for interactive help, or help(object) for help about object., 'hex': , 'id': , 'input': , 'int': , 'isinstance': , 'issubclass': , 'iter': , 'len': , 'license': Type license() to see the full license text, 'list': , 'locals': , 'map': , 'max': , 'memoryview': , 'min': , 'next': , 'object': , 'oct': , 'open': , 'ord': , 'pow': , 'print': , 'property': , 'quit': Use quit() or Ctrl-D (i.e. EOF) to exit, 'range': , 'repr': , 'reversed': , 'round': , 'set': , 'setattr': , 'slice': , 'sorted': , 'staticmethod': , 'str': , 'sum': , 'super': , 'tuple': , 'type': , 'vars': , 'zip': }, '__cached__': '/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/__pycache__/main.cpython-38.pyc', '__doc__': None, '__file__': '/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/main.py', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f26adfaf640>, '__name__': 'mycli.main', '__package__': 'mycli', '__spec__': ModuleSpec(name='mycli.main', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7f26adfaf640>, origin='/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/main.py'), '__version__': '1.22.2', 'choice': >, 'cli': , 'cli_is_multiline': , 'click': , 'confirm': , 'confirm_destructive_query': , 'create_toolbar_tokens_func': , 'datetime': , 'dir_path_exists': , 'edit_and_execute': , 'fileinput': , 'get_mylogin_cnf_path': , 'getpwuid': , 'guess_socket_location': , 'is_dropping_database': , 'is_mutating': , 'is_select': , 'itertools': , 'logging': , 'mycli_bindings': , 'namedtuple': , 'need_completion_refresh': , 'need_completion_reset': , 'open': , 'open_mylogin_cnf': , 'os': , 'paramiko': , 'preprocessors': , 'prompt_register': , 're': , 'read_config_files': , 'read_ssh_config': , 'special': , 'sql_format': , 'sqlparse': , 'str_to_bool': , 'strip_ansi': , 'strip_matching_quotes': , 'style_factory': , 'style_factory_output': , 'sys': , 'thanks_picker': , 'threading': , 'time': , 'traceback': , 'unquote': , 'urlparse': , 'write_default_config': } module = name = 'mycli.main' obj = self = <_pytest.doctest.DoctestModule.collect..MockAwareDocTestFinder object at 0x7f26ad21d910> source_lines = ['import os\n', 'import sys\n', 'import traceback\n', 'import logging\n', 'import threading\n', 'import re\n', 'import fileinput\n', 'from collections import namedtuple\n', 'try:\n', ' from pwd import getpwuid\n', 'except ImportError:\n', ' pass\n', 'from time import time\n', 'from datetime import datetime\n', 'from random import choice\n', 'from io import open\n', '\n', 'from pymysql import OperationalError\n', 'from cli_helpers.tabular_output import TabularOutputFormatter\n', 'from cli_helpers.tabular_output import preprocessors\n', 'from cli_helpers.utils import strip_ansi\n', 'import click\n', 'import sqlparse\n', 'from mycli.packages.parseutils import is_dropping_database\n', 'from prompt_toolkit.completion import DynamicCompleter\n', 'from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode\n', 'from prompt_toolkit.key_binding.bindings.named_commands import register as ' 'prompt_register\n', 'from prompt_toolkit.shortcuts import PromptSession, CompleteStyle\n', 'from prompt_toolkit.document import Document\n', 'from prompt_toolkit.filters import HasFocus, IsDone\n', 'from prompt_toolkit.layout.processors import ' '(HighlightMatchingBracketProcessor,\n', ' ConditionalProcessor)\n', 'from prompt_toolkit.lexers import PygmentsLexer\n', 'from prompt_toolkit.history import FileHistory\n', 'from prompt_toolkit.auto_suggest import AutoSuggestFromHistory\n', '\n', 'from .packages.special.main import NO_QUERY\n', 'from .packages.prompt_utils import confirm, confirm_destructive_query\n', 'from .packages.tabular_output import sql_format\n', 'from .packages import special\n', 'from .packages.special.favoritequeries import FavoriteQueries\n', 'from .sqlcompleter import SQLCompleter\n', 'from .clitoolbar import create_toolbar_tokens_func\n', 'from .clistyle import style_factory, style_factory_output\n', 'from .sqlexecute import FIELD_TYPES, SQLExecute\n', 'from .clibuffer import cli_is_multiline\n', 'from .completion_refresher import CompletionRefresher\n', 'from .config import (write_default_config, get_mylogin_cnf_path,\n', ' open_mylogin_cnf, read_config_files, str_to_bool,\n', ' strip_matching_quotes)\n', 'from .key_bindings import mycli_bindings\n', 'from .lexer import MyCliLexer\n', 'from .__init__ import __version__\n', 'from .compat import WIN\n', 'from .packages.filepaths import dir_path_exists, guess_socket_location\n', '\n', 'import itertools\n', '\n', 'click.disable_unicode_literals_warning = True\n', '\n', 'try:\n', ' from urlparse import urlparse\n', ' from urlparse import unquote\n', 'except ImportError:\n', ' from urllib.parse import urlparse\n', ' from urllib.parse import unquote\n', '\n', '\n', 'try:\n', ' import paramiko\n', 'except ImportError:\n', ' from mycli.packages.paramiko_stub import paramiko\n', '\n', '# Query tuples are used for maintaining history\n', "Query = namedtuple('Query', ['query', 'successful', 'mutating'])\n", '\n', 'PACKAGE_ROOT = os.path.abspath(os.path.dirname(__file__))\n', '\n', '\n', 'class MyCli(object):\n', '\n', " default_prompt = '\\\\t \\\\u@\\\\h:\\\\d> '\n", ' max_len_prompt = 45\n', ' defaults_suffix = None\n', '\n', ' # In order of being loaded. Files lower in list override earlier ones.\n', ' cnf_files = [\n', " '/etc/my.cnf',\n", " '/etc/mysql/my.cnf',\n", " '/usr/local/etc/my.cnf',\n", " '~/.my.cnf'\n", ' ]\n', '\n', ' # check XDG_CONFIG_HOME exists and not an empty string\n', ' if os.environ.get("XDG_CONFIG_HOME"):\n', ' xdg_config_home = os.environ.get("XDG_CONFIG_HOME")\n', ' else:\n', ' xdg_config_home = "~/.config"\n', ' system_config_files = [\n', " '/etc/myclirc',\n", ' os.path.join(os.path.expanduser(xdg_config_home), "mycli", ' '"myclirc")\n', ' ]\n', '\n', " default_config_file = os.path.join(PACKAGE_ROOT, 'myclirc')\n", ' pwd_config_file = os.path.join(os.getcwd(), ".myclirc")\n', '\n', ' def __init__(self, sqlexecute=None, prompt=None,\n', ' logfile=None, defaults_suffix=None, defaults_file=None,\n', ' login_path=None, auto_vertical_output=False, warn=None,\n', ' myclirc="~/.myclirc"):\n', ' self.sqlexecute = sqlexecute\n', ' self.logfile = logfile\n', ' self.defaults_suffix = defaults_suffix\n', ' self.login_path = login_path\n', '\n', ' # self.cnf_files is a class variable that stores the list of mysql\n', ' # config files to read in at launch.\n', ' # If defaults_file is specified then override the class variable ' 'with\n', ' # defaults_file.\n', ' if defaults_file:\n', ' self.cnf_files = [defaults_file]\n', '\n', ' # Load config.\n', ' config_files = ([self.default_config_file] + ' 'self.system_config_files +\n', ' [myclirc] + [self.pwd_config_file])\n', ' c = self.config = read_config_files(config_files)\n', " self.multi_line = c['main'].as_bool('multi_line')\n", " self.key_bindings = c['main']['key_bindings']\n", " special.set_timing_enabled(c['main'].as_bool('timing'))\n", '\n', ' FavoriteQueries.instance = ' 'FavoriteQueries.from_config(self.config)\n', '\n', ' self.dsn_alias = None\n', ' self.formatter = TabularOutputFormatter(\n', " format_name=c['main']['table_format'])\n", ' sql_format.register_new_formatter(self.formatter)\n', ' self.formatter.mycli = self\n', " self.syntax_style = c['main']['syntax_style']\n", " self.less_chatty = c['main'].as_bool('less_chatty')\n", " self.cli_style = c['colors']\n", ' self.output_style = style_factory_output(\n', ' self.syntax_style,\n', ' self.cli_style\n', ' )\n', ' self.wider_completion_menu = ' "c['main'].as_bool('wider_completion_menu')\n", " c_dest_warning = c['main'].as_bool('destructive_warning')\n", ' self.destructive_warning = c_dest_warning if warn is None else ' 'warn\n', " self.login_path_as_host = c['main'].as_bool('login_path_as_host')\n", '\n', ' # read from cli argument or user config file\n', ' self.auto_vertical_output = auto_vertical_output or \\\n', " c['main'].as_bool('auto_vertical_output')\n", '\n', " # Write user config if system config wasn't the last config " 'loaded.\n', ' if c.filename not in self.system_config_files and not ' 'os.path.exists(myclirc):\n', ' write_default_config(self.default_config_file, myclirc)\n', '\n', ' # audit log\n', " if self.logfile is None and 'audit_log' in c['main']:\n", ' try:\n', ' self.logfile = ' "open(os.path.expanduser(c['main']['audit_log']), 'a')\n", ' except (IOError, OSError) as e:\n', " self.echo('Error: Unable to open the audit log file. Your " "queries will not be logged.',\n", " err=True, fg='red')\n", ' self.logfile = False\n', '\n', ' self.completion_refresher = CompletionRefresher()\n', '\n', ' self.logger = logging.getLogger(__name__)\n', ' self.initialize_logging()\n', '\n', ' prompt_cnf = self.read_my_cnf_files(self.cnf_files, ' "['prompt'])['prompt']\n", " self.prompt_format = prompt or prompt_cnf or c['main']['prompt'] or " '\\\n', ' self.default_prompt\n', ' self.multiline_continuation_char = ' "c['main']['prompt_continuation']\n", " keyword_casing = c['main'].get('keyword_casing', 'auto')\n", '\n', ' self.query_history = []\n', '\n', ' # Initialize completer.\n', " self.smart_completion = c['main'].as_bool('smart_completion')\n", ' self.completer = SQLCompleter(\n', ' self.smart_completion,\n', ' supported_formats=self.formatter.supported_formats,\n', ' keyword_casing=keyword_casing)\n', ' self._completer_lock = threading.Lock()\n', '\n', ' # Register custom special commands.\n', ' self.register_special_commands()\n', '\n', ' # Load .mylogin.cnf if it exists.\n', ' mylogin_cnf_path = get_mylogin_cnf_path()\n', ' if mylogin_cnf_path:\n', ' mylogin_cnf = open_mylogin_cnf(mylogin_cnf_path)\n', ' if mylogin_cnf_path and mylogin_cnf:\n', ' # .mylogin.cnf gets read last, even if defaults_file is ' 'specified.\n', ' self.cnf_files.append(mylogin_cnf)\n', ' elif mylogin_cnf_path and not mylogin_cnf:\n', ' # There was an error reading the login path file.\n', " print('Error: Unable to read login path file.')\n", '\n', ' self.prompt_app = None\n', '\n', ' def register_special_commands(self):\n', " special.register_special_command(self.change_db, 'use',\n", " '\\\\u', 'Change to a new database.', aliases=('\\\\u',))\n", " special.register_special_command(self.change_db, 'connect',\n", " '\\\\r', 'Reconnect to the database. Optional database " "argument.',\n", " aliases=('\\\\r', ), case_sensitive=True)\n", ' special.register_special_command(self.refresh_completions, ' "'rehash',\n", " '\\\\#', 'Refresh auto-completions.', arg_type=NO_QUERY, " "aliases=('\\\\#',))\n", ' special.register_special_command(\n', " self.change_table_format, 'tableformat', '\\\\T',\n", " 'Change the table format used to output results.',\n", " aliases=('\\\\T',), case_sensitive=True)\n", " special.register_special_command(self.execute_from_file, 'source', " "'\\\\. filename',\n", " 'Execute commands from file.', " "aliases=('\\\\.',))\n", ' special.register_special_command(self.change_prompt_format, ' "'prompt',\n", " '\\\\R', 'Change prompt format.', aliases=('\\\\R',), " 'case_sensitive=True)\n', '\n', ' def change_table_format(self, arg, **_):\n', ' try:\n', ' self.formatter.format_name = arg\n', ' yield (None, None, None,\n', " 'Changed table format to {}'.format(arg))\n", ' except ValueError:\n', " msg = 'Table format {} not recognized. Allowed " "formats:'.format(\n", ' arg)\n', ' for table_type in self.formatter.supported_formats:\n', ' msg += "\\n\\t{}".format(table_type)\n', ' yield (None, None, None, msg)\n', '\n', ' def change_db(self, arg, **_):\n', ' if not arg:\n', ' click.secho(\n', ' "No database selected",\n', ' err=True, fg="red"\n', ' )\n', ' return\n', '\n', ' self.sqlexecute.change_db(arg)\n', '\n', ' yield (None, None, None, \'You are now connected to database "%s" as ' "'\n", ' \'user "%s"\' % (self.sqlexecute.dbname, ' 'self.sqlexecute.user))\n', '\n', ' def execute_from_file(self, arg, **_):\n', ' if not arg:\n', " message = 'Missing required argument, filename.'\n", ' return [(None, None, None, message)]\n', ' try:\n', ' with open(os.path.expanduser(arg)) as f:\n', ' query = f.read()\n', ' except IOError as e:\n', ' return [(None, None, None, str(e))]\n', '\n', ' if (self.destructive_warning and\n', ' confirm_destructive_query(query) is False):\n', " message = 'Wise choice. Command execution stopped.'\n", ' return [(None, None, None, message)]\n', '\n', ' return self.sqlexecute.run(query)\n', '\n', ' def change_prompt_format(self, arg, **_):\n', ' """\n', ' Change the prompt format.\n', ' """\n', ' if not arg:\n', " message = 'Missing required argument, format.'\n", ' return [(None, None, None, message)]\n', '\n', ' self.prompt_format = self.get_prompt(arg)\n', ' return [(None, None, None, "Changed prompt format to %s" % arg)]\n', '\n', ' def initialize_logging(self):\n', '\n', " log_file = os.path.expanduser(self.config['main']['log_file'])\n", " log_level = self.config['main']['log_level']\n", '\n', " level_map = {'CRITICAL': logging.CRITICAL,\n", " 'ERROR': logging.ERROR,\n", " 'WARNING': logging.WARNING,\n", " 'INFO': logging.INFO,\n", " 'DEBUG': logging.DEBUG\n", ' }\n', '\n', ' # Disable logging if value is NONE by switching to a no-op handler\n', " # Set log level to a high value so it doesn't even waste cycles " 'getting called.\n', ' if log_level.upper() == "NONE":\n', ' handler = logging.NullHandler()\n', ' log_level = "CRITICAL"\n', ' elif dir_path_exists(log_file):\n', ' handler = logging.FileHandler(log_file)\n', ' else:\n', ' self.echo(\n', " 'Error: Unable to open the log file " '"{}".\'.format(log_file),\n', " err=True, fg='red')\n", ' return\n', '\n', ' formatter = logging.Formatter(\n', " '%(asctime)s (%(process)d/%(threadName)s) '\n", " '%(name)s %(levelname)s - %(message)s')\n", '\n', ' handler.setFormatter(formatter)\n', '\n', " root_logger = logging.getLogger('mycli')\n", ' root_logger.addHandler(handler)\n', ' root_logger.setLevel(level_map[log_level.upper()])\n', '\n', ' logging.captureWarnings(True)\n', '\n', " root_logger.debug('Initializing mycli logging.')\n", " root_logger.debug('Log file %r.', log_file)\n", '\n', '\n', ' def read_my_cnf_files(self, files, keys):\n', ' """\n', ' Reads a list of config files and merges them. The last one will ' 'win.\n', ' :param files: list of files to read\n', ' :param keys: list of keys to retrieve\n', ' :returns: tuple, with None for missing keys.\n', ' """\n', ' cnf = read_config_files(files, list_values=False)\n', '\n', " sections = ['client', 'mysqld']\n", " if self.login_path and self.login_path != 'client':\n", ' sections.append(self.login_path)\n', '\n', ' if self.defaults_suffix:\n', ' sections.extend([sect + self.defaults_suffix for sect in ' 'sections])\n', '\n', ' def get(key):\n', ' result = None\n', ' for sect in cnf:\n', ' if sect in sections and key in cnf[sect]:\n', ' result = strip_matching_quotes(cnf[sect][key])\n', ' return result\n', '\n', ' return {x: get(x) for x in keys}\n', '\n', ' def merge_ssl_with_cnf(self, ssl, cnf):\n', ' """Merge SSL configuration dict with cnf dict"""\n', '\n', ' merged = {}\n', ' merged.update(ssl)\n', " prefix = 'ssl-'\n", ' for k, v in cnf.items():\n', ' # skip unrelated options\n', ' if not k.startswith(prefix):\n', ' continue\n', ' if v is None:\n', ' continue\n', ' # special case because PyMySQL argument is significantly ' 'different\n', ' # from commandline\n', " if k == 'ssl-verify-server-cert':\n", " merged['check_hostname'] = v\n", ' else:\n', ' # use argument name just strip "ssl-" prefix\n', ' arg = k[len(prefix):]\n', ' merged[arg] = v\n', '\n', ' return merged\n', '\n', " def connect(self, database='', user='', passwd='', host='', port='',\n", " socket='', charset='', local_infile='', ssl='',\n", " ssh_user='', ssh_host='', ssh_port='',\n", " ssh_password='', ssh_key_filename='', init_command=''):\n", '\n', " cnf = {'database': None,\n", " 'user': None,\n", " 'password': None,\n", " 'host': None,\n", " 'port': None,\n", " 'socket': None,\n", " 'default-character-set': None,\n", " 'local-infile': None,\n", " 'loose-local-infile': None,\n", " 'ssl-ca': None,\n", " 'ssl-cert': None,\n", " 'ssl-key': None,\n", " 'ssl-cipher': None,\n", " 'ssl-verify-serer-cert': None,\n", ' }\n', '\n', ' cnf = self.read_my_cnf_files(self.cnf_files, cnf.keys())\n', '\n', ' # Fall back to config values only if user did not specify a value.\n', '\n', " database = database or cnf['database']\n", ' # Socket interface not supported for SSH connections\n', ' if port or host or ssh_host or ssh_port:\n', " socket = ''\n", ' else:\n', " socket = socket or cnf['socket'] or guess_socket_location()\n", " user = user or cnf['user'] or os.getenv('USER')\n", " host = host or cnf['host']\n", " port = port or cnf['port']\n", ' ssl = ssl or {}\n', '\n', " passwd = passwd if isinstance(passwd, str) else cnf['password']\n", " charset = charset or cnf['default-character-set'] or 'utf8'\n", '\n', ' # Favor whichever local_infile option is set.\n', " for local_infile_option in (local_infile, cnf['local-infile'],\n", " cnf['loose-local-infile'], False):\n", ' try:\n', ' local_infile = str_to_bool(local_infile_option)\n', ' break\n', ' except (TypeError, ValueError):\n', ' pass\n', '\n', ' ssl = self.merge_ssl_with_cnf(ssl, cnf)\n', ' # prune lone check_hostname=False\n', ' if not any(v for v in ssl.values()):\n', ' ssl = None\n', '\n', ' # Connect to the database.\n', '\n', ' def _connect():\n', ' try:\n', ' self.sqlexecute = SQLExecute(\n', ' database, user, passwd, host, port, socket, charset,\n', ' local_infile, ssl, ssh_user, ssh_host, ssh_port,\n', ' ssh_password, ssh_key_filename, init_command\n', ' )\n', ' except OperationalError as e:\n', " if ('Access denied for user' in e.args[1]):\n", " new_passwd = click.prompt('Password', hide_input=True,\n", ' show_default=False, type=str, ' 'err=True)\n', ' self.sqlexecute = SQLExecute(\n', ' database, user, new_passwd, host, port, socket,\n', ' charset, local_infile, ssl, ssh_user, ssh_host,\n', ' ssh_port, ssh_password, ssh_key_filename, ' 'init_command\n', ' )\n', ' else:\n', ' raise e\n', '\n', ' try:\n', ' if not WIN and socket:\n', ' socket_owner = getpwuid(os.stat(socket).st_uid).pw_name\n', ' self.echo(\n', ' f"Connecting to socket {socket}, owned by user ' '{socket_owner}")\n', ' try:\n', ' _connect()\n', ' except OperationalError as e:\n', ' # These are "Can\'t open socket" and 2x "Can\'t ' 'connect"\n', ' if [code for code in (2001, 2002, 2003) if code == ' 'e.args[0]]:\n', " self.logger.debug('Database connection failed: %r.', " 'e)\n', ' self.logger.error(\n', ' "traceback: %r", traceback.format_exc())\n', " self.logger.debug('Retrying over TCP/IP')\n", ' self.echo(\n', ' "Failed to connect to local MySQL server through ' 'socket \'{}\':".format(socket))\n', ' self.echo(str(e), err=True)\n', ' self.echo(\n', " 'Retrying over TCP/IP', err=True)\n", '\n', ' # Else fall back to TCP/IP localhost\n', ' socket = ""\n', " host = 'localhost'\n", ' port = 3306\n', ' _connect()\n', ' else:\n', ' raise e\n', ' else:\n', " host = host or 'localhost'\n", ' port = port or 3306\n', '\n', ' # Bad ports give particularly daft error messages\n', ' try:\n', ' port = int(port)\n', ' except ValueError as e:\n', ' self.echo("Error: Invalid port number: ' '\'{0}\'.".format(port),\n', " err=True, fg='red')\n", ' exit(1)\n', '\n', ' _connect()\n', ' except Exception as e: # Connecting to a database could fail.\n', " self.logger.debug('Database connection failed: %r.', e)\n", ' self.logger.error("traceback: %r", traceback.format_exc())\n', " self.echo(str(e), err=True, fg='red')\n", ' exit(1)\n', '\n', ' def handle_editor_command(self, text):\n', ' """Editor command is any query that is prefixed or suffixed by a ' "'\\e'.\n", ' The reason for a while loop is because a user might edit a query\n', ' multiple times. For eg:\n', '\n', ' "select * from \\e" to edit it in vim, then come\n', ' back to the prompt with the edited query "select * from\n', ' blah where q = \'abc\'\\e" to edit it again.\n', ' :param text: Document\n', ' :return: Document\n', '\n', ' """\n', '\n', ' while special.editor_command(text):\n', ' filename = special.get_filename(text)\n', ' query = (special.get_editor_query(text) or\n', ' self.get_last_query())\n', ' sql, message = special.open_external_editor(filename, ' 'sql=query)\n', ' if message:\n', ' # Something went wrong. Raise an exception and bail.\n', ' raise RuntimeError(message)\n', ' while True:\n', ' try:\n', ' text = self.prompt_app.prompt(default=sql)\n', ' break\n', ' except KeyboardInterrupt:\n', ' sql = ""\n', '\n', ' continue\n', ' return text\n', '\n', ' def run_cli(self):\n', ' iterations = 0\n', ' sqlexecute = self.sqlexecute\n', ' logger = self.logger\n', ' self.configure_pager()\n', '\n', ' if self.smart_completion:\n', ' self.refresh_completions()\n', '\n', " author_file = os.path.join(PACKAGE_ROOT, 'AUTHORS')\n", " sponsor_file = os.path.join(PACKAGE_ROOT, 'SPONSORS')\n", '\n', ' history_file = os.path.expanduser(\n', " os.environ.get('MYCLI_HISTFILE', '~/.mycli-history'))\n", ' if dir_path_exists(history_file):\n', ' history = FileHistory(history_file)\n', ' else:\n', ' history = None\n', ' self.echo(\n', ' \'Error: Unable to open the history file "{}". \'\n', " 'Your query history will not be " "saved.'.format(history_file),\n", " err=True, fg='red')\n", '\n', ' key_bindings = mycli_bindings(self)\n', '\n', ' if not self.less_chatty:\n', " print(' '.join(sqlexecute.server_type()))\n", " print('mycli', __version__)\n", " print('Chat: https://gitter.im/dbcli/mycli')\n", " print('Mail: " "https://groups.google.com/forum/#!forum/mycli-users')\n", " print('Home: http://mycli.net')\n", " print('Thanks to the contributor -', thanks_picker([author_file, " 'sponsor_file]))\n', '\n', ' def get_message():\n', ' prompt = self.get_prompt(self.prompt_format)\n', ' if self.prompt_format == self.default_prompt and len(prompt) > ' 'self.max_len_prompt:\n', " prompt = self.get_prompt('\\\\d> ')\n", " return [('class:prompt', prompt)]\n", '\n', ' def get_continuation(width, *_):\n', ' if self.multiline_continuation_char:\n', ' left_padding = width - ' 'len(self.multiline_continuation_char)\n', ' continuation = " " * \\\n', ' max((left_padding - 1), 0) + \\\n', ' self.multiline_continuation_char + " "\n', ' else:\n', ' continuation = " "\n', " return [('class:continuation', continuation)]\n", '\n', ' def show_suggestion_tip():\n', ' return iterations < 2\n', '\n', ' def one_iteration(text=None):\n', ' if text is None:\n', ' try:\n', ' text = self.prompt_app.prompt()\n', ' except KeyboardInterrupt:\n', ' return\n', '\n', ' special.set_expanded_output(False)\n', '\n', ' try:\n', ' text = self.handle_editor_command(text)\n', ' except RuntimeError as e:\n', ' logger.error("sql: %r, error: %r", text, e)\n', ' logger.error("traceback: %r", traceback.format_exc())\n', " self.echo(str(e), err=True, fg='red')\n", ' return\n', '\n', ' if not text.strip():\n', ' return\n', '\n', ' if self.destructive_warning:\n', ' destroy = confirm_destructive_query(text)\n', ' if destroy is None:\n', ' pass # Query was not destructive. Nothing to do here.\n', ' elif destroy is True:\n', " self.echo('Your call!')\n", ' else:\n', " self.echo('Wise choice!')\n", ' return\n', ' else:\n', ' destroy = True\n', '\n', ' # Keep track of whether or not the query is mutating. In case\n', ' # of a multi-statement query, the overall query is considered\n', ' # mutating if any one of the component statements is mutating\n', ' mutating = False\n', '\n', ' try:\n', " logger.debug('sql: %r', text)\n", '\n', ' special.write_tee(self.get_prompt(self.prompt_format) + ' 'text)\n', ' if self.logfile:\n', " self.logfile.write('\\n# %s\\n' % datetime.now())\n", ' self.logfile.write(text)\n', " self.logfile.write('\\n')\n", '\n', ' successful = False\n', ' start = time()\n', ' res = sqlexecute.run(text)\n', ' self.formatter.query = text\n', ' successful = True\n', ' result_count = 0\n', ' for title, cur, headers, status in res:\n', ' logger.debug("headers: %r", headers)\n', ' logger.debug("rows: %r", cur)\n', ' logger.debug("status: %r", status)\n', ' threshold = 1000\n', ' if (is_select(status) and\n', ' cur and cur.rowcount > threshold):\n', " self.echo('The result set has more than {} " "rows.'.format(\n", " threshold), fg='red')\n", " if not confirm('Do you want to continue?'):\n", ' self.echo("Aborted!", err=True, fg=\'red\')\n', ' break\n', '\n', ' if self.auto_vertical_output:\n', ' max_width = ' 'self.prompt_app.output.get_size().columns\n', ' else:\n', ' max_width = None\n', '\n', ' formatted = self.format_output(\n', ' title, cur, headers, special.is_expanded_output(),\n', ' max_width)\n', '\n', ' t = time() - start\n', ' try:\n', ' if result_count > 0:\n', " self.echo('')\n", ' try:\n', ' self.output(formatted, status)\n', ' except KeyboardInterrupt:\n', ' pass\n', ' if special.is_timing_enabled():\n', " self.echo('Time: %0.03fs' % t)\n", ' except KeyboardInterrupt:\n', ' pass\n', '\n', ' start = time()\n', ' result_count += 1\n', ' mutating = mutating or destroy or is_mutating(status)\n', ' special.unset_once_if_written()\n', ' except EOFError as e:\n', ' raise e\n', ' except KeyboardInterrupt:\n', ' # get last connection id\n', ' connection_id_to_kill = sqlexecute.connection_id\n', ' logger.debug("connection id to kill: %r", ' 'connection_id_to_kill)\n', ' # Restart connection to the database\n', ' sqlexecute.connect()\n', ' try:\n', " for title, cur, headers, status in sqlexecute.run('kill " "%s' % connection_id_to_kill):\n", ' status_str = str(status).lower()\n', " if status_str.find('ok') > -1:\n", ' logger.debug("cancelled query, connection id: ' '%r, sql: %r",\n', ' connection_id_to_kill, text)\n', ' self.echo("cancelled query", err=True, ' "fg='red')\n", ' except Exception as e:\n', " self.echo('Encountered error while cancelling query: " "{}'.format(e),\n", " err=True, fg='red')\n", ' except NotImplementedError:\n', ' self.echo(\'Not Yet Implemented.\', fg="yellow")\n', ' except OperationalError as e:\n', ' logger.debug("Exception: %r", e)\n', ' if (e.args[0] in (2003, 2006, 2013)):\n', " logger.debug('Attempting to reconnect.')\n", " self.echo('Reconnecting...', fg='yellow')\n", ' try:\n', ' sqlexecute.connect()\n', " logger.debug('Reconnected successfully.')\n", ' one_iteration(text)\n', ' return # OK to just return, cuz the recursion call ' 'runs to the end.\n', ' except OperationalError as e:\n', " logger.debug('Reconnect failed. e: %r', e)\n", " self.echo(str(e), err=True, fg='red')\n", " # If reconnection failed, don't proceed further.\n", ' return\n', ' else:\n', ' logger.error("sql: %r, error: %r", text, e)\n', ' logger.error("traceback: %r", traceback.format_exc())\n', " self.echo(str(e), err=True, fg='red')\n", ' except Exception as e:\n', ' logger.error("sql: %r, error: %r", text, e)\n', ' logger.error("traceback: %r", traceback.format_exc())\n', " self.echo(str(e), err=True, fg='red')\n", ' else:\n', ' if is_dropping_database(text, self.sqlexecute.dbname):\n', ' self.sqlexecute.dbname = None\n', ' self.sqlexecute.connect()\n', '\n', ' # Refresh the table names and column names if necessary.\n', ' if need_completion_refresh(text):\n', ' self.refresh_completions(\n', ' reset=need_completion_reset(text))\n', ' finally:\n', ' if self.logfile is False:\n', ' self.echo("Warning: This query was not logged.",\n', " err=True, fg='red')\n", ' query = Query(text, successful, mutating)\n', ' self.query_history.append(query)\n', '\n', ' get_toolbar_tokens = create_toolbar_tokens_func(\n', ' self, show_suggestion_tip)\n', ' if self.wider_completion_menu:\n', ' complete_style = CompleteStyle.MULTI_COLUMN\n', ' else:\n', ' complete_style = CompleteStyle.COLUMN\n', '\n', ' with self._completer_lock:\n', '\n', " if self.key_bindings == 'vi':\n", ' editing_mode = EditingMode.VI\n', ' else:\n', ' editing_mode = EditingMode.EMACS\n', '\n', ' self.prompt_app = PromptSession(\n', ' lexer=PygmentsLexer(MyCliLexer),\n', ' reserve_space_for_menu=self.get_reserved_space(),\n', ' message=get_message,\n', ' prompt_continuation=get_continuation,\n', ' bottom_toolbar=get_toolbar_tokens,\n', ' complete_style=complete_style,\n', ' input_processors=[ConditionalProcessor(\n', ' processor=HighlightMatchingBracketProcessor(\n', " chars='[](){}'),\n", ' filter=HasFocus(DEFAULT_BUFFER) & ~IsDone()\n', ' )],\n', " tempfile_suffix='.sql',\n", ' completer=DynamicCompleter(lambda: self.completer),\n', ' history=history,\n', ' auto_suggest=AutoSuggestFromHistory(),\n', ' complete_while_typing=True,\n', ' multiline=cli_is_multiline(self),\n', ' style=style_factory(self.syntax_style, self.cli_style),\n', ' include_default_pygments_style=False,\n', ' key_bindings=key_bindings,\n', ' enable_open_in_editor=True,\n', ' enable_system_prompt=True,\n', ' enable_suspend=True,\n', ' editing_mode=editing_mode,\n', ' search_ignore_case=True\n', ' )\n', '\n', ' try:\n', ' while True:\n', ' one_iteration()\n', ' iterations += 1\n', ' except EOFError:\n', ' special.close_tee()\n', ' if not self.less_chatty:\n', " self.echo('Goodbye!')\n", '\n', ' def log_output(self, output):\n', ' """Log the output in the audit log, if it\'s enabled."""\n', ' if self.logfile:\n', ' click.echo(output, file=self.logfile)\n', '\n', ' def echo(self, s, **kwargs):\n', ' """Print a message to stdout.\n', '\n', ' The message will be logged in the audit log, if enabled.\n', '\n', ' All keyword arguments are passed to click.echo().\n', '\n', ' """\n', ' self.log_output(s)\n', ' click.secho(s, **kwargs)\n', '\n', ' def get_output_margin(self, status=None):\n', ' """Get the output margin (number of rows for the prompt, footer ' 'and\n', ' timing message."""\n', ' margin = self.get_reserved_space() + ' "self.get_prompt(self.prompt_format).count('\\n') + 1\n", ' if special.is_timing_enabled():\n', ' margin += 1\n', ' if status:\n', " margin += 1 + status.count('\\n')\n", '\n', ' return margin\n', '\n', '\n', ' def output(self, output, status=None):\n', ' """Output text to stdout or a pager command.\n', '\n', ' The status text is not outputted to pager or files.\n', '\n', ' The message will be logged in the audit log, if enabled. The\n', ' message will be written to the tee file, if enabled. The\n', ' message will be written to the output file, if enabled.\n', '\n', ' """\n', ' if output:\n', ' size = self.prompt_app.output.get_size()\n', '\n', ' margin = self.get_output_margin(status)\n', '\n', ' fits = True\n', ' buf = []\n', ' output_via_pager = self.explicit_pager and ' 'special.is_pager_enabled()\n', ' for i, line in enumerate(output, 1):\n', ' self.log_output(line)\n', ' special.write_tee(line)\n', ' special.write_once(line)\n', '\n', ' if fits or output_via_pager:\n', ' # buffering\n', ' buf.append(line)\n', ' if len(line) > size.columns or i > (size.rows - ' 'margin):\n', ' fits = False\n', ' if not self.explicit_pager and ' 'special.is_pager_enabled():\n', " # doesn't fit, use pager\n", ' output_via_pager = True\n', '\n', ' if not output_via_pager:\n', " # doesn't fit, flush buffer\n", ' for line in buf:\n', ' click.secho(line)\n', ' buf = []\n', ' else:\n', ' click.secho(line)\n', '\n', ' if buf:\n', ' if output_via_pager:\n', ' def newlinewrapper(text):\n', ' for line in text:\n', ' yield line + "\\n"\n', ' click.echo_via_pager(newlinewrapper(buf))\n', ' else:\n', ' for line in buf:\n', ' click.secho(line)\n', '\n', ' if status:\n', ' self.log_output(status)\n', ' click.secho(status)\n', '\n', ' def configure_pager(self):\n', ' # Provide sane defaults for less if they are empty.\n', " if not os.environ.get('LESS'):\n", " os.environ['LESS'] = '-RXF'\n", '\n', " cnf = self.read_my_cnf_files(self.cnf_files, ['pager', " "'skip-pager'])\n", " if cnf['pager']:\n", " special.set_pager(cnf['pager'])\n", ' self.explicit_pager = True\n', ' else:\n', ' self.explicit_pager = False\n', '\n', " if cnf['skip-pager'] or not " "self.config['main'].as_bool('enable_pager'):\n", ' special.disable_pager()\n', '\n', ' def refresh_completions(self, reset=False):\n', ' if reset:\n', ' with self._completer_lock:\n', ' self.completer.reset_completions()\n', ' self.completion_refresher.refresh(\n', ' self.sqlexecute, self._on_completions_refreshed,\n', " {'smart_completion': self.smart_completion,\n", " 'supported_formats': self.formatter.supported_formats,\n", " 'keyword_casing': self.completer.keyword_casing})\n", '\n', ' return [(None, None, None,\n', " 'Auto-completion refresh started in the background.')]\n", '\n', ' def _on_completions_refreshed(self, new_completer):\n', ' """Swap the completer object in cli with the newly created ' 'completer.\n', ' """\n', ' with self._completer_lock:\n', ' self.completer = new_completer\n', '\n', ' if self.prompt_app:\n', ' # After refreshing, redraw the CLI to clear the statusbar\n', ' # "Refreshing completions..." indicator\n', ' self.prompt_app.app.invalidate()\n', '\n', ' def get_completions(self, text, cursor_positition):\n', ' with self._completer_lock:\n', ' return self.completer.get_completions(\n', ' Document(text=text, cursor_position=cursor_positition), ' 'None)\n', '\n', ' def get_prompt(self, string):\n', ' sqlexecute = self.sqlexecute\n', ' host = self.login_path if self.login_path and ' 'self.login_path_as_host else sqlexecute.host\n', ' now = datetime.now()\n', " string = string.replace('\\\\u', sqlexecute.user or '(none)')\n", " string = string.replace('\\\\h', host or '(none)')\n", " string = string.replace('\\\\d', sqlexecute.dbname or '(none)')\n", " string = string.replace('\\\\t', sqlexecute.server_type()[0] or " "'mycli')\n", ' string = string.replace(\'\\\\n\', "\\n")\n', " string = string.replace('\\\\D', now.strftime('%a %b %d %H:%M:%S " "%Y'))\n", " string = string.replace('\\\\m', now.strftime('%M'))\n", " string = string.replace('\\\\P', now.strftime('%p'))\n", " string = string.replace('\\\\R', now.strftime('%H'))\n", " string = string.replace('\\\\r', now.strftime('%I'))\n", " string = string.replace('\\\\s', now.strftime('%S'))\n", " string = string.replace('\\\\p', str(sqlexecute.port))\n", " string = string.replace('\\\\A', self.dsn_alias or '(none)')\n", " string = string.replace('\\\\_', ' ')\n", ' return string\n', '\n', ' def run_query(self, query, new_line=True):\n', ' """Runs *query*."""\n', ' results = self.sqlexecute.run(query)\n', ' for result in results:\n', ' title, cur, headers, status = result\n', ' self.formatter.query = query\n', ' output = self.format_output(title, cur, headers)\n', ' for line in output:\n', ' click.echo(line, nl=new_line)\n', '\n', ' def format_output(self, title, cur, headers, expanded=False,\n', ' max_width=None):\n', " expanded = expanded or self.formatter.format_name == 'vertical'\n", ' output = []\n', '\n', ' output_kwargs = {\n', " 'dialect': 'unix',\n", " 'disable_numparse': True,\n", " 'preserve_whitespace': True,\n", " 'style': self.output_style\n", ' }\n', '\n', ' if not self.formatter.format_name in sql_format.supported_formats:\n', ' output_kwargs["preprocessors"] = (preprocessors.align_decimals, ' ')\n', '\n', " if title: # Only print the title if it's not None.\n", ' output = itertools.chain(output, [title])\n', '\n', ' if cur:\n', ' column_types = None\n', " if hasattr(cur, 'description'):\n", ' def get_col_type(col):\n', ' col_type = FIELD_TYPES.get(col[1], str)\n', ' return col_type if type(col_type) is type else str\n', ' column_types = [get_col_type(col) for col in ' 'cur.description]\n', '\n', ' if max_width is not None:\n', ' cur = list(cur)\n', '\n', ' formatted = self.formatter.format_output(\n', " cur, headers, format_name='vertical' if expanded else " 'None,\n', ' column_types=column_types,\n', ' **output_kwargs)\n', '\n', ' if isinstance(formatted, str):\n', ' formatted = formatted.splitlines()\n', ' formatted = iter(formatted)\n', '\n', ' if (not expanded and max_width and headers and cur):\n', ' first_line = next(formatted)\n', ' if len(strip_ansi(first_line)) > max_width:\n', ' formatted = self.formatter.format_output(\n', " cur, headers, format_name='vertical', " 'column_types=column_types, **output_kwargs)\n', ' if isinstance(formatted, str):\n', ' formatted = iter(formatted.splitlines())\n', ' else:\n', ' formatted = itertools.chain([first_line], formatted)\n', '\n', ' output = itertools.chain(output, formatted)\n', '\n', '\n', ' return output\n', '\n', ' def get_reserved_space(self):\n', ' """Get the number of lines to reserve for the completion menu."""\n', ' reserved_space_ratio = .45\n', ' max_reserved_space = 8\n', ' _, height = click.get_terminal_size()\n', ' return min(int(round(height * reserved_space_ratio)), ' 'max_reserved_space)\n', '\n', ' def get_last_query(self):\n', ' """Get the last query executed or None."""\n', ' return self.query_history[-1][0] if self.query_history else None\n', '\n', '\n', '@click.command()\n', "@click.option('-h', '--host', envvar='MYSQL_HOST', help='Host address of the " "database.')\n", "@click.option('-P', '--port', envvar='MYSQL_TCP_PORT', type=int, help='Port " "number to use for connection. Honors '\n", " '$MYSQL_TCP_PORT.')\n", "@click.option('-u', '--user', help='User name to connect to the " "database.')\n", "@click.option('-S', '--socket', envvar='MYSQL_UNIX_PORT', help='The socket " "file to use for connection.')\n", "@click.option('-p', '--password', 'password', envvar='MYSQL_PWD', " 'type=str,\n', " help='Password to connect to the database.')\n", "@click.option('--pass', 'password', envvar='MYSQL_PWD', type=str,\n", " help='Password to connect to the database.')\n", "@click.option('--ssh-user', help='User name to connect to ssh server.')\n", "@click.option('--ssh-host', help='Host name to connect to ssh server.')\n", "@click.option('--ssh-port', default=22, help='Port to connect to ssh " "server.')\n", "@click.option('--ssh-password', help='Password to connect to ssh server.')\n", "@click.option('--ssh-key-filename', help='Private key filename (identify " "file) for the ssh connection.')\n", "@click.option('--ssh-config-path', help='Path to ssh configuration.',\n", " default=os.path.expanduser('~') + '/.ssh/config')\n", "@click.option('--ssh-config-host', help='Host to connect to ssh server " "reading from ssh configuration.')\n", "@click.option('--ssl-ca', help='CA file in PEM format.',\n", ' type=click.Path(exists=True))\n', "@click.option('--ssl-capath', help='CA directory.')\n", "@click.option('--ssl-cert', help='X509 cert in PEM format.',\n", ' type=click.Path(exists=True))\n', "@click.option('--ssl-key', help='X509 key in PEM format.',\n", ' type=click.Path(exists=True))\n', "@click.option('--ssl-cipher', help='SSL cipher to use.')\n", "@click.option('--ssl-verify-server-cert', is_flag=True,\n", ' help=(\'Verify server\\\'s "Common Name" in its cert against ' "'\n", " 'hostname used when connecting. This option is disabled " "'\n", " 'by default.'))\n", '# as of 2016-02-15 revocation list is not supported by underling PyMySQL\n', '# library (--ssl-crl and --ssl-crlpath options in vanilla mysql client)\n', "@click.option('-V', '--version', is_flag=True, help='Output mycli\\'s " "version.')\n", "@click.option('-v', '--verbose', is_flag=True, help='Verbose output.')\n", "@click.option('-D', '--database', 'dbname', help='Database to use.')\n", "@click.option('-d', '--dsn', default='', envvar='DSN',\n", " help='Use DSN configured into the [alias_dsn] section of " "myclirc file.')\n", "@click.option('--list-dsn', 'list_dsn', is_flag=True,\n", " help='list of DSN configured into the [alias_dsn] section of myclirc " "file.')\n", "@click.option('--list-ssh-config', 'list_ssh_config', is_flag=True,\n", " help='list ssh configurations in the ssh config (requires " "paramiko).')\n", "@click.option('-R', '--prompt', 'prompt',\n", ' help=\'Prompt format (Default: "{0}").\'.format(\n', ' MyCli.default_prompt))\n', "@click.option('-l', '--logfile', type=click.File(mode='a', " "encoding='utf-8'),\n", " help='Log every query and its results to a file.')\n", "@click.option('--defaults-group-suffix', type=str,\n", " help='Read MySQL config groups with the specified suffix.')\n", "@click.option('--defaults-file', type=click.Path(),\n", " help='Only read MySQL options from the given file.')\n", '@click.option(\'--myclirc\', type=click.Path(), default="~/.myclirc",\n', " help='Location of myclirc file.')\n", "@click.option('--auto-vertical-output', is_flag=True,\n", " help='Automatically switch to vertical output mode if the " "result is wider than the terminal width.')\n", "@click.option('-t', '--table', is_flag=True,\n", " help='Display batch output in table format.')\n", "@click.option('--csv', is_flag=True,\n", " help='Display batch output in CSV format.')\n", "@click.option('--warn/--no-warn', default=None,\n", " help='Warn before running a destructive query.')\n", "@click.option('--local-infile', type=bool,\n", " help='Enable/disable LOAD DATA LOCAL INFILE.')\n", "@click.option('--login-path', type=str,\n", " help='Read this path from the login file.')\n", "@click.option('-e', '--execute', type=str,\n", " help='Execute command and quit.')\n", "@click.option('--init-command', type=str,\n", " help='SQL statement to execute after connecting.')\n", "@click.argument('database', default='', nargs=1)\n", 'def cli(database, user, host, port, socket, password, dbname,\n', ' version, verbose, prompt, logfile, defaults_group_suffix,\n', ' defaults_file, login_path, auto_vertical_output, local_infile,\n', ' ssl_ca, ssl_capath, ssl_cert, ssl_key, ssl_cipher,\n', ' ssl_verify_server_cert, table, csv, warn, execute, myclirc, dsn,\n', ' list_dsn, ssh_user, ssh_host, ssh_port, ssh_password,\n', ' ssh_key_filename, list_ssh_config, ssh_config_path, ' 'ssh_config_host,\n', ' init_command):\n', ' """A MySQL terminal client with auto-completion and syntax ' 'highlighting.\n', '\n', ' \\b\n', ' Examples:\n', ' - mycli my_database\n', ' - mycli -u my_user -h my_host.com my_database\n', ' - mycli mysql://my_user@my_host.com:3306/my_database\n', '\n', ' """\n', '\n', ' if version:\n', " print('Version:', __version__)\n", ' sys.exit(0)\n', '\n', ' mycli = MyCli(prompt=prompt, logfile=logfile,\n', ' defaults_suffix=defaults_group_suffix,\n', ' defaults_file=defaults_file, login_path=login_path,\n', ' auto_vertical_output=auto_vertical_output, warn=warn,\n', ' myclirc=myclirc)\n', ' if list_dsn:\n', ' try:\n', " alias_dsn = mycli.config['alias_dsn']\n", ' except KeyError as err:\n', " click.secho('Invalid DSNs found in the config file. '\\\n", ' \'Please check the "[alias_dsn]" section in myclirc.\',\n', " err=True, fg='red')\n", ' exit(1)\n', ' except Exception as e:\n', " click.secho(str(e), err=True, fg='red')\n", ' exit(1)\n', ' for alias, value in alias_dsn.items():\n', ' if verbose:\n', ' click.secho("{} : {}".format(alias, value))\n', ' else:\n', ' click.secho(alias)\n', ' sys.exit(0)\n', ' if list_ssh_config:\n', ' ssh_config = read_ssh_config(ssh_config_path)\n', ' for host in ssh_config.get_hostnames():\n', ' if verbose:\n', ' host_config = ssh_config.lookup(host)\n', ' click.secho("{} : {}".format(\n', " host, host_config.get('hostname')))\n", ' else:\n', ' click.secho(host)\n', ' sys.exit(0)\n', ' # Choose which ever one has a valid value.\n', ' database = dbname or database\n', '\n', ' ssl = {\n', " 'ca': ssl_ca and os.path.expanduser(ssl_ca),\n", " 'cert': ssl_cert and os.path.expanduser(ssl_cert),\n", " 'key': ssl_key and os.path.expanduser(ssl_key),\n", " 'capath': ssl_capath,\n", " 'cipher': ssl_cipher,\n", " 'check_hostname': ssl_verify_server_cert,\n", ' }\n', '\n', ' # remove empty ssl options\n', ' ssl = {k: v for k, v in ssl.items() if v is not None}\n', '\n', ' dsn_uri = None\n', '\n', " # Treat the database argument as a DSN alias if we're missing\n", ' # other connection information.\n', " if (mycli.config['alias_dsn'] and database and '://' not in database\n", ' and not any([user, password, host, port, login_path])):\n', " dsn, database = database, ''\n", '\n', " if database and '://' in database:\n", " dsn_uri, database = database, ''\n", '\n', ' if dsn:\n', ' try:\n', " dsn_uri = mycli.config['alias_dsn'][dsn]\n", ' except KeyError:\n', " click.secho('Could not find the specified DSN in the config " "file. '\n", ' \'Please check the "[alias_dsn]" section in your ' "'\n", " 'myclirc.', err=True, fg='red')\n", ' exit(1)\n', ' else:\n', ' mycli.dsn_alias = dsn\n', '\n', ' if dsn_uri:\n', ' uri = urlparse(dsn_uri)\n', ' if not database:\n', ' database = uri.path[1:] # ignore the leading fwd slash\n', ' if not user:\n', ' user = unquote(uri.username)\n', ' if not password and uri.password is not None:\n', ' password = unquote(uri.password)\n', ' if not host:\n', ' host = uri.hostname\n', ' if not port:\n', ' port = uri.port\n', '\n', ' if ssh_config_host:\n', ' ssh_config = read_ssh_config(\n', ' ssh_config_path\n', ' ).lookup(ssh_config_host)\n', " ssh_host = ssh_host if ssh_host else ssh_config.get('hostname')\n", " ssh_user = ssh_user if ssh_user else ssh_config.get('user')\n", " if ssh_config.get('port') and ssh_port == 22:\n", " # port has a default value, overwrite it if it's in the config\n", " ssh_port = int(ssh_config.get('port'))\n", ' ssh_key_filename = ssh_key_filename if ssh_key_filename else ' 'ssh_config.get(\n', " 'identityfile', [None])[0]\n", '\n', ' ssh_key_filename = ssh_key_filename and ' 'os.path.expanduser(ssh_key_filename)\n', '\n', ' mycli.connect(\n', ' database=database,\n', ' user=user,\n', ' passwd=password,\n', ' host=host,\n', ' port=port,\n', ' socket=socket,\n', ' local_infile=local_infile,\n', ' ssl=ssl,\n', ' ssh_user=ssh_user,\n', ' ssh_host=ssh_host,\n', ' ssh_port=ssh_port,\n', ' ssh_password=ssh_password,\n', ' ssh_key_filename=ssh_key_filename,\n', ' init_command=init_command\n', ' )\n', '\n', " mycli.logger.debug('Launch Params: \\n'\n", " '\\tdatabase: %r'\n", " '\\tuser: %r'\n", " '\\thost: %r'\n", " '\\tport: %r', database, user, host, port)\n", '\n', ' # --execute argument\n', ' if execute:\n', ' try:\n', ' if csv:\n', " mycli.formatter.format_name = 'csv'\n", ' elif not table:\n', " mycli.formatter.format_name = 'tsv'\n", '\n', ' mycli.run_query(execute)\n', ' exit(0)\n', ' except Exception as e:\n', " click.secho(str(e), err=True, fg='red')\n", ' exit(1)\n', '\n', ' if sys.stdin.isatty():\n', ' mycli.run_cli()\n', ' else:\n', " stdin = click.get_text_stream('stdin')\n", ' try:\n', ' stdin_text = stdin.read()\n', ' except MemoryError:\n', " click.secho('Failed! Ran out of memory.', err=True, fg='red')\n", " click.secho('You might want to try the official mysql client.', " "err=True, fg='red')\n", " click.secho('Sorry... :(', err=True, fg='red')\n", ' exit(1)\n', '\n', ' try:\n', " sys.stdin = open('/dev/tty')\n", ' except (IOError, OSError):\n', " mycli.logger.warning('Unable to open TTY as stdin.')\n", '\n', ' if (mycli.destructive_warning and\n', ' confirm_destructive_query(stdin_text) is False):\n', ' exit(0)\n', ' try:\n', ' new_line = True\n', '\n', ' if csv:\n', " mycli.formatter.format_name = 'csv'\n", ' elif not table:\n', " mycli.formatter.format_name = 'tsv'\n", '\n', ' mycli.run_query(stdin_text, new_line=new_line)\n', ' exit(0)\n', ' except Exception as e:\n', " click.secho(str(e), err=True, fg='red')\n", ' exit(1)\n', '\n', '\n', 'def need_completion_refresh(queries):\n', ' """Determines if the completion needs a refresh by checking if the sql\n', ' statement is an alter, create, drop or change db."""\n', ' for query in sqlparse.split(queries):\n', ' try:\n', ' first_token = query.split()[0]\n', " if first_token.lower() in ('alter', 'create', 'use', '\\\\r',\n", " '\\\\u', 'connect', 'drop', " "'rename'):\n", ' return True\n', ' except Exception:\n', ' return False\n', '\n', '\n', 'def need_completion_reset(queries):\n', ' """Determines if the statement is a database switch such as \'use\' or ' "'\\\\u'.\n", ' When a database is changed the existing completions must be reset before ' 'we\n', ' start the completion refresh for the new database.\n', ' """\n', ' for query in sqlparse.split(queries):\n', ' try:\n', ' first_token = query.split()[0]\n', " if first_token.lower() in ('use', '\\\\u'):\n", ' return True\n', ' except Exception:\n', ' return False\n', '\n', '\n', 'def is_mutating(status):\n', ' """Determines if the statement is mutating based on the status."""\n', ' if not status:\n', ' return False\n', '\n', " mutating = set(['insert', 'update', 'delete', 'alter', 'create', " "'drop',\n", " 'replace', 'truncate', 'load', 'rename'])\n", ' return status.split(None, 1)[0].lower() in mutating\n', '\n', '\n', 'def is_select(status):\n', ' """Returns true if the first word in status is \'select\'."""\n', ' if not status:\n', ' return False\n', " return status.split(None, 1)[0].lower() == 'select'\n", '\n', '\n', 'def thanks_picker(files=()):\n', ' contents = []\n', ' for line in fileinput.input(files=files):\n', " m = re.match('^ *\\* (.*)', line)\n", ' if m:\n', ' contents.append(m.group(1))\n', ' return choice(contents)\n', '\n', '\n', "@prompt_register('edit-and-execute-command')\n", 'def edit_and_execute(event):\n', ' """Different from the prompt-toolkit default, we want to have a choice ' 'not\n', ' to execute a query after editing, hence validate_and_handle=False."""\n', ' buff = event.current_buffer\n', ' buff.open_in_editor(validate_and_handle=False)\n', '\n', '\n', 'def read_ssh_config(ssh_config_path):\n', ' ssh_config = paramiko.config.SSHConfig()\n', ' try:\n', ' with open(ssh_config_path) as f:\n', ' ssh_config.parse(f)\n', ' # Paramiko prior to version 2.7 raises Exception on parse errors.\n', ' # In 2.7 it has become paramiko.ssh_exception.SSHException,\n', " # but let's catch everything for compatibility\n", ' except Exception as err:\n', ' click.secho(\n', " f'Could not parse SSH configuration file " "{ssh_config_path}:\\n{err} ',\n", " err=True, fg='red'\n", ' )\n', ' sys.exit(1)\n', ' except FileNotFoundError as e:\n', " click.secho(str(e), err=True, fg='red')\n", ' sys.exit(1)\n', ' else:\n', ' return ssh_config\n', '\n', '\n', 'if __name__ == "__main__":\n', ' cli()\n'] tests = [] /usr/lib/python3.8/site-packages/_pytest/doctest.py:522: in _find doctest.DocTestFinder._find( # type: ignore doctest = globs = {'AutoSuggestFromHistory': , 'CompleteStyle': , 'CompletionRefresher': , 'ConditionalProcessor': , 'DEFAULT_BUFFER': 'DEFAULT_BUFFER', 'Document': , 'DynamicCompleter': , 'EditingMode': , 'FIELD_TYPES': {0: , 1: , 2: , 3: , 4: , 5: , 6: , 7: , 8: , 9: , 10: , 11: , 12: , 13: , 15: , 16: , 246: , 249: , 250: , 251: , 252: , 253: , 254: }, 'FavoriteQueries': , 'FileHistory': , 'HasFocus': , 'HighlightMatchingBracketProcessor': , 'IsDone': at 0x7f26ad7b0310>, 'MyCli': , 'MyCliLexer': , 'NO_QUERY': 0, 'OperationalError': , 'PACKAGE_ROOT': '/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli', 'PromptSession': , 'PygmentsLexer': , 'Query': , 'SQLCompleter': , 'SQLExecute': , 'TabularOutputFormatter': , 'WIN': False, '__builtins__': {'ArithmeticError': , 'AssertionError': , 'AttributeError': , 'BaseException': , 'BlockingIOError': , 'BrokenPipeError': , 'BufferError': , 'BytesWarning': , 'ChildProcessError': , 'ConnectionAbortedError': , 'ConnectionError': , 'ConnectionRefusedError': , 'ConnectionResetError': , 'DeprecationWarning': , 'EOFError': , 'Ellipsis': Ellipsis, 'EnvironmentError': , 'Exception': , 'False': False, 'FileExistsError': , 'FileNotFoundError': , 'FloatingPointError': , 'FutureWarning': , 'GeneratorExit': , 'IOError': , 'ImportError': , 'ImportWarning': , 'IndentationError': , 'IndexError': , 'InterruptedError': , 'IsADirectoryError': , 'KeyError': , 'KeyboardInterrupt': , 'LookupError': , 'MemoryError': , 'ModuleNotFoundError': , 'NameError': , 'None': None, 'NotADirectoryError': , 'NotImplemented': NotImplemented, 'NotImplementedError': , 'OSError': , 'OverflowError': , 'PendingDeprecationWarning': , 'PermissionError': , 'ProcessLookupError': , 'RecursionError': , 'ReferenceError': , 'ResourceWarning': , 'RuntimeError': , 'RuntimeWarning': , 'StopAsyncIteration': , 'StopIteration': , 'SyntaxError': , 'SyntaxWarning': , 'SystemError': , 'SystemExit': , 'TabError': , 'TimeoutError': , 'True': True, 'TypeError': , 'UnboundLocalError': , 'UnicodeDecodeError': , 'UnicodeEncodeError': , 'UnicodeError': , 'UnicodeTranslateError': , 'UnicodeWarning': , 'UserWarning': , 'ValueError': , 'Warning': , 'ZeroDivisionError': , '__build_class__': , '__debug__': True, '__doc__': 'Built-in functions, exceptions, and other ' 'objects.\n' '\n' "Noteworthy: None is the `nil' object; Ellipsis " "represents `...' in slices.", '__import__': , '__loader__': , '__name__': 'builtins', '__package__': '', '__spec__': ModuleSpec(name='builtins', loader=), 'abs': , 'all': , 'any': , 'ascii': , 'bin': , 'bool': , 'breakpoint': , 'bytearray': , 'bytes': , 'callable': , 'chr': , 'classmethod': , 'compile': , 'complex': , 'copyright': Copyright (c) 2001-2021 Python Software Foundation. All Rights Reserved. Copyright (c) 2000 BeOpen.com. All Rights Reserved. Copyright (c) 1995-2001 Corporation for National Research Initiatives. All Rights Reserved. Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam. All Rights Reserved., 'credits': Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands for supporting Python development. See www.python.org for more information., 'delattr': , 'dict': , 'dir': , 'divmod': , 'enumerate': , 'eval': , 'exec': , 'exit': Use exit() or Ctrl-D (i.e. EOF) to exit, 'filter': , 'float': , 'format': , 'frozenset': , 'getattr': , 'globals': , 'hasattr': , 'hash': , 'help': Type help() for interactive help, or help(object) for help about object., 'hex': , 'id': , 'input': , 'int': , 'isinstance': , 'issubclass': , 'iter': , 'len': , 'license': Type license() to see the full license text, 'list': , 'locals': , 'map': , 'max': , 'memoryview': , 'min': , 'next': , 'object': , 'oct': , 'open': , 'ord': , 'pow': , 'print': , 'property': , 'quit': Use quit() or Ctrl-D (i.e. EOF) to exit, 'range': , 'repr': , 'reversed': , 'round': , 'set': , 'setattr': , 'slice': , 'sorted': , 'staticmethod': , 'str': , 'sum': , 'super': , 'tuple': , 'type': , 'vars': , 'zip': }, '__cached__': '/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/__pycache__/main.cpython-38.pyc', '__doc__': None, '__file__': '/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/main.py', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f26adfaf640>, '__name__': 'mycli.main', '__package__': 'mycli', '__spec__': ModuleSpec(name='mycli.main', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7f26adfaf640>, origin='/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/main.py'), '__version__': '1.22.2', 'choice': >, 'cli': , 'cli_is_multiline': , 'click': , 'confirm': , 'confirm_destructive_query': , 'create_toolbar_tokens_func': , 'datetime': , 'dir_path_exists': , 'edit_and_execute': , 'fileinput': , 'get_mylogin_cnf_path': , 'getpwuid': , 'guess_socket_location': , 'is_dropping_database': , 'is_mutating': , 'is_select': , 'itertools': , 'logging': , 'mycli_bindings': , 'namedtuple': , 'need_completion_refresh': , 'need_completion_reset': , 'open': , 'open_mylogin_cnf': , 'os': , 'paramiko': , 'preprocessors': , 'prompt_register': , 're': , 'read_config_files': , 'read_ssh_config': , 'special': , 'sql_format': , 'sqlparse': , 'str_to_bool': , 'strip_ansi': , 'strip_matching_quotes': , 'style_factory': , 'style_factory_output': , 'sys': , 'thanks_picker': , 'threading': , 'time': , 'traceback': , 'unquote': , 'urlparse': , 'write_default_config': } module = name = 'mycli.main' obj = seen = {139804099906032: 1} self = <_pytest.doctest.DoctestModule.collect..MockAwareDocTestFinder object at 0x7f26ad21d910> source_lines = ['import os\n', 'import sys\n', 'import traceback\n', 'import logging\n', 'import threading\n', 'import re\n', 'import fileinput\n', 'from collections import namedtuple\n', 'try:\n', ' from pwd import getpwuid\n', 'except ImportError:\n', ' pass\n', 'from time import time\n', 'from datetime import datetime\n', 'from random import choice\n', 'from io import open\n', '\n', 'from pymysql import OperationalError\n', 'from cli_helpers.tabular_output import TabularOutputFormatter\n', 'from cli_helpers.tabular_output import preprocessors\n', 'from cli_helpers.utils import strip_ansi\n', 'import click\n', 'import sqlparse\n', 'from mycli.packages.parseutils import is_dropping_database\n', 'from prompt_toolkit.completion import DynamicCompleter\n', 'from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode\n', 'from prompt_toolkit.key_binding.bindings.named_commands import register as ' 'prompt_register\n', 'from prompt_toolkit.shortcuts import PromptSession, CompleteStyle\n', 'from prompt_toolkit.document import Document\n', 'from prompt_toolkit.filters import HasFocus, IsDone\n', 'from prompt_toolkit.layout.processors import ' '(HighlightMatchingBracketProcessor,\n', ' ConditionalProcessor)\n', 'from prompt_toolkit.lexers import PygmentsLexer\n', 'from prompt_toolkit.history import FileHistory\n', 'from prompt_toolkit.auto_suggest import AutoSuggestFromHistory\n', '\n', 'from .packages.special.main import NO_QUERY\n', 'from .packages.prompt_utils import confirm, confirm_destructive_query\n', 'from .packages.tabular_output import sql_format\n', 'from .packages import special\n', 'from .packages.special.favoritequeries import FavoriteQueries\n', 'from .sqlcompleter import SQLCompleter\n', 'from .clitoolbar import create_toolbar_tokens_func\n', 'from .clistyle import style_factory, style_factory_output\n', 'from .sqlexecute import FIELD_TYPES, SQLExecute\n', 'from .clibuffer import cli_is_multiline\n', 'from .completion_refresher import CompletionRefresher\n', 'from .config import (write_default_config, get_mylogin_cnf_path,\n', ' open_mylogin_cnf, read_config_files, str_to_bool,\n', ' strip_matching_quotes)\n', 'from .key_bindings import mycli_bindings\n', 'from .lexer import MyCliLexer\n', 'from .__init__ import __version__\n', 'from .compat import WIN\n', 'from .packages.filepaths import dir_path_exists, guess_socket_location\n', '\n', 'import itertools\n', '\n', 'click.disable_unicode_literals_warning = True\n', '\n', 'try:\n', ' from urlparse import urlparse\n', ' from urlparse import unquote\n', 'except ImportError:\n', ' from urllib.parse import urlparse\n', ' from urllib.parse import unquote\n', '\n', '\n', 'try:\n', ' import paramiko\n', 'except ImportError:\n', ' from mycli.packages.paramiko_stub import paramiko\n', '\n', '# Query tuples are used for maintaining history\n', "Query = namedtuple('Query', ['query', 'successful', 'mutating'])\n", '\n', 'PACKAGE_ROOT = os.path.abspath(os.path.dirname(__file__))\n', '\n', '\n', 'class MyCli(object):\n', '\n', " default_prompt = '\\\\t \\\\u@\\\\h:\\\\d> '\n", ' max_len_prompt = 45\n', ' defaults_suffix = None\n', '\n', ' # In order of being loaded. Files lower in list override earlier ones.\n', ' cnf_files = [\n', " '/etc/my.cnf',\n", " '/etc/mysql/my.cnf',\n", " '/usr/local/etc/my.cnf',\n", " '~/.my.cnf'\n", ' ]\n', '\n', ' # check XDG_CONFIG_HOME exists and not an empty string\n', ' if os.environ.get("XDG_CONFIG_HOME"):\n', ' xdg_config_home = os.environ.get("XDG_CONFIG_HOME")\n', ' else:\n', ' xdg_config_home = "~/.config"\n', ' system_config_files = [\n', " '/etc/myclirc',\n", ' os.path.join(os.path.expanduser(xdg_config_home), "mycli", ' '"myclirc")\n', ' ]\n', '\n', " default_config_file = os.path.join(PACKAGE_ROOT, 'myclirc')\n", ' pwd_config_file = os.path.join(os.getcwd(), ".myclirc")\n', '\n', ' def __init__(self, sqlexecute=None, prompt=None,\n', ' logfile=None, defaults_suffix=None, defaults_file=None,\n', ' login_path=None, auto_vertical_output=False, warn=None,\n', ' myclirc="~/.myclirc"):\n', ' self.sqlexecute = sqlexecute\n', ' self.logfile = logfile\n', ' self.defaults_suffix = defaults_suffix\n', ' self.login_path = login_path\n', '\n', ' # self.cnf_files is a class variable that stores the list of mysql\n', ' # config files to read in at launch.\n', ' # If defaults_file is specified then override the class variable ' 'with\n', ' # defaults_file.\n', ' if defaults_file:\n', ' self.cnf_files = [defaults_file]\n', '\n', ' # Load config.\n', ' config_files = ([self.default_config_file] + ' 'self.system_config_files +\n', ' [myclirc] + [self.pwd_config_file])\n', ' c = self.config = read_config_files(config_files)\n', " self.multi_line = c['main'].as_bool('multi_line')\n", " self.key_bindings = c['main']['key_bindings']\n", " special.set_timing_enabled(c['main'].as_bool('timing'))\n", '\n', ' FavoriteQueries.instance = ' 'FavoriteQueries.from_config(self.config)\n', '\n', ' self.dsn_alias = None\n', ' self.formatter = TabularOutputFormatter(\n', " format_name=c['main']['table_format'])\n", ' sql_format.register_new_formatter(self.formatter)\n', ' self.formatter.mycli = self\n', " self.syntax_style = c['main']['syntax_style']\n", " self.less_chatty = c['main'].as_bool('less_chatty')\n", " self.cli_style = c['colors']\n", ' self.output_style = style_factory_output(\n', ' self.syntax_style,\n', ' self.cli_style\n', ' )\n', ' self.wider_completion_menu = ' "c['main'].as_bool('wider_completion_menu')\n", " c_dest_warning = c['main'].as_bool('destructive_warning')\n", ' self.destructive_warning = c_dest_warning if warn is None else ' 'warn\n', " self.login_path_as_host = c['main'].as_bool('login_path_as_host')\n", '\n', ' # read from cli argument or user config file\n', ' self.auto_vertical_output = auto_vertical_output or \\\n', " c['main'].as_bool('auto_vertical_output')\n", '\n', " # Write user config if system config wasn't the last config " 'loaded.\n', ' if c.filename not in self.system_config_files and not ' 'os.path.exists(myclirc):\n', ' write_default_config(self.default_config_file, myclirc)\n', '\n', ' # audit log\n', " if self.logfile is None and 'audit_log' in c['main']:\n", ' try:\n', ' self.logfile = ' "open(os.path.expanduser(c['main']['audit_log']), 'a')\n", ' except (IOError, OSError) as e:\n', " self.echo('Error: Unable to open the audit log file. Your " "queries will not be logged.',\n", " err=True, fg='red')\n", ' self.logfile = False\n', '\n', ' self.completion_refresher = CompletionRefresher()\n', '\n', ' self.logger = logging.getLogger(__name__)\n', ' self.initialize_logging()\n', '\n', ' prompt_cnf = self.read_my_cnf_files(self.cnf_files, ' "['prompt'])['prompt']\n", " self.prompt_format = prompt or prompt_cnf or c['main']['prompt'] or " '\\\n', ' self.default_prompt\n', ' self.multiline_continuation_char = ' "c['main']['prompt_continuation']\n", " keyword_casing = c['main'].get('keyword_casing', 'auto')\n", '\n', ' self.query_history = []\n', '\n', ' # Initialize completer.\n', " self.smart_completion = c['main'].as_bool('smart_completion')\n", ' self.completer = SQLCompleter(\n', ' self.smart_completion,\n', ' supported_formats=self.formatter.supported_formats,\n', ' keyword_casing=keyword_casing)\n', ' self._completer_lock = threading.Lock()\n', '\n', ' # Register custom special commands.\n', ' self.register_special_commands()\n', '\n', ' # Load .mylogin.cnf if it exists.\n', ' mylogin_cnf_path = get_mylogin_cnf_path()\n', ' if mylogin_cnf_path:\n', ' mylogin_cnf = open_mylogin_cnf(mylogin_cnf_path)\n', ' if mylogin_cnf_path and mylogin_cnf:\n', ' # .mylogin.cnf gets read last, even if defaults_file is ' 'specified.\n', ' self.cnf_files.append(mylogin_cnf)\n', ' elif mylogin_cnf_path and not mylogin_cnf:\n', ' # There was an error reading the login path file.\n', " print('Error: Unable to read login path file.')\n", '\n', ' self.prompt_app = None\n', '\n', ' def register_special_commands(self):\n', " special.register_special_command(self.change_db, 'use',\n", " '\\\\u', 'Change to a new database.', aliases=('\\\\u',))\n", " special.register_special_command(self.change_db, 'connect',\n", " '\\\\r', 'Reconnect to the database. Optional database " "argument.',\n", " aliases=('\\\\r', ), case_sensitive=True)\n", ' special.register_special_command(self.refresh_completions, ' "'rehash',\n", " '\\\\#', 'Refresh auto-completions.', arg_type=NO_QUERY, " "aliases=('\\\\#',))\n", ' special.register_special_command(\n', " self.change_table_format, 'tableformat', '\\\\T',\n", " 'Change the table format used to output results.',\n", " aliases=('\\\\T',), case_sensitive=True)\n", " special.register_special_command(self.execute_from_file, 'source', " "'\\\\. filename',\n", " 'Execute commands from file.', " "aliases=('\\\\.',))\n", ' special.register_special_command(self.change_prompt_format, ' "'prompt',\n", " '\\\\R', 'Change prompt format.', aliases=('\\\\R',), " 'case_sensitive=True)\n', '\n', ' def change_table_format(self, arg, **_):\n', ' try:\n', ' self.formatter.format_name = arg\n', ' yield (None, None, None,\n', " 'Changed table format to {}'.format(arg))\n", ' except ValueError:\n', " msg = 'Table format {} not recognized. Allowed " "formats:'.format(\n", ' arg)\n', ' for table_type in self.formatter.supported_formats:\n', ' msg += "\\n\\t{}".format(table_type)\n', ' yield (None, None, None, msg)\n', '\n', ' def change_db(self, arg, **_):\n', ' if not arg:\n', ' click.secho(\n', ' "No database selected",\n', ' err=True, fg="red"\n', ' )\n', ' return\n', '\n', ' self.sqlexecute.change_db(arg)\n', '\n', ' yield (None, None, None, \'You are now connected to database "%s" as ' "'\n", ' \'user "%s"\' % (self.sqlexecute.dbname, ' 'self.sqlexecute.user))\n', '\n', ' def execute_from_file(self, arg, **_):\n', ' if not arg:\n', " message = 'Missing required argument, filename.'\n", ' return [(None, None, None, message)]\n', ' try:\n', ' with open(os.path.expanduser(arg)) as f:\n', ' query = f.read()\n', ' except IOError as e:\n', ' return [(None, None, None, str(e))]\n', '\n', ' if (self.destructive_warning and\n', ' confirm_destructive_query(query) is False):\n', " message = 'Wise choice. Command execution stopped.'\n", ' return [(None, None, None, message)]\n', '\n', ' return self.sqlexecute.run(query)\n', '\n', ' def change_prompt_format(self, arg, **_):\n', ' """\n', ' Change the prompt format.\n', ' """\n', ' if not arg:\n', " message = 'Missing required argument, format.'\n", ' return [(None, None, None, message)]\n', '\n', ' self.prompt_format = self.get_prompt(arg)\n', ' return [(None, None, None, "Changed prompt format to %s" % arg)]\n', '\n', ' def initialize_logging(self):\n', '\n', " log_file = os.path.expanduser(self.config['main']['log_file'])\n", " log_level = self.config['main']['log_level']\n", '\n', " level_map = {'CRITICAL': logging.CRITICAL,\n", " 'ERROR': logging.ERROR,\n", " 'WARNING': logging.WARNING,\n", " 'INFO': logging.INFO,\n", " 'DEBUG': logging.DEBUG\n", ' }\n', '\n', ' # Disable logging if value is NONE by switching to a no-op handler\n', " # Set log level to a high value so it doesn't even waste cycles " 'getting called.\n', ' if log_level.upper() == "NONE":\n', ' handler = logging.NullHandler()\n', ' log_level = "CRITICAL"\n', ' elif dir_path_exists(log_file):\n', ' handler = logging.FileHandler(log_file)\n', ' else:\n', ' self.echo(\n', " 'Error: Unable to open the log file " '"{}".\'.format(log_file),\n', " err=True, fg='red')\n", ' return\n', '\n', ' formatter = logging.Formatter(\n', " '%(asctime)s (%(process)d/%(threadName)s) '\n", " '%(name)s %(levelname)s - %(message)s')\n", '\n', ' handler.setFormatter(formatter)\n', '\n', " root_logger = logging.getLogger('mycli')\n", ' root_logger.addHandler(handler)\n', ' root_logger.setLevel(level_map[log_level.upper()])\n', '\n', ' logging.captureWarnings(True)\n', '\n', " root_logger.debug('Initializing mycli logging.')\n", " root_logger.debug('Log file %r.', log_file)\n", '\n', '\n', ' def read_my_cnf_files(self, files, keys):\n', ' """\n', ' Reads a list of config files and merges them. The last one will ' 'win.\n', ' :param files: list of files to read\n', ' :param keys: list of keys to retrieve\n', ' :returns: tuple, with None for missing keys.\n', ' """\n', ' cnf = read_config_files(files, list_values=False)\n', '\n', " sections = ['client', 'mysqld']\n", " if self.login_path and self.login_path != 'client':\n", ' sections.append(self.login_path)\n', '\n', ' if self.defaults_suffix:\n', ' sections.extend([sect + self.defaults_suffix for sect in ' 'sections])\n', '\n', ' def get(key):\n', ' result = None\n', ' for sect in cnf:\n', ' if sect in sections and key in cnf[sect]:\n', ' result = strip_matching_quotes(cnf[sect][key])\n', ' return result\n', '\n', ' return {x: get(x) for x in keys}\n', '\n', ' def merge_ssl_with_cnf(self, ssl, cnf):\n', ' """Merge SSL configuration dict with cnf dict"""\n', '\n', ' merged = {}\n', ' merged.update(ssl)\n', " prefix = 'ssl-'\n", ' for k, v in cnf.items():\n', ' # skip unrelated options\n', ' if not k.startswith(prefix):\n', ' continue\n', ' if v is None:\n', ' continue\n', ' # special case because PyMySQL argument is significantly ' 'different\n', ' # from commandline\n', " if k == 'ssl-verify-server-cert':\n", " merged['check_hostname'] = v\n", ' else:\n', ' # use argument name just strip "ssl-" prefix\n', ' arg = k[len(prefix):]\n', ' merged[arg] = v\n', '\n', ' return merged\n', '\n', " def connect(self, database='', user='', passwd='', host='', port='',\n", " socket='', charset='', local_infile='', ssl='',\n", " ssh_user='', ssh_host='', ssh_port='',\n", " ssh_password='', ssh_key_filename='', init_command=''):\n", '\n', " cnf = {'database': None,\n", " 'user': None,\n", " 'password': None,\n", " 'host': None,\n", " 'port': None,\n", " 'socket': None,\n", " 'default-character-set': None,\n", " 'local-infile': None,\n", " 'loose-local-infile': None,\n", " 'ssl-ca': None,\n", " 'ssl-cert': None,\n", " 'ssl-key': None,\n", " 'ssl-cipher': None,\n", " 'ssl-verify-serer-cert': None,\n", ' }\n', '\n', ' cnf = self.read_my_cnf_files(self.cnf_files, cnf.keys())\n', '\n', ' # Fall back to config values only if user did not specify a value.\n', '\n', " database = database or cnf['database']\n", ' # Socket interface not supported for SSH connections\n', ' if port or host or ssh_host or ssh_port:\n', " socket = ''\n", ' else:\n', " socket = socket or cnf['socket'] or guess_socket_location()\n", " user = user or cnf['user'] or os.getenv('USER')\n", " host = host or cnf['host']\n", " port = port or cnf['port']\n", ' ssl = ssl or {}\n', '\n', " passwd = passwd if isinstance(passwd, str) else cnf['password']\n", " charset = charset or cnf['default-character-set'] or 'utf8'\n", '\n', ' # Favor whichever local_infile option is set.\n', " for local_infile_option in (local_infile, cnf['local-infile'],\n", " cnf['loose-local-infile'], False):\n", ' try:\n', ' local_infile = str_to_bool(local_infile_option)\n', ' break\n', ' except (TypeError, ValueError):\n', ' pass\n', '\n', ' ssl = self.merge_ssl_with_cnf(ssl, cnf)\n', ' # prune lone check_hostname=False\n', ' if not any(v for v in ssl.values()):\n', ' ssl = None\n', '\n', ' # Connect to the database.\n', '\n', ' def _connect():\n', ' try:\n', ' self.sqlexecute = SQLExecute(\n', ' database, user, passwd, host, port, socket, charset,\n', ' local_infile, ssl, ssh_user, ssh_host, ssh_port,\n', ' ssh_password, ssh_key_filename, init_command\n', ' )\n', ' except OperationalError as e:\n', " if ('Access denied for user' in e.args[1]):\n", " new_passwd = click.prompt('Password', hide_input=True,\n", ' show_default=False, type=str, ' 'err=True)\n', ' self.sqlexecute = SQLExecute(\n', ' database, user, new_passwd, host, port, socket,\n', ' charset, local_infile, ssl, ssh_user, ssh_host,\n', ' ssh_port, ssh_password, ssh_key_filename, ' 'init_command\n', ' )\n', ' else:\n', ' raise e\n', '\n', ' try:\n', ' if not WIN and socket:\n', ' socket_owner = getpwuid(os.stat(socket).st_uid).pw_name\n', ' self.echo(\n', ' f"Connecting to socket {socket}, owned by user ' '{socket_owner}")\n', ' try:\n', ' _connect()\n', ' except OperationalError as e:\n', ' # These are "Can\'t open socket" and 2x "Can\'t ' 'connect"\n', ' if [code for code in (2001, 2002, 2003) if code == ' 'e.args[0]]:\n', " self.logger.debug('Database connection failed: %r.', " 'e)\n', ' self.logger.error(\n', ' "traceback: %r", traceback.format_exc())\n', " self.logger.debug('Retrying over TCP/IP')\n", ' self.echo(\n', ' "Failed to connect to local MySQL server through ' 'socket \'{}\':".format(socket))\n', ' self.echo(str(e), err=True)\n', ' self.echo(\n', " 'Retrying over TCP/IP', err=True)\n", '\n', ' # Else fall back to TCP/IP localhost\n', ' socket = ""\n', " host = 'localhost'\n", ' port = 3306\n', ' _connect()\n', ' else:\n', ' raise e\n', ' else:\n', " host = host or 'localhost'\n", ' port = port or 3306\n', '\n', ' # Bad ports give particularly daft error messages\n', ' try:\n', ' port = int(port)\n', ' except ValueError as e:\n', ' self.echo("Error: Invalid port number: ' '\'{0}\'.".format(port),\n', " err=True, fg='red')\n", ' exit(1)\n', '\n', ' _connect()\n', ' except Exception as e: # Connecting to a database could fail.\n', " self.logger.debug('Database connection failed: %r.', e)\n", ' self.logger.error("traceback: %r", traceback.format_exc())\n', " self.echo(str(e), err=True, fg='red')\n", ' exit(1)\n', '\n', ' def handle_editor_command(self, text):\n', ' """Editor command is any query that is prefixed or suffixed by a ' "'\\e'.\n", ' The reason for a while loop is because a user might edit a query\n', ' multiple times. For eg:\n', '\n', ' "select * from \\e" to edit it in vim, then come\n', ' back to the prompt with the edited query "select * from\n', ' blah where q = \'abc\'\\e" to edit it again.\n', ' :param text: Document\n', ' :return: Document\n', '\n', ' """\n', '\n', ' while special.editor_command(text):\n', ' filename = special.get_filename(text)\n', ' query = (special.get_editor_query(text) or\n', ' self.get_last_query())\n', ' sql, message = special.open_external_editor(filename, ' 'sql=query)\n', ' if message:\n', ' # Something went wrong. Raise an exception and bail.\n', ' raise RuntimeError(message)\n', ' while True:\n', ' try:\n', ' text = self.prompt_app.prompt(default=sql)\n', ' break\n', ' except KeyboardInterrupt:\n', ' sql = ""\n', '\n', ' continue\n', ' return text\n', '\n', ' def run_cli(self):\n', ' iterations = 0\n', ' sqlexecute = self.sqlexecute\n', ' logger = self.logger\n', ' self.configure_pager()\n', '\n', ' if self.smart_completion:\n', ' self.refresh_completions()\n', '\n', " author_file = os.path.join(PACKAGE_ROOT, 'AUTHORS')\n", " sponsor_file = os.path.join(PACKAGE_ROOT, 'SPONSORS')\n", '\n', ' history_file = os.path.expanduser(\n', " os.environ.get('MYCLI_HISTFILE', '~/.mycli-history'))\n", ' if dir_path_exists(history_file):\n', ' history = FileHistory(history_file)\n', ' else:\n', ' history = None\n', ' self.echo(\n', ' \'Error: Unable to open the history file "{}". \'\n', " 'Your query history will not be " "saved.'.format(history_file),\n", " err=True, fg='red')\n", '\n', ' key_bindings = mycli_bindings(self)\n', '\n', ' if not self.less_chatty:\n', " print(' '.join(sqlexecute.server_type()))\n", " print('mycli', __version__)\n", " print('Chat: https://gitter.im/dbcli/mycli')\n", " print('Mail: " "https://groups.google.com/forum/#!forum/mycli-users')\n", " print('Home: http://mycli.net')\n", " print('Thanks to the contributor -', thanks_picker([author_file, " 'sponsor_file]))\n', '\n', ' def get_message():\n', ' prompt = self.get_prompt(self.prompt_format)\n', ' if self.prompt_format == self.default_prompt and len(prompt) > ' 'self.max_len_prompt:\n', " prompt = self.get_prompt('\\\\d> ')\n", " return [('class:prompt', prompt)]\n", '\n', ' def get_continuation(width, *_):\n', ' if self.multiline_continuation_char:\n', ' left_padding = width - ' 'len(self.multiline_continuation_char)\n', ' continuation = " " * \\\n', ' max((left_padding - 1), 0) + \\\n', ' self.multiline_continuation_char + " "\n', ' else:\n', ' continuation = " "\n', " return [('class:continuation', continuation)]\n", '\n', ' def show_suggestion_tip():\n', ' return iterations < 2\n', '\n', ' def one_iteration(text=None):\n', ' if text is None:\n', ' try:\n', ' text = self.prompt_app.prompt()\n', ' except KeyboardInterrupt:\n', ' return\n', '\n', ' special.set_expanded_output(False)\n', '\n', ' try:\n', ' text = self.handle_editor_command(text)\n', ' except RuntimeError as e:\n', ' logger.error("sql: %r, error: %r", text, e)\n', ' logger.error("traceback: %r", traceback.format_exc())\n', " self.echo(str(e), err=True, fg='red')\n", ' return\n', '\n', ' if not text.strip():\n', ' return\n', '\n', ' if self.destructive_warning:\n', ' destroy = confirm_destructive_query(text)\n', ' if destroy is None:\n', ' pass # Query was not destructive. Nothing to do here.\n', ' elif destroy is True:\n', " self.echo('Your call!')\n", ' else:\n', " self.echo('Wise choice!')\n", ' return\n', ' else:\n', ' destroy = True\n', '\n', ' # Keep track of whether or not the query is mutating. In case\n', ' # of a multi-statement query, the overall query is considered\n', ' # mutating if any one of the component statements is mutating\n', ' mutating = False\n', '\n', ' try:\n', " logger.debug('sql: %r', text)\n", '\n', ' special.write_tee(self.get_prompt(self.prompt_format) + ' 'text)\n', ' if self.logfile:\n', " self.logfile.write('\\n# %s\\n' % datetime.now())\n", ' self.logfile.write(text)\n', " self.logfile.write('\\n')\n", '\n', ' successful = False\n', ' start = time()\n', ' res = sqlexecute.run(text)\n', ' self.formatter.query = text\n', ' successful = True\n', ' result_count = 0\n', ' for title, cur, headers, status in res:\n', ' logger.debug("headers: %r", headers)\n', ' logger.debug("rows: %r", cur)\n', ' logger.debug("status: %r", status)\n', ' threshold = 1000\n', ' if (is_select(status) and\n', ' cur and cur.rowcount > threshold):\n', " self.echo('The result set has more than {} " "rows.'.format(\n", " threshold), fg='red')\n", " if not confirm('Do you want to continue?'):\n", ' self.echo("Aborted!", err=True, fg=\'red\')\n', ' break\n', '\n', ' if self.auto_vertical_output:\n', ' max_width = ' 'self.prompt_app.output.get_size().columns\n', ' else:\n', ' max_width = None\n', '\n', ' formatted = self.format_output(\n', ' title, cur, headers, special.is_expanded_output(),\n', ' max_width)\n', '\n', ' t = time() - start\n', ' try:\n', ' if result_count > 0:\n', " self.echo('')\n", ' try:\n', ' self.output(formatted, status)\n', ' except KeyboardInterrupt:\n', ' pass\n', ' if special.is_timing_enabled():\n', " self.echo('Time: %0.03fs' % t)\n", ' except KeyboardInterrupt:\n', ' pass\n', '\n', ' start = time()\n', ' result_count += 1\n', ' mutating = mutating or destroy or is_mutating(status)\n', ' special.unset_once_if_written()\n', ' except EOFError as e:\n', ' raise e\n', ' except KeyboardInterrupt:\n', ' # get last connection id\n', ' connection_id_to_kill = sqlexecute.connection_id\n', ' logger.debug("connection id to kill: %r", ' 'connection_id_to_kill)\n', ' # Restart connection to the database\n', ' sqlexecute.connect()\n', ' try:\n', " for title, cur, headers, status in sqlexecute.run('kill " "%s' % connection_id_to_kill):\n", ' status_str = str(status).lower()\n', " if status_str.find('ok') > -1:\n", ' logger.debug("cancelled query, connection id: ' '%r, sql: %r",\n', ' connection_id_to_kill, text)\n', ' self.echo("cancelled query", err=True, ' "fg='red')\n", ' except Exception as e:\n', " self.echo('Encountered error while cancelling query: " "{}'.format(e),\n", " err=True, fg='red')\n", ' except NotImplementedError:\n', ' self.echo(\'Not Yet Implemented.\', fg="yellow")\n', ' except OperationalError as e:\n', ' logger.debug("Exception: %r", e)\n', ' if (e.args[0] in (2003, 2006, 2013)):\n', " logger.debug('Attempting to reconnect.')\n", " self.echo('Reconnecting...', fg='yellow')\n", ' try:\n', ' sqlexecute.connect()\n', " logger.debug('Reconnected successfully.')\n", ' one_iteration(text)\n', ' return # OK to just return, cuz the recursion call ' 'runs to the end.\n', ' except OperationalError as e:\n', " logger.debug('Reconnect failed. e: %r', e)\n", " self.echo(str(e), err=True, fg='red')\n", " # If reconnection failed, don't proceed further.\n", ' return\n', ' else:\n', ' logger.error("sql: %r, error: %r", text, e)\n', ' logger.error("traceback: %r", traceback.format_exc())\n', " self.echo(str(e), err=True, fg='red')\n", ' except Exception as e:\n', ' logger.error("sql: %r, error: %r", text, e)\n', ' logger.error("traceback: %r", traceback.format_exc())\n', " self.echo(str(e), err=True, fg='red')\n", ' else:\n', ' if is_dropping_database(text, self.sqlexecute.dbname):\n', ' self.sqlexecute.dbname = None\n', ' self.sqlexecute.connect()\n', '\n', ' # Refresh the table names and column names if necessary.\n', ' if need_completion_refresh(text):\n', ' self.refresh_completions(\n', ' reset=need_completion_reset(text))\n', ' finally:\n', ' if self.logfile is False:\n', ' self.echo("Warning: This query was not logged.",\n', " err=True, fg='red')\n", ' query = Query(text, successful, mutating)\n', ' self.query_history.append(query)\n', '\n', ' get_toolbar_tokens = create_toolbar_tokens_func(\n', ' self, show_suggestion_tip)\n', ' if self.wider_completion_menu:\n', ' complete_style = CompleteStyle.MULTI_COLUMN\n', ' else:\n', ' complete_style = CompleteStyle.COLUMN\n', '\n', ' with self._completer_lock:\n', '\n', " if self.key_bindings == 'vi':\n", ' editing_mode = EditingMode.VI\n', ' else:\n', ' editing_mode = EditingMode.EMACS\n', '\n', ' self.prompt_app = PromptSession(\n', ' lexer=PygmentsLexer(MyCliLexer),\n', ' reserve_space_for_menu=self.get_reserved_space(),\n', ' message=get_message,\n', ' prompt_continuation=get_continuation,\n', ' bottom_toolbar=get_toolbar_tokens,\n', ' complete_style=complete_style,\n', ' input_processors=[ConditionalProcessor(\n', ' processor=HighlightMatchingBracketProcessor(\n', " chars='[](){}'),\n", ' filter=HasFocus(DEFAULT_BUFFER) & ~IsDone()\n', ' )],\n', " tempfile_suffix='.sql',\n", ' completer=DynamicCompleter(lambda: self.completer),\n', ' history=history,\n', ' auto_suggest=AutoSuggestFromHistory(),\n', ' complete_while_typing=True,\n', ' multiline=cli_is_multiline(self),\n', ' style=style_factory(self.syntax_style, self.cli_style),\n', ' include_default_pygments_style=False,\n', ' key_bindings=key_bindings,\n', ' enable_open_in_editor=True,\n', ' enable_system_prompt=True,\n', ' enable_suspend=True,\n', ' editing_mode=editing_mode,\n', ' search_ignore_case=True\n', ' )\n', '\n', ' try:\n', ' while True:\n', ' one_iteration()\n', ' iterations += 1\n', ' except EOFError:\n', ' special.close_tee()\n', ' if not self.less_chatty:\n', " self.echo('Goodbye!')\n", '\n', ' def log_output(self, output):\n', ' """Log the output in the audit log, if it\'s enabled."""\n', ' if self.logfile:\n', ' click.echo(output, file=self.logfile)\n', '\n', ' def echo(self, s, **kwargs):\n', ' """Print a message to stdout.\n', '\n', ' The message will be logged in the audit log, if enabled.\n', '\n', ' All keyword arguments are passed to click.echo().\n', '\n', ' """\n', ' self.log_output(s)\n', ' click.secho(s, **kwargs)\n', '\n', ' def get_output_margin(self, status=None):\n', ' """Get the output margin (number of rows for the prompt, footer ' 'and\n', ' timing message."""\n', ' margin = self.get_reserved_space() + ' "self.get_prompt(self.prompt_format).count('\\n') + 1\n", ' if special.is_timing_enabled():\n', ' margin += 1\n', ' if status:\n', " margin += 1 + status.count('\\n')\n", '\n', ' return margin\n', '\n', '\n', ' def output(self, output, status=None):\n', ' """Output text to stdout or a pager command.\n', '\n', ' The status text is not outputted to pager or files.\n', '\n', ' The message will be logged in the audit log, if enabled. The\n', ' message will be written to the tee file, if enabled. The\n', ' message will be written to the output file, if enabled.\n', '\n', ' """\n', ' if output:\n', ' size = self.prompt_app.output.get_size()\n', '\n', ' margin = self.get_output_margin(status)\n', '\n', ' fits = True\n', ' buf = []\n', ' output_via_pager = self.explicit_pager and ' 'special.is_pager_enabled()\n', ' for i, line in enumerate(output, 1):\n', ' self.log_output(line)\n', ' special.write_tee(line)\n', ' special.write_once(line)\n', '\n', ' if fits or output_via_pager:\n', ' # buffering\n', ' buf.append(line)\n', ' if len(line) > size.columns or i > (size.rows - ' 'margin):\n', ' fits = False\n', ' if not self.explicit_pager and ' 'special.is_pager_enabled():\n', " # doesn't fit, use pager\n", ' output_via_pager = True\n', '\n', ' if not output_via_pager:\n', " # doesn't fit, flush buffer\n", ' for line in buf:\n', ' click.secho(line)\n', ' buf = []\n', ' else:\n', ' click.secho(line)\n', '\n', ' if buf:\n', ' if output_via_pager:\n', ' def newlinewrapper(text):\n', ' for line in text:\n', ' yield line + "\\n"\n', ' click.echo_via_pager(newlinewrapper(buf))\n', ' else:\n', ' for line in buf:\n', ' click.secho(line)\n', '\n', ' if status:\n', ' self.log_output(status)\n', ' click.secho(status)\n', '\n', ' def configure_pager(self):\n', ' # Provide sane defaults for less if they are empty.\n', " if not os.environ.get('LESS'):\n", " os.environ['LESS'] = '-RXF'\n", '\n', " cnf = self.read_my_cnf_files(self.cnf_files, ['pager', " "'skip-pager'])\n", " if cnf['pager']:\n", " special.set_pager(cnf['pager'])\n", ' self.explicit_pager = True\n', ' else:\n', ' self.explicit_pager = False\n', '\n', " if cnf['skip-pager'] or not " "self.config['main'].as_bool('enable_pager'):\n", ' special.disable_pager()\n', '\n', ' def refresh_completions(self, reset=False):\n', ' if reset:\n', ' with self._completer_lock:\n', ' self.completer.reset_completions()\n', ' self.completion_refresher.refresh(\n', ' self.sqlexecute, self._on_completions_refreshed,\n', " {'smart_completion': self.smart_completion,\n", " 'supported_formats': self.formatter.supported_formats,\n", " 'keyword_casing': self.completer.keyword_casing})\n", '\n', ' return [(None, None, None,\n', " 'Auto-completion refresh started in the background.')]\n", '\n', ' def _on_completions_refreshed(self, new_completer):\n', ' """Swap the completer object in cli with the newly created ' 'completer.\n', ' """\n', ' with self._completer_lock:\n', ' self.completer = new_completer\n', '\n', ' if self.prompt_app:\n', ' # After refreshing, redraw the CLI to clear the statusbar\n', ' # "Refreshing completions..." indicator\n', ' self.prompt_app.app.invalidate()\n', '\n', ' def get_completions(self, text, cursor_positition):\n', ' with self._completer_lock:\n', ' return self.completer.get_completions(\n', ' Document(text=text, cursor_position=cursor_positition), ' 'None)\n', '\n', ' def get_prompt(self, string):\n', ' sqlexecute = self.sqlexecute\n', ' host = self.login_path if self.login_path and ' 'self.login_path_as_host else sqlexecute.host\n', ' now = datetime.now()\n', " string = string.replace('\\\\u', sqlexecute.user or '(none)')\n", " string = string.replace('\\\\h', host or '(none)')\n", " string = string.replace('\\\\d', sqlexecute.dbname or '(none)')\n", " string = string.replace('\\\\t', sqlexecute.server_type()[0] or " "'mycli')\n", ' string = string.replace(\'\\\\n\', "\\n")\n', " string = string.replace('\\\\D', now.strftime('%a %b %d %H:%M:%S " "%Y'))\n", " string = string.replace('\\\\m', now.strftime('%M'))\n", " string = string.replace('\\\\P', now.strftime('%p'))\n", " string = string.replace('\\\\R', now.strftime('%H'))\n", " string = string.replace('\\\\r', now.strftime('%I'))\n", " string = string.replace('\\\\s', now.strftime('%S'))\n", " string = string.replace('\\\\p', str(sqlexecute.port))\n", " string = string.replace('\\\\A', self.dsn_alias or '(none)')\n", " string = string.replace('\\\\_', ' ')\n", ' return string\n', '\n', ' def run_query(self, query, new_line=True):\n', ' """Runs *query*."""\n', ' results = self.sqlexecute.run(query)\n', ' for result in results:\n', ' title, cur, headers, status = result\n', ' self.formatter.query = query\n', ' output = self.format_output(title, cur, headers)\n', ' for line in output:\n', ' click.echo(line, nl=new_line)\n', '\n', ' def format_output(self, title, cur, headers, expanded=False,\n', ' max_width=None):\n', " expanded = expanded or self.formatter.format_name == 'vertical'\n", ' output = []\n', '\n', ' output_kwargs = {\n', " 'dialect': 'unix',\n", " 'disable_numparse': True,\n", " 'preserve_whitespace': True,\n", " 'style': self.output_style\n", ' }\n', '\n', ' if not self.formatter.format_name in sql_format.supported_formats:\n', ' output_kwargs["preprocessors"] = (preprocessors.align_decimals, ' ')\n', '\n', " if title: # Only print the title if it's not None.\n", ' output = itertools.chain(output, [title])\n', '\n', ' if cur:\n', ' column_types = None\n', " if hasattr(cur, 'description'):\n", ' def get_col_type(col):\n', ' col_type = FIELD_TYPES.get(col[1], str)\n', ' return col_type if type(col_type) is type else str\n', ' column_types = [get_col_type(col) for col in ' 'cur.description]\n', '\n', ' if max_width is not None:\n', ' cur = list(cur)\n', '\n', ' formatted = self.formatter.format_output(\n', " cur, headers, format_name='vertical' if expanded else " 'None,\n', ' column_types=column_types,\n', ' **output_kwargs)\n', '\n', ' if isinstance(formatted, str):\n', ' formatted = formatted.splitlines()\n', ' formatted = iter(formatted)\n', '\n', ' if (not expanded and max_width and headers and cur):\n', ' first_line = next(formatted)\n', ' if len(strip_ansi(first_line)) > max_width:\n', ' formatted = self.formatter.format_output(\n', " cur, headers, format_name='vertical', " 'column_types=column_types, **output_kwargs)\n', ' if isinstance(formatted, str):\n', ' formatted = iter(formatted.splitlines())\n', ' else:\n', ' formatted = itertools.chain([first_line], formatted)\n', '\n', ' output = itertools.chain(output, formatted)\n', '\n', '\n', ' return output\n', '\n', ' def get_reserved_space(self):\n', ' """Get the number of lines to reserve for the completion menu."""\n', ' reserved_space_ratio = .45\n', ' max_reserved_space = 8\n', ' _, height = click.get_terminal_size()\n', ' return min(int(round(height * reserved_space_ratio)), ' 'max_reserved_space)\n', '\n', ' def get_last_query(self):\n', ' """Get the last query executed or None."""\n', ' return self.query_history[-1][0] if self.query_history else None\n', '\n', '\n', '@click.command()\n', "@click.option('-h', '--host', envvar='MYSQL_HOST', help='Host address of the " "database.')\n", "@click.option('-P', '--port', envvar='MYSQL_TCP_PORT', type=int, help='Port " "number to use for connection. Honors '\n", " '$MYSQL_TCP_PORT.')\n", "@click.option('-u', '--user', help='User name to connect to the " "database.')\n", "@click.option('-S', '--socket', envvar='MYSQL_UNIX_PORT', help='The socket " "file to use for connection.')\n", "@click.option('-p', '--password', 'password', envvar='MYSQL_PWD', " 'type=str,\n', " help='Password to connect to the database.')\n", "@click.option('--pass', 'password', envvar='MYSQL_PWD', type=str,\n", " help='Password to connect to the database.')\n", "@click.option('--ssh-user', help='User name to connect to ssh server.')\n", "@click.option('--ssh-host', help='Host name to connect to ssh server.')\n", "@click.option('--ssh-port', default=22, help='Port to connect to ssh " "server.')\n", "@click.option('--ssh-password', help='Password to connect to ssh server.')\n", "@click.option('--ssh-key-filename', help='Private key filename (identify " "file) for the ssh connection.')\n", "@click.option('--ssh-config-path', help='Path to ssh configuration.',\n", " default=os.path.expanduser('~') + '/.ssh/config')\n", "@click.option('--ssh-config-host', help='Host to connect to ssh server " "reading from ssh configuration.')\n", "@click.option('--ssl-ca', help='CA file in PEM format.',\n", ' type=click.Path(exists=True))\n', "@click.option('--ssl-capath', help='CA directory.')\n", "@click.option('--ssl-cert', help='X509 cert in PEM format.',\n", ' type=click.Path(exists=True))\n', "@click.option('--ssl-key', help='X509 key in PEM format.',\n", ' type=click.Path(exists=True))\n', "@click.option('--ssl-cipher', help='SSL cipher to use.')\n", "@click.option('--ssl-verify-server-cert', is_flag=True,\n", ' help=(\'Verify server\\\'s "Common Name" in its cert against ' "'\n", " 'hostname used when connecting. This option is disabled " "'\n", " 'by default.'))\n", '# as of 2016-02-15 revocation list is not supported by underling PyMySQL\n', '# library (--ssl-crl and --ssl-crlpath options in vanilla mysql client)\n', "@click.option('-V', '--version', is_flag=True, help='Output mycli\\'s " "version.')\n", "@click.option('-v', '--verbose', is_flag=True, help='Verbose output.')\n", "@click.option('-D', '--database', 'dbname', help='Database to use.')\n", "@click.option('-d', '--dsn', default='', envvar='DSN',\n", " help='Use DSN configured into the [alias_dsn] section of " "myclirc file.')\n", "@click.option('--list-dsn', 'list_dsn', is_flag=True,\n", " help='list of DSN configured into the [alias_dsn] section of myclirc " "file.')\n", "@click.option('--list-ssh-config', 'list_ssh_config', is_flag=True,\n", " help='list ssh configurations in the ssh config (requires " "paramiko).')\n", "@click.option('-R', '--prompt', 'prompt',\n", ' help=\'Prompt format (Default: "{0}").\'.format(\n', ' MyCli.default_prompt))\n', "@click.option('-l', '--logfile', type=click.File(mode='a', " "encoding='utf-8'),\n", " help='Log every query and its results to a file.')\n", "@click.option('--defaults-group-suffix', type=str,\n", " help='Read MySQL config groups with the specified suffix.')\n", "@click.option('--defaults-file', type=click.Path(),\n", " help='Only read MySQL options from the given file.')\n", '@click.option(\'--myclirc\', type=click.Path(), default="~/.myclirc",\n', " help='Location of myclirc file.')\n", "@click.option('--auto-vertical-output', is_flag=True,\n", " help='Automatically switch to vertical output mode if the " "result is wider than the terminal width.')\n", "@click.option('-t', '--table', is_flag=True,\n", " help='Display batch output in table format.')\n", "@click.option('--csv', is_flag=True,\n", " help='Display batch output in CSV format.')\n", "@click.option('--warn/--no-warn', default=None,\n", " help='Warn before running a destructive query.')\n", "@click.option('--local-infile', type=bool,\n", " help='Enable/disable LOAD DATA LOCAL INFILE.')\n", "@click.option('--login-path', type=str,\n", " help='Read this path from the login file.')\n", "@click.option('-e', '--execute', type=str,\n", " help='Execute command and quit.')\n", "@click.option('--init-command', type=str,\n", " help='SQL statement to execute after connecting.')\n", "@click.argument('database', default='', nargs=1)\n", 'def cli(database, user, host, port, socket, password, dbname,\n', ' version, verbose, prompt, logfile, defaults_group_suffix,\n', ' defaults_file, login_path, auto_vertical_output, local_infile,\n', ' ssl_ca, ssl_capath, ssl_cert, ssl_key, ssl_cipher,\n', ' ssl_verify_server_cert, table, csv, warn, execute, myclirc, dsn,\n', ' list_dsn, ssh_user, ssh_host, ssh_port, ssh_password,\n', ' ssh_key_filename, list_ssh_config, ssh_config_path, ' 'ssh_config_host,\n', ' init_command):\n', ' """A MySQL terminal client with auto-completion and syntax ' 'highlighting.\n', '\n', ' \\b\n', ' Examples:\n', ' - mycli my_database\n', ' - mycli -u my_user -h my_host.com my_database\n', ' - mycli mysql://my_user@my_host.com:3306/my_database\n', '\n', ' """\n', '\n', ' if version:\n', " print('Version:', __version__)\n", ' sys.exit(0)\n', '\n', ' mycli = MyCli(prompt=prompt, logfile=logfile,\n', ' defaults_suffix=defaults_group_suffix,\n', ' defaults_file=defaults_file, login_path=login_path,\n', ' auto_vertical_output=auto_vertical_output, warn=warn,\n', ' myclirc=myclirc)\n', ' if list_dsn:\n', ' try:\n', " alias_dsn = mycli.config['alias_dsn']\n", ' except KeyError as err:\n', " click.secho('Invalid DSNs found in the config file. '\\\n", ' \'Please check the "[alias_dsn]" section in myclirc.\',\n', " err=True, fg='red')\n", ' exit(1)\n', ' except Exception as e:\n', " click.secho(str(e), err=True, fg='red')\n", ' exit(1)\n', ' for alias, value in alias_dsn.items():\n', ' if verbose:\n', ' click.secho("{} : {}".format(alias, value))\n', ' else:\n', ' click.secho(alias)\n', ' sys.exit(0)\n', ' if list_ssh_config:\n', ' ssh_config = read_ssh_config(ssh_config_path)\n', ' for host in ssh_config.get_hostnames():\n', ' if verbose:\n', ' host_config = ssh_config.lookup(host)\n', ' click.secho("{} : {}".format(\n', " host, host_config.get('hostname')))\n", ' else:\n', ' click.secho(host)\n', ' sys.exit(0)\n', ' # Choose which ever one has a valid value.\n', ' database = dbname or database\n', '\n', ' ssl = {\n', " 'ca': ssl_ca and os.path.expanduser(ssl_ca),\n", " 'cert': ssl_cert and os.path.expanduser(ssl_cert),\n", " 'key': ssl_key and os.path.expanduser(ssl_key),\n", " 'capath': ssl_capath,\n", " 'cipher': ssl_cipher,\n", " 'check_hostname': ssl_verify_server_cert,\n", ' }\n', '\n', ' # remove empty ssl options\n', ' ssl = {k: v for k, v in ssl.items() if v is not None}\n', '\n', ' dsn_uri = None\n', '\n', " # Treat the database argument as a DSN alias if we're missing\n", ' # other connection information.\n', " if (mycli.config['alias_dsn'] and database and '://' not in database\n", ' and not any([user, password, host, port, login_path])):\n', " dsn, database = database, ''\n", '\n', " if database and '://' in database:\n", " dsn_uri, database = database, ''\n", '\n', ' if dsn:\n', ' try:\n', " dsn_uri = mycli.config['alias_dsn'][dsn]\n", ' except KeyError:\n', " click.secho('Could not find the specified DSN in the config " "file. '\n", ' \'Please check the "[alias_dsn]" section in your ' "'\n", " 'myclirc.', err=True, fg='red')\n", ' exit(1)\n', ' else:\n', ' mycli.dsn_alias = dsn\n', '\n', ' if dsn_uri:\n', ' uri = urlparse(dsn_uri)\n', ' if not database:\n', ' database = uri.path[1:] # ignore the leading fwd slash\n', ' if not user:\n', ' user = unquote(uri.username)\n', ' if not password and uri.password is not None:\n', ' password = unquote(uri.password)\n', ' if not host:\n', ' host = uri.hostname\n', ' if not port:\n', ' port = uri.port\n', '\n', ' if ssh_config_host:\n', ' ssh_config = read_ssh_config(\n', ' ssh_config_path\n', ' ).lookup(ssh_config_host)\n', " ssh_host = ssh_host if ssh_host else ssh_config.get('hostname')\n", " ssh_user = ssh_user if ssh_user else ssh_config.get('user')\n", " if ssh_config.get('port') and ssh_port == 22:\n", " # port has a default value, overwrite it if it's in the config\n", " ssh_port = int(ssh_config.get('port'))\n", ' ssh_key_filename = ssh_key_filename if ssh_key_filename else ' 'ssh_config.get(\n', " 'identityfile', [None])[0]\n", '\n', ' ssh_key_filename = ssh_key_filename and ' 'os.path.expanduser(ssh_key_filename)\n', '\n', ' mycli.connect(\n', ' database=database,\n', ' user=user,\n', ' passwd=password,\n', ' host=host,\n', ' port=port,\n', ' socket=socket,\n', ' local_infile=local_infile,\n', ' ssl=ssl,\n', ' ssh_user=ssh_user,\n', ' ssh_host=ssh_host,\n', ' ssh_port=ssh_port,\n', ' ssh_password=ssh_password,\n', ' ssh_key_filename=ssh_key_filename,\n', ' init_command=init_command\n', ' )\n', '\n', " mycli.logger.debug('Launch Params: \\n'\n", " '\\tdatabase: %r'\n", " '\\tuser: %r'\n", " '\\thost: %r'\n", " '\\tport: %r', database, user, host, port)\n", '\n', ' # --execute argument\n', ' if execute:\n', ' try:\n', ' if csv:\n', " mycli.formatter.format_name = 'csv'\n", ' elif not table:\n', " mycli.formatter.format_name = 'tsv'\n", '\n', ' mycli.run_query(execute)\n', ' exit(0)\n', ' except Exception as e:\n', " click.secho(str(e), err=True, fg='red')\n", ' exit(1)\n', '\n', ' if sys.stdin.isatty():\n', ' mycli.run_cli()\n', ' else:\n', " stdin = click.get_text_stream('stdin')\n", ' try:\n', ' stdin_text = stdin.read()\n', ' except MemoryError:\n', " click.secho('Failed! Ran out of memory.', err=True, fg='red')\n", " click.secho('You might want to try the official mysql client.', " "err=True, fg='red')\n", " click.secho('Sorry... :(', err=True, fg='red')\n", ' exit(1)\n', '\n', ' try:\n', " sys.stdin = open('/dev/tty')\n", ' except (IOError, OSError):\n', " mycli.logger.warning('Unable to open TTY as stdin.')\n", '\n', ' if (mycli.destructive_warning and\n', ' confirm_destructive_query(stdin_text) is False):\n', ' exit(0)\n', ' try:\n', ' new_line = True\n', '\n', ' if csv:\n', " mycli.formatter.format_name = 'csv'\n", ' elif not table:\n', " mycli.formatter.format_name = 'tsv'\n", '\n', ' mycli.run_query(stdin_text, new_line=new_line)\n', ' exit(0)\n', ' except Exception as e:\n', " click.secho(str(e), err=True, fg='red')\n", ' exit(1)\n', '\n', '\n', 'def need_completion_refresh(queries):\n', ' """Determines if the completion needs a refresh by checking if the sql\n', ' statement is an alter, create, drop or change db."""\n', ' for query in sqlparse.split(queries):\n', ' try:\n', ' first_token = query.split()[0]\n', " if first_token.lower() in ('alter', 'create', 'use', '\\\\r',\n", " '\\\\u', 'connect', 'drop', " "'rename'):\n", ' return True\n', ' except Exception:\n', ' return False\n', '\n', '\n', 'def need_completion_reset(queries):\n', ' """Determines if the statement is a database switch such as \'use\' or ' "'\\\\u'.\n", ' When a database is changed the existing completions must be reset before ' 'we\n', ' start the completion refresh for the new database.\n', ' """\n', ' for query in sqlparse.split(queries):\n', ' try:\n', ' first_token = query.split()[0]\n', " if first_token.lower() in ('use', '\\\\u'):\n", ' return True\n', ' except Exception:\n', ' return False\n', '\n', '\n', 'def is_mutating(status):\n', ' """Determines if the statement is mutating based on the status."""\n', ' if not status:\n', ' return False\n', '\n', " mutating = set(['insert', 'update', 'delete', 'alter', 'create', " "'drop',\n", " 'replace', 'truncate', 'load', 'rename'])\n", ' return status.split(None, 1)[0].lower() in mutating\n', '\n', '\n', 'def is_select(status):\n', ' """Returns true if the first word in status is \'select\'."""\n', ' if not status:\n', ' return False\n', " return status.split(None, 1)[0].lower() == 'select'\n", '\n', '\n', 'def thanks_picker(files=()):\n', ' contents = []\n', ' for line in fileinput.input(files=files):\n', " m = re.match('^ *\\* (.*)', line)\n", ' if m:\n', ' contents.append(m.group(1))\n', ' return choice(contents)\n', '\n', '\n', "@prompt_register('edit-and-execute-command')\n", 'def edit_and_execute(event):\n', ' """Different from the prompt-toolkit default, we want to have a choice ' 'not\n', ' to execute a query after editing, hence validate_and_handle=False."""\n', ' buff = event.current_buffer\n', ' buff.open_in_editor(validate_and_handle=False)\n', '\n', '\n', 'def read_ssh_config(ssh_config_path):\n', ' ssh_config = paramiko.config.SSHConfig()\n', ' try:\n', ' with open(ssh_config_path) as f:\n', ' ssh_config.parse(f)\n', ' # Paramiko prior to version 2.7 raises Exception on parse errors.\n', ' # In 2.7 it has become paramiko.ssh_exception.SSHException,\n', " # but let's catch everything for compatibility\n", ' except Exception as err:\n', ' click.secho(\n', " f'Could not parse SSH configuration file " "{ssh_config_path}:\\n{err} ',\n", " err=True, fg='red'\n", ' )\n', ' sys.exit(1)\n', ' except FileNotFoundError as e:\n', " click.secho(str(e), err=True, fg='red')\n", ' sys.exit(1)\n', ' else:\n', ' return ssh_config\n', '\n', '\n', 'if __name__ == "__main__":\n', ' cli()\n'] tests = [] /usr/lib/python3.8/doctest.py:998: in _find if ((inspect.isroutine(inspect.unwrap(val)) globs = {'AutoSuggestFromHistory': , 'CompleteStyle': , 'CompletionRefresher': , 'ConditionalProcessor': , 'DEFAULT_BUFFER': 'DEFAULT_BUFFER', 'Document': , 'DynamicCompleter': , 'EditingMode': , 'FIELD_TYPES': {0: , 1: , 2: , 3: , 4: , 5: , 6: , 7: , 8: , 9: , 10: , 11: , 12: , 13: , 15: , 16: , 246: , 249: , 250: , 251: , 252: , 253: , 254: }, 'FavoriteQueries': , 'FileHistory': , 'HasFocus': , 'HighlightMatchingBracketProcessor': , 'IsDone': at 0x7f26ad7b0310>, 'MyCli': , 'MyCliLexer': , 'NO_QUERY': 0, 'OperationalError': , 'PACKAGE_ROOT': '/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli', 'PromptSession': , 'PygmentsLexer': , 'Query': , 'SQLCompleter': , 'SQLExecute': , 'TabularOutputFormatter': , 'WIN': False, '__builtins__': {'ArithmeticError': , 'AssertionError': , 'AttributeError': , 'BaseException': , 'BlockingIOError': , 'BrokenPipeError': , 'BufferError': , 'BytesWarning': , 'ChildProcessError': , 'ConnectionAbortedError': , 'ConnectionError': , 'ConnectionRefusedError': , 'ConnectionResetError': , 'DeprecationWarning': , 'EOFError': , 'Ellipsis': Ellipsis, 'EnvironmentError': , 'Exception': , 'False': False, 'FileExistsError': , 'FileNotFoundError': , 'FloatingPointError': , 'FutureWarning': , 'GeneratorExit': , 'IOError': , 'ImportError': , 'ImportWarning': , 'IndentationError': , 'IndexError': , 'InterruptedError': , 'IsADirectoryError': , 'KeyError': , 'KeyboardInterrupt': , 'LookupError': , 'MemoryError': , 'ModuleNotFoundError': , 'NameError': , 'None': None, 'NotADirectoryError': , 'NotImplemented': NotImplemented, 'NotImplementedError': , 'OSError': , 'OverflowError': , 'PendingDeprecationWarning': , 'PermissionError': , 'ProcessLookupError': , 'RecursionError': , 'ReferenceError': , 'ResourceWarning': , 'RuntimeError': , 'RuntimeWarning': , 'StopAsyncIteration': , 'StopIteration': , 'SyntaxError': , 'SyntaxWarning': , 'SystemError': , 'SystemExit': , 'TabError': , 'TimeoutError': , 'True': True, 'TypeError': , 'UnboundLocalError': , 'UnicodeDecodeError': , 'UnicodeEncodeError': , 'UnicodeError': , 'UnicodeTranslateError': , 'UnicodeWarning': , 'UserWarning': , 'ValueError': , 'Warning': , 'ZeroDivisionError': , '__build_class__': , '__debug__': True, '__doc__': 'Built-in functions, exceptions, and other ' 'objects.\n' '\n' "Noteworthy: None is the `nil' object; Ellipsis " "represents `...' in slices.", '__import__': , '__loader__': , '__name__': 'builtins', '__package__': '', '__spec__': ModuleSpec(name='builtins', loader=), 'abs': , 'all': , 'any': , 'ascii': , 'bin': , 'bool': , 'breakpoint': , 'bytearray': , 'bytes': , 'callable': , 'chr': , 'classmethod': , 'compile': , 'complex': , 'copyright': Copyright (c) 2001-2021 Python Software Foundation. All Rights Reserved. Copyright (c) 2000 BeOpen.com. All Rights Reserved. Copyright (c) 1995-2001 Corporation for National Research Initiatives. All Rights Reserved. Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam. All Rights Reserved., 'credits': Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands for supporting Python development. See www.python.org for more information., 'delattr': , 'dict': , 'dir': , 'divmod': , 'enumerate': , 'eval': , 'exec': , 'exit': Use exit() or Ctrl-D (i.e. EOF) to exit, 'filter': , 'float': , 'format': , 'frozenset': , 'getattr': , 'globals': , 'hasattr': , 'hash': , 'help': Type help() for interactive help, or help(object) for help about object., 'hex': , 'id': , 'input': , 'int': , 'isinstance': , 'issubclass': , 'iter': , 'len': , 'license': Type license() to see the full license text, 'list': , 'locals': , 'map': , 'max': , 'memoryview': , 'min': , 'next': , 'object': , 'oct': , 'open': , 'ord': , 'pow': , 'print': , 'property': , 'quit': Use quit() or Ctrl-D (i.e. EOF) to exit, 'range': , 'repr': , 'reversed': , 'round': , 'set': , 'setattr': , 'slice': , 'sorted': , 'staticmethod': , 'str': , 'sum': , 'super': , 'tuple': , 'type': , 'vars': , 'zip': }, '__cached__': '/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/__pycache__/main.cpython-38.pyc', '__doc__': None, '__file__': '/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/main.py', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f26adfaf640>, '__name__': 'mycli.main', '__package__': 'mycli', '__spec__': ModuleSpec(name='mycli.main', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7f26adfaf640>, origin='/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/main.py'), '__version__': '1.22.2', 'choice': >, 'cli': , 'cli_is_multiline': , 'click': , 'confirm': , 'confirm_destructive_query': , 'create_toolbar_tokens_func': , 'datetime': , 'dir_path_exists': , 'edit_and_execute': , 'fileinput': , 'get_mylogin_cnf_path': , 'getpwuid': , 'guess_socket_location': , 'is_dropping_database': , 'is_mutating': , 'is_select': , 'itertools': , 'logging': , 'mycli_bindings': , 'namedtuple': , 'need_completion_refresh': , 'need_completion_reset': , 'open': , 'open_mylogin_cnf': , 'os': , 'paramiko': , 'preprocessors': , 'prompt_register': , 're': , 'read_config_files': , 'read_ssh_config': , 'special': , 'sql_format': , 'sqlparse': , 'str_to_bool': , 'strip_ansi': , 'strip_matching_quotes': , 'style_factory': , 'style_factory_output': , 'sys': , 'thanks_picker': , 'threading': , 'time': , 'traceback': , 'unquote': , 'urlparse': , 'write_default_config': } module = name = 'mycli.main' obj = seen = {139804099906032: 1} self = <_pytest.doctest.DoctestModule.collect..MockAwareDocTestFinder object at 0x7f26ad21d910> source_lines = ['import os\n', 'import sys\n', 'import traceback\n', 'import logging\n', 'import threading\n', 'import re\n', 'import fileinput\n', 'from collections import namedtuple\n', 'try:\n', ' from pwd import getpwuid\n', 'except ImportError:\n', ' pass\n', 'from time import time\n', 'from datetime import datetime\n', 'from random import choice\n', 'from io import open\n', '\n', 'from pymysql import OperationalError\n', 'from cli_helpers.tabular_output import TabularOutputFormatter\n', 'from cli_helpers.tabular_output import preprocessors\n', 'from cli_helpers.utils import strip_ansi\n', 'import click\n', 'import sqlparse\n', 'from mycli.packages.parseutils import is_dropping_database\n', 'from prompt_toolkit.completion import DynamicCompleter\n', 'from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode\n', 'from prompt_toolkit.key_binding.bindings.named_commands import register as ' 'prompt_register\n', 'from prompt_toolkit.shortcuts import PromptSession, CompleteStyle\n', 'from prompt_toolkit.document import Document\n', 'from prompt_toolkit.filters import HasFocus, IsDone\n', 'from prompt_toolkit.layout.processors import ' '(HighlightMatchingBracketProcessor,\n', ' ConditionalProcessor)\n', 'from prompt_toolkit.lexers import PygmentsLexer\n', 'from prompt_toolkit.history import FileHistory\n', 'from prompt_toolkit.auto_suggest import AutoSuggestFromHistory\n', '\n', 'from .packages.special.main import NO_QUERY\n', 'from .packages.prompt_utils import confirm, confirm_destructive_query\n', 'from .packages.tabular_output import sql_format\n', 'from .packages import special\n', 'from .packages.special.favoritequeries import FavoriteQueries\n', 'from .sqlcompleter import SQLCompleter\n', 'from .clitoolbar import create_toolbar_tokens_func\n', 'from .clistyle import style_factory, style_factory_output\n', 'from .sqlexecute import FIELD_TYPES, SQLExecute\n', 'from .clibuffer import cli_is_multiline\n', 'from .completion_refresher import CompletionRefresher\n', 'from .config import (write_default_config, get_mylogin_cnf_path,\n', ' open_mylogin_cnf, read_config_files, str_to_bool,\n', ' strip_matching_quotes)\n', 'from .key_bindings import mycli_bindings\n', 'from .lexer import MyCliLexer\n', 'from .__init__ import __version__\n', 'from .compat import WIN\n', 'from .packages.filepaths import dir_path_exists, guess_socket_location\n', '\n', 'import itertools\n', '\n', 'click.disable_unicode_literals_warning = True\n', '\n', 'try:\n', ' from urlparse import urlparse\n', ' from urlparse import unquote\n', 'except ImportError:\n', ' from urllib.parse import urlparse\n', ' from urllib.parse import unquote\n', '\n', '\n', 'try:\n', ' import paramiko\n', 'except ImportError:\n', ' from mycli.packages.paramiko_stub import paramiko\n', '\n', '# Query tuples are used for maintaining history\n', "Query = namedtuple('Query', ['query', 'successful', 'mutating'])\n", '\n', 'PACKAGE_ROOT = os.path.abspath(os.path.dirname(__file__))\n', '\n', '\n', 'class MyCli(object):\n', '\n', " default_prompt = '\\\\t \\\\u@\\\\h:\\\\d> '\n", ' max_len_prompt = 45\n', ' defaults_suffix = None\n', '\n', ' # In order of being loaded. Files lower in list override earlier ones.\n', ' cnf_files = [\n', " '/etc/my.cnf',\n", " '/etc/mysql/my.cnf',\n", " '/usr/local/etc/my.cnf',\n", " '~/.my.cnf'\n", ' ]\n', '\n', ' # check XDG_CONFIG_HOME exists and not an empty string\n', ' if os.environ.get("XDG_CONFIG_HOME"):\n', ' xdg_config_home = os.environ.get("XDG_CONFIG_HOME")\n', ' else:\n', ' xdg_config_home = "~/.config"\n', ' system_config_files = [\n', " '/etc/myclirc',\n", ' os.path.join(os.path.expanduser(xdg_config_home), "mycli", ' '"myclirc")\n', ' ]\n', '\n', " default_config_file = os.path.join(PACKAGE_ROOT, 'myclirc')\n", ' pwd_config_file = os.path.join(os.getcwd(), ".myclirc")\n', '\n', ' def __init__(self, sqlexecute=None, prompt=None,\n', ' logfile=None, defaults_suffix=None, defaults_file=None,\n', ' login_path=None, auto_vertical_output=False, warn=None,\n', ' myclirc="~/.myclirc"):\n', ' self.sqlexecute = sqlexecute\n', ' self.logfile = logfile\n', ' self.defaults_suffix = defaults_suffix\n', ' self.login_path = login_path\n', '\n', ' # self.cnf_files is a class variable that stores the list of mysql\n', ' # config files to read in at launch.\n', ' # If defaults_file is specified then override the class variable ' 'with\n', ' # defaults_file.\n', ' if defaults_file:\n', ' self.cnf_files = [defaults_file]\n', '\n', ' # Load config.\n', ' config_files = ([self.default_config_file] + ' 'self.system_config_files +\n', ' [myclirc] + [self.pwd_config_file])\n', ' c = self.config = read_config_files(config_files)\n', " self.multi_line = c['main'].as_bool('multi_line')\n", " self.key_bindings = c['main']['key_bindings']\n", " special.set_timing_enabled(c['main'].as_bool('timing'))\n", '\n', ' FavoriteQueries.instance = ' 'FavoriteQueries.from_config(self.config)\n', '\n', ' self.dsn_alias = None\n', ' self.formatter = TabularOutputFormatter(\n', " format_name=c['main']['table_format'])\n", ' sql_format.register_new_formatter(self.formatter)\n', ' self.formatter.mycli = self\n', " self.syntax_style = c['main']['syntax_style']\n", " self.less_chatty = c['main'].as_bool('less_chatty')\n", " self.cli_style = c['colors']\n", ' self.output_style = style_factory_output(\n', ' self.syntax_style,\n', ' self.cli_style\n', ' )\n', ' self.wider_completion_menu = ' "c['main'].as_bool('wider_completion_menu')\n", " c_dest_warning = c['main'].as_bool('destructive_warning')\n", ' self.destructive_warning = c_dest_warning if warn is None else ' 'warn\n', " self.login_path_as_host = c['main'].as_bool('login_path_as_host')\n", '\n', ' # read from cli argument or user config file\n', ' self.auto_vertical_output = auto_vertical_output or \\\n', " c['main'].as_bool('auto_vertical_output')\n", '\n', " # Write user config if system config wasn't the last config " 'loaded.\n', ' if c.filename not in self.system_config_files and not ' 'os.path.exists(myclirc):\n', ' write_default_config(self.default_config_file, myclirc)\n', '\n', ' # audit log\n', " if self.logfile is None and 'audit_log' in c['main']:\n", ' try:\n', ' self.logfile = ' "open(os.path.expanduser(c['main']['audit_log']), 'a')\n", ' except (IOError, OSError) as e:\n', " self.echo('Error: Unable to open the audit log file. Your " "queries will not be logged.',\n", " err=True, fg='red')\n", ' self.logfile = False\n', '\n', ' self.completion_refresher = CompletionRefresher()\n', '\n', ' self.logger = logging.getLogger(__name__)\n', ' self.initialize_logging()\n', '\n', ' prompt_cnf = self.read_my_cnf_files(self.cnf_files, ' "['prompt'])['prompt']\n", " self.prompt_format = prompt or prompt_cnf or c['main']['prompt'] or " '\\\n', ' self.default_prompt\n', ' self.multiline_continuation_char = ' "c['main']['prompt_continuation']\n", " keyword_casing = c['main'].get('keyword_casing', 'auto')\n", '\n', ' self.query_history = []\n', '\n', ' # Initialize completer.\n', " self.smart_completion = c['main'].as_bool('smart_completion')\n", ' self.completer = SQLCompleter(\n', ' self.smart_completion,\n', ' supported_formats=self.formatter.supported_formats,\n', ' keyword_casing=keyword_casing)\n', ' self._completer_lock = threading.Lock()\n', '\n', ' # Register custom special commands.\n', ' self.register_special_commands()\n', '\n', ' # Load .mylogin.cnf if it exists.\n', ' mylogin_cnf_path = get_mylogin_cnf_path()\n', ' if mylogin_cnf_path:\n', ' mylogin_cnf = open_mylogin_cnf(mylogin_cnf_path)\n', ' if mylogin_cnf_path and mylogin_cnf:\n', ' # .mylogin.cnf gets read last, even if defaults_file is ' 'specified.\n', ' self.cnf_files.append(mylogin_cnf)\n', ' elif mylogin_cnf_path and not mylogin_cnf:\n', ' # There was an error reading the login path file.\n', " print('Error: Unable to read login path file.')\n", '\n', ' self.prompt_app = None\n', '\n', ' def register_special_commands(self):\n', " special.register_special_command(self.change_db, 'use',\n", " '\\\\u', 'Change to a new database.', aliases=('\\\\u',))\n", " special.register_special_command(self.change_db, 'connect',\n", " '\\\\r', 'Reconnect to the database. Optional database " "argument.',\n", " aliases=('\\\\r', ), case_sensitive=True)\n", ' special.register_special_command(self.refresh_completions, ' "'rehash',\n", " '\\\\#', 'Refresh auto-completions.', arg_type=NO_QUERY, " "aliases=('\\\\#',))\n", ' special.register_special_command(\n', " self.change_table_format, 'tableformat', '\\\\T',\n", " 'Change the table format used to output results.',\n", " aliases=('\\\\T',), case_sensitive=True)\n", " special.register_special_command(self.execute_from_file, 'source', " "'\\\\. filename',\n", " 'Execute commands from file.', " "aliases=('\\\\.',))\n", ' special.register_special_command(self.change_prompt_format, ' "'prompt',\n", " '\\\\R', 'Change prompt format.', aliases=('\\\\R',), " 'case_sensitive=True)\n', '\n', ' def change_table_format(self, arg, **_):\n', ' try:\n', ' self.formatter.format_name = arg\n', ' yield (None, None, None,\n', " 'Changed table format to {}'.format(arg))\n", ' except ValueError:\n', " msg = 'Table format {} not recognized. Allowed " "formats:'.format(\n", ' arg)\n', ' for table_type in self.formatter.supported_formats:\n', ' msg += "\\n\\t{}".format(table_type)\n', ' yield (None, None, None, msg)\n', '\n', ' def change_db(self, arg, **_):\n', ' if not arg:\n', ' click.secho(\n', ' "No database selected",\n', ' err=True, fg="red"\n', ' )\n', ' return\n', '\n', ' self.sqlexecute.change_db(arg)\n', '\n', ' yield (None, None, None, \'You are now connected to database "%s" as ' "'\n", ' \'user "%s"\' % (self.sqlexecute.dbname, ' 'self.sqlexecute.user))\n', '\n', ' def execute_from_file(self, arg, **_):\n', ' if not arg:\n', " message = 'Missing required argument, filename.'\n", ' return [(None, None, None, message)]\n', ' try:\n', ' with open(os.path.expanduser(arg)) as f:\n', ' query = f.read()\n', ' except IOError as e:\n', ' return [(None, None, None, str(e))]\n', '\n', ' if (self.destructive_warning and\n', ' confirm_destructive_query(query) is False):\n', " message = 'Wise choice. Command execution stopped.'\n", ' return [(None, None, None, message)]\n', '\n', ' return self.sqlexecute.run(query)\n', '\n', ' def change_prompt_format(self, arg, **_):\n', ' """\n', ' Change the prompt format.\n', ' """\n', ' if not arg:\n', " message = 'Missing required argument, format.'\n", ' return [(None, None, None, message)]\n', '\n', ' self.prompt_format = self.get_prompt(arg)\n', ' return [(None, None, None, "Changed prompt format to %s" % arg)]\n', '\n', ' def initialize_logging(self):\n', '\n', " log_file = os.path.expanduser(self.config['main']['log_file'])\n", " log_level = self.config['main']['log_level']\n", '\n', " level_map = {'CRITICAL': logging.CRITICAL,\n", " 'ERROR': logging.ERROR,\n", " 'WARNING': logging.WARNING,\n", " 'INFO': logging.INFO,\n", " 'DEBUG': logging.DEBUG\n", ' }\n', '\n', ' # Disable logging if value is NONE by switching to a no-op handler\n', " # Set log level to a high value so it doesn't even waste cycles " 'getting called.\n', ' if log_level.upper() == "NONE":\n', ' handler = logging.NullHandler()\n', ' log_level = "CRITICAL"\n', ' elif dir_path_exists(log_file):\n', ' handler = logging.FileHandler(log_file)\n', ' else:\n', ' self.echo(\n', " 'Error: Unable to open the log file " '"{}".\'.format(log_file),\n', " err=True, fg='red')\n", ' return\n', '\n', ' formatter = logging.Formatter(\n', " '%(asctime)s (%(process)d/%(threadName)s) '\n", " '%(name)s %(levelname)s - %(message)s')\n", '\n', ' handler.setFormatter(formatter)\n', '\n', " root_logger = logging.getLogger('mycli')\n", ' root_logger.addHandler(handler)\n', ' root_logger.setLevel(level_map[log_level.upper()])\n', '\n', ' logging.captureWarnings(True)\n', '\n', " root_logger.debug('Initializing mycli logging.')\n", " root_logger.debug('Log file %r.', log_file)\n", '\n', '\n', ' def read_my_cnf_files(self, files, keys):\n', ' """\n', ' Reads a list of config files and merges them. The last one will ' 'win.\n', ' :param files: list of files to read\n', ' :param keys: list of keys to retrieve\n', ' :returns: tuple, with None for missing keys.\n', ' """\n', ' cnf = read_config_files(files, list_values=False)\n', '\n', " sections = ['client', 'mysqld']\n", " if self.login_path and self.login_path != 'client':\n", ' sections.append(self.login_path)\n', '\n', ' if self.defaults_suffix:\n', ' sections.extend([sect + self.defaults_suffix for sect in ' 'sections])\n', '\n', ' def get(key):\n', ' result = None\n', ' for sect in cnf:\n', ' if sect in sections and key in cnf[sect]:\n', ' result = strip_matching_quotes(cnf[sect][key])\n', ' return result\n', '\n', ' return {x: get(x) for x in keys}\n', '\n', ' def merge_ssl_with_cnf(self, ssl, cnf):\n', ' """Merge SSL configuration dict with cnf dict"""\n', '\n', ' merged = {}\n', ' merged.update(ssl)\n', " prefix = 'ssl-'\n", ' for k, v in cnf.items():\n', ' # skip unrelated options\n', ' if not k.startswith(prefix):\n', ' continue\n', ' if v is None:\n', ' continue\n', ' # special case because PyMySQL argument is significantly ' 'different\n', ' # from commandline\n', " if k == 'ssl-verify-server-cert':\n", " merged['check_hostname'] = v\n", ' else:\n', ' # use argument name just strip "ssl-" prefix\n', ' arg = k[len(prefix):]\n', ' merged[arg] = v\n', '\n', ' return merged\n', '\n', " def connect(self, database='', user='', passwd='', host='', port='',\n", " socket='', charset='', local_infile='', ssl='',\n", " ssh_user='', ssh_host='', ssh_port='',\n", " ssh_password='', ssh_key_filename='', init_command=''):\n", '\n', " cnf = {'database': None,\n", " 'user': None,\n", " 'password': None,\n", " 'host': None,\n", " 'port': None,\n", " 'socket': None,\n", " 'default-character-set': None,\n", " 'local-infile': None,\n", " 'loose-local-infile': None,\n", " 'ssl-ca': None,\n", " 'ssl-cert': None,\n", " 'ssl-key': None,\n", " 'ssl-cipher': None,\n", " 'ssl-verify-serer-cert': None,\n", ' }\n', '\n', ' cnf = self.read_my_cnf_files(self.cnf_files, cnf.keys())\n', '\n', ' # Fall back to config values only if user did not specify a value.\n', '\n', " database = database or cnf['database']\n", ' # Socket interface not supported for SSH connections\n', ' if port or host or ssh_host or ssh_port:\n', " socket = ''\n", ' else:\n', " socket = socket or cnf['socket'] or guess_socket_location()\n", " user = user or cnf['user'] or os.getenv('USER')\n", " host = host or cnf['host']\n", " port = port or cnf['port']\n", ' ssl = ssl or {}\n', '\n', " passwd = passwd if isinstance(passwd, str) else cnf['password']\n", " charset = charset or cnf['default-character-set'] or 'utf8'\n", '\n', ' # Favor whichever local_infile option is set.\n', " for local_infile_option in (local_infile, cnf['local-infile'],\n", " cnf['loose-local-infile'], False):\n", ' try:\n', ' local_infile = str_to_bool(local_infile_option)\n', ' break\n', ' except (TypeError, ValueError):\n', ' pass\n', '\n', ' ssl = self.merge_ssl_with_cnf(ssl, cnf)\n', ' # prune lone check_hostname=False\n', ' if not any(v for v in ssl.values()):\n', ' ssl = None\n', '\n', ' # Connect to the database.\n', '\n', ' def _connect():\n', ' try:\n', ' self.sqlexecute = SQLExecute(\n', ' database, user, passwd, host, port, socket, charset,\n', ' local_infile, ssl, ssh_user, ssh_host, ssh_port,\n', ' ssh_password, ssh_key_filename, init_command\n', ' )\n', ' except OperationalError as e:\n', " if ('Access denied for user' in e.args[1]):\n", " new_passwd = click.prompt('Password', hide_input=True,\n", ' show_default=False, type=str, ' 'err=True)\n', ' self.sqlexecute = SQLExecute(\n', ' database, user, new_passwd, host, port, socket,\n', ' charset, local_infile, ssl, ssh_user, ssh_host,\n', ' ssh_port, ssh_password, ssh_key_filename, ' 'init_command\n', ' )\n', ' else:\n', ' raise e\n', '\n', ' try:\n', ' if not WIN and socket:\n', ' socket_owner = getpwuid(os.stat(socket).st_uid).pw_name\n', ' self.echo(\n', ' f"Connecting to socket {socket}, owned by user ' '{socket_owner}")\n', ' try:\n', ' _connect()\n', ' except OperationalError as e:\n', ' # These are "Can\'t open socket" and 2x "Can\'t ' 'connect"\n', ' if [code for code in (2001, 2002, 2003) if code == ' 'e.args[0]]:\n', " self.logger.debug('Database connection failed: %r.', " 'e)\n', ' self.logger.error(\n', ' "traceback: %r", traceback.format_exc())\n', " self.logger.debug('Retrying over TCP/IP')\n", ' self.echo(\n', ' "Failed to connect to local MySQL server through ' 'socket \'{}\':".format(socket))\n', ' self.echo(str(e), err=True)\n', ' self.echo(\n', " 'Retrying over TCP/IP', err=True)\n", '\n', ' # Else fall back to TCP/IP localhost\n', ' socket = ""\n', " host = 'localhost'\n", ' port = 3306\n', ' _connect()\n', ' else:\n', ' raise e\n', ' else:\n', " host = host or 'localhost'\n", ' port = port or 3306\n', '\n', ' # Bad ports give particularly daft error messages\n', ' try:\n', ' port = int(port)\n', ' except ValueError as e:\n', ' self.echo("Error: Invalid port number: ' '\'{0}\'.".format(port),\n', " err=True, fg='red')\n", ' exit(1)\n', '\n', ' _connect()\n', ' except Exception as e: # Connecting to a database could fail.\n', " self.logger.debug('Database connection failed: %r.', e)\n", ' self.logger.error("traceback: %r", traceback.format_exc())\n', " self.echo(str(e), err=True, fg='red')\n", ' exit(1)\n', '\n', ' def handle_editor_command(self, text):\n', ' """Editor command is any query that is prefixed or suffixed by a ' "'\\e'.\n", ' The reason for a while loop is because a user might edit a query\n', ' multiple times. For eg:\n', '\n', ' "select * from \\e" to edit it in vim, then come\n', ' back to the prompt with the edited query "select * from\n', ' blah where q = \'abc\'\\e" to edit it again.\n', ' :param text: Document\n', ' :return: Document\n', '\n', ' """\n', '\n', ' while special.editor_command(text):\n', ' filename = special.get_filename(text)\n', ' query = (special.get_editor_query(text) or\n', ' self.get_last_query())\n', ' sql, message = special.open_external_editor(filename, ' 'sql=query)\n', ' if message:\n', ' # Something went wrong. Raise an exception and bail.\n', ' raise RuntimeError(message)\n', ' while True:\n', ' try:\n', ' text = self.prompt_app.prompt(default=sql)\n', ' break\n', ' except KeyboardInterrupt:\n', ' sql = ""\n', '\n', ' continue\n', ' return text\n', '\n', ' def run_cli(self):\n', ' iterations = 0\n', ' sqlexecute = self.sqlexecute\n', ' logger = self.logger\n', ' self.configure_pager()\n', '\n', ' if self.smart_completion:\n', ' self.refresh_completions()\n', '\n', " author_file = os.path.join(PACKAGE_ROOT, 'AUTHORS')\n", " sponsor_file = os.path.join(PACKAGE_ROOT, 'SPONSORS')\n", '\n', ' history_file = os.path.expanduser(\n', " os.environ.get('MYCLI_HISTFILE', '~/.mycli-history'))\n", ' if dir_path_exists(history_file):\n', ' history = FileHistory(history_file)\n', ' else:\n', ' history = None\n', ' self.echo(\n', ' \'Error: Unable to open the history file "{}". \'\n', " 'Your query history will not be " "saved.'.format(history_file),\n", " err=True, fg='red')\n", '\n', ' key_bindings = mycli_bindings(self)\n', '\n', ' if not self.less_chatty:\n', " print(' '.join(sqlexecute.server_type()))\n", " print('mycli', __version__)\n", " print('Chat: https://gitter.im/dbcli/mycli')\n", " print('Mail: " "https://groups.google.com/forum/#!forum/mycli-users')\n", " print('Home: http://mycli.net')\n", " print('Thanks to the contributor -', thanks_picker([author_file, " 'sponsor_file]))\n', '\n', ' def get_message():\n', ' prompt = self.get_prompt(self.prompt_format)\n', ' if self.prompt_format == self.default_prompt and len(prompt) > ' 'self.max_len_prompt:\n', " prompt = self.get_prompt('\\\\d> ')\n", " return [('class:prompt', prompt)]\n", '\n', ' def get_continuation(width, *_):\n', ' if self.multiline_continuation_char:\n', ' left_padding = width - ' 'len(self.multiline_continuation_char)\n', ' continuation = " " * \\\n', ' max((left_padding - 1), 0) + \\\n', ' self.multiline_continuation_char + " "\n', ' else:\n', ' continuation = " "\n', " return [('class:continuation', continuation)]\n", '\n', ' def show_suggestion_tip():\n', ' return iterations < 2\n', '\n', ' def one_iteration(text=None):\n', ' if text is None:\n', ' try:\n', ' text = self.prompt_app.prompt()\n', ' except KeyboardInterrupt:\n', ' return\n', '\n', ' special.set_expanded_output(False)\n', '\n', ' try:\n', ' text = self.handle_editor_command(text)\n', ' except RuntimeError as e:\n', ' logger.error("sql: %r, error: %r", text, e)\n', ' logger.error("traceback: %r", traceback.format_exc())\n', " self.echo(str(e), err=True, fg='red')\n", ' return\n', '\n', ' if not text.strip():\n', ' return\n', '\n', ' if self.destructive_warning:\n', ' destroy = confirm_destructive_query(text)\n', ' if destroy is None:\n', ' pass # Query was not destructive. Nothing to do here.\n', ' elif destroy is True:\n', " self.echo('Your call!')\n", ' else:\n', " self.echo('Wise choice!')\n", ' return\n', ' else:\n', ' destroy = True\n', '\n', ' # Keep track of whether or not the query is mutating. In case\n', ' # of a multi-statement query, the overall query is considered\n', ' # mutating if any one of the component statements is mutating\n', ' mutating = False\n', '\n', ' try:\n', " logger.debug('sql: %r', text)\n", '\n', ' special.write_tee(self.get_prompt(self.prompt_format) + ' 'text)\n', ' if self.logfile:\n', " self.logfile.write('\\n# %s\\n' % datetime.now())\n", ' self.logfile.write(text)\n', " self.logfile.write('\\n')\n", '\n', ' successful = False\n', ' start = time()\n', ' res = sqlexecute.run(text)\n', ' self.formatter.query = text\n', ' successful = True\n', ' result_count = 0\n', ' for title, cur, headers, status in res:\n', ' logger.debug("headers: %r", headers)\n', ' logger.debug("rows: %r", cur)\n', ' logger.debug("status: %r", status)\n', ' threshold = 1000\n', ' if (is_select(status) and\n', ' cur and cur.rowcount > threshold):\n', " self.echo('The result set has more than {} " "rows.'.format(\n", " threshold), fg='red')\n", " if not confirm('Do you want to continue?'):\n", ' self.echo("Aborted!", err=True, fg=\'red\')\n', ' break\n', '\n', ' if self.auto_vertical_output:\n', ' max_width = ' 'self.prompt_app.output.get_size().columns\n', ' else:\n', ' max_width = None\n', '\n', ' formatted = self.format_output(\n', ' title, cur, headers, special.is_expanded_output(),\n', ' max_width)\n', '\n', ' t = time() - start\n', ' try:\n', ' if result_count > 0:\n', " self.echo('')\n", ' try:\n', ' self.output(formatted, status)\n', ' except KeyboardInterrupt:\n', ' pass\n', ' if special.is_timing_enabled():\n', " self.echo('Time: %0.03fs' % t)\n", ' except KeyboardInterrupt:\n', ' pass\n', '\n', ' start = time()\n', ' result_count += 1\n', ' mutating = mutating or destroy or is_mutating(status)\n', ' special.unset_once_if_written()\n', ' except EOFError as e:\n', ' raise e\n', ' except KeyboardInterrupt:\n', ' # get last connection id\n', ' connection_id_to_kill = sqlexecute.connection_id\n', ' logger.debug("connection id to kill: %r", ' 'connection_id_to_kill)\n', ' # Restart connection to the database\n', ' sqlexecute.connect()\n', ' try:\n', " for title, cur, headers, status in sqlexecute.run('kill " "%s' % connection_id_to_kill):\n", ' status_str = str(status).lower()\n', " if status_str.find('ok') > -1:\n", ' logger.debug("cancelled query, connection id: ' '%r, sql: %r",\n', ' connection_id_to_kill, text)\n', ' self.echo("cancelled query", err=True, ' "fg='red')\n", ' except Exception as e:\n', " self.echo('Encountered error while cancelling query: " "{}'.format(e),\n", " err=True, fg='red')\n", ' except NotImplementedError:\n', ' self.echo(\'Not Yet Implemented.\', fg="yellow")\n', ' except OperationalError as e:\n', ' logger.debug("Exception: %r", e)\n', ' if (e.args[0] in (2003, 2006, 2013)):\n', " logger.debug('Attempting to reconnect.')\n", " self.echo('Reconnecting...', fg='yellow')\n", ' try:\n', ' sqlexecute.connect()\n', " logger.debug('Reconnected successfully.')\n", ' one_iteration(text)\n', ' return # OK to just return, cuz the recursion call ' 'runs to the end.\n', ' except OperationalError as e:\n', " logger.debug('Reconnect failed. e: %r', e)\n", " self.echo(str(e), err=True, fg='red')\n", " # If reconnection failed, don't proceed further.\n", ' return\n', ' else:\n', ' logger.error("sql: %r, error: %r", text, e)\n', ' logger.error("traceback: %r", traceback.format_exc())\n', " self.echo(str(e), err=True, fg='red')\n", ' except Exception as e:\n', ' logger.error("sql: %r, error: %r", text, e)\n', ' logger.error("traceback: %r", traceback.format_exc())\n', " self.echo(str(e), err=True, fg='red')\n", ' else:\n', ' if is_dropping_database(text, self.sqlexecute.dbname):\n', ' self.sqlexecute.dbname = None\n', ' self.sqlexecute.connect()\n', '\n', ' # Refresh the table names and column names if necessary.\n', ' if need_completion_refresh(text):\n', ' self.refresh_completions(\n', ' reset=need_completion_reset(text))\n', ' finally:\n', ' if self.logfile is False:\n', ' self.echo("Warning: This query was not logged.",\n', " err=True, fg='red')\n", ' query = Query(text, successful, mutating)\n', ' self.query_history.append(query)\n', '\n', ' get_toolbar_tokens = create_toolbar_tokens_func(\n', ' self, show_suggestion_tip)\n', ' if self.wider_completion_menu:\n', ' complete_style = CompleteStyle.MULTI_COLUMN\n', ' else:\n', ' complete_style = CompleteStyle.COLUMN\n', '\n', ' with self._completer_lock:\n', '\n', " if self.key_bindings == 'vi':\n", ' editing_mode = EditingMode.VI\n', ' else:\n', ' editing_mode = EditingMode.EMACS\n', '\n', ' self.prompt_app = PromptSession(\n', ' lexer=PygmentsLexer(MyCliLexer),\n', ' reserve_space_for_menu=self.get_reserved_space(),\n', ' message=get_message,\n', ' prompt_continuation=get_continuation,\n', ' bottom_toolbar=get_toolbar_tokens,\n', ' complete_style=complete_style,\n', ' input_processors=[ConditionalProcessor(\n', ' processor=HighlightMatchingBracketProcessor(\n', " chars='[](){}'),\n", ' filter=HasFocus(DEFAULT_BUFFER) & ~IsDone()\n', ' )],\n', " tempfile_suffix='.sql',\n", ' completer=DynamicCompleter(lambda: self.completer),\n', ' history=history,\n', ' auto_suggest=AutoSuggestFromHistory(),\n', ' complete_while_typing=True,\n', ' multiline=cli_is_multiline(self),\n', ' style=style_factory(self.syntax_style, self.cli_style),\n', ' include_default_pygments_style=False,\n', ' key_bindings=key_bindings,\n', ' enable_open_in_editor=True,\n', ' enable_system_prompt=True,\n', ' enable_suspend=True,\n', ' editing_mode=editing_mode,\n', ' search_ignore_case=True\n', ' )\n', '\n', ' try:\n', ' while True:\n', ' one_iteration()\n', ' iterations += 1\n', ' except EOFError:\n', ' special.close_tee()\n', ' if not self.less_chatty:\n', " self.echo('Goodbye!')\n", '\n', ' def log_output(self, output):\n', ' """Log the output in the audit log, if it\'s enabled."""\n', ' if self.logfile:\n', ' click.echo(output, file=self.logfile)\n', '\n', ' def echo(self, s, **kwargs):\n', ' """Print a message to stdout.\n', '\n', ' The message will be logged in the audit log, if enabled.\n', '\n', ' All keyword arguments are passed to click.echo().\n', '\n', ' """\n', ' self.log_output(s)\n', ' click.secho(s, **kwargs)\n', '\n', ' def get_output_margin(self, status=None):\n', ' """Get the output margin (number of rows for the prompt, footer ' 'and\n', ' timing message."""\n', ' margin = self.get_reserved_space() + ' "self.get_prompt(self.prompt_format).count('\\n') + 1\n", ' if special.is_timing_enabled():\n', ' margin += 1\n', ' if status:\n', " margin += 1 + status.count('\\n')\n", '\n', ' return margin\n', '\n', '\n', ' def output(self, output, status=None):\n', ' """Output text to stdout or a pager command.\n', '\n', ' The status text is not outputted to pager or files.\n', '\n', ' The message will be logged in the audit log, if enabled. The\n', ' message will be written to the tee file, if enabled. The\n', ' message will be written to the output file, if enabled.\n', '\n', ' """\n', ' if output:\n', ' size = self.prompt_app.output.get_size()\n', '\n', ' margin = self.get_output_margin(status)\n', '\n', ' fits = True\n', ' buf = []\n', ' output_via_pager = self.explicit_pager and ' 'special.is_pager_enabled()\n', ' for i, line in enumerate(output, 1):\n', ' self.log_output(line)\n', ' special.write_tee(line)\n', ' special.write_once(line)\n', '\n', ' if fits or output_via_pager:\n', ' # buffering\n', ' buf.append(line)\n', ' if len(line) > size.columns or i > (size.rows - ' 'margin):\n', ' fits = False\n', ' if not self.explicit_pager and ' 'special.is_pager_enabled():\n', " # doesn't fit, use pager\n", ' output_via_pager = True\n', '\n', ' if not output_via_pager:\n', " # doesn't fit, flush buffer\n", ' for line in buf:\n', ' click.secho(line)\n', ' buf = []\n', ' else:\n', ' click.secho(line)\n', '\n', ' if buf:\n', ' if output_via_pager:\n', ' def newlinewrapper(text):\n', ' for line in text:\n', ' yield line + "\\n"\n', ' click.echo_via_pager(newlinewrapper(buf))\n', ' else:\n', ' for line in buf:\n', ' click.secho(line)\n', '\n', ' if status:\n', ' self.log_output(status)\n', ' click.secho(status)\n', '\n', ' def configure_pager(self):\n', ' # Provide sane defaults for less if they are empty.\n', " if not os.environ.get('LESS'):\n", " os.environ['LESS'] = '-RXF'\n", '\n', " cnf = self.read_my_cnf_files(self.cnf_files, ['pager', " "'skip-pager'])\n", " if cnf['pager']:\n", " special.set_pager(cnf['pager'])\n", ' self.explicit_pager = True\n', ' else:\n', ' self.explicit_pager = False\n', '\n', " if cnf['skip-pager'] or not " "self.config['main'].as_bool('enable_pager'):\n", ' special.disable_pager()\n', '\n', ' def refresh_completions(self, reset=False):\n', ' if reset:\n', ' with self._completer_lock:\n', ' self.completer.reset_completions()\n', ' self.completion_refresher.refresh(\n', ' self.sqlexecute, self._on_completions_refreshed,\n', " {'smart_completion': self.smart_completion,\n", " 'supported_formats': self.formatter.supported_formats,\n", " 'keyword_casing': self.completer.keyword_casing})\n", '\n', ' return [(None, None, None,\n', " 'Auto-completion refresh started in the background.')]\n", '\n', ' def _on_completions_refreshed(self, new_completer):\n', ' """Swap the completer object in cli with the newly created ' 'completer.\n', ' """\n', ' with self._completer_lock:\n', ' self.completer = new_completer\n', '\n', ' if self.prompt_app:\n', ' # After refreshing, redraw the CLI to clear the statusbar\n', ' # "Refreshing completions..." indicator\n', ' self.prompt_app.app.invalidate()\n', '\n', ' def get_completions(self, text, cursor_positition):\n', ' with self._completer_lock:\n', ' return self.completer.get_completions(\n', ' Document(text=text, cursor_position=cursor_positition), ' 'None)\n', '\n', ' def get_prompt(self, string):\n', ' sqlexecute = self.sqlexecute\n', ' host = self.login_path if self.login_path and ' 'self.login_path_as_host else sqlexecute.host\n', ' now = datetime.now()\n', " string = string.replace('\\\\u', sqlexecute.user or '(none)')\n", " string = string.replace('\\\\h', host or '(none)')\n", " string = string.replace('\\\\d', sqlexecute.dbname or '(none)')\n", " string = string.replace('\\\\t', sqlexecute.server_type()[0] or " "'mycli')\n", ' string = string.replace(\'\\\\n\', "\\n")\n', " string = string.replace('\\\\D', now.strftime('%a %b %d %H:%M:%S " "%Y'))\n", " string = string.replace('\\\\m', now.strftime('%M'))\n", " string = string.replace('\\\\P', now.strftime('%p'))\n", " string = string.replace('\\\\R', now.strftime('%H'))\n", " string = string.replace('\\\\r', now.strftime('%I'))\n", " string = string.replace('\\\\s', now.strftime('%S'))\n", " string = string.replace('\\\\p', str(sqlexecute.port))\n", " string = string.replace('\\\\A', self.dsn_alias or '(none)')\n", " string = string.replace('\\\\_', ' ')\n", ' return string\n', '\n', ' def run_query(self, query, new_line=True):\n', ' """Runs *query*."""\n', ' results = self.sqlexecute.run(query)\n', ' for result in results:\n', ' title, cur, headers, status = result\n', ' self.formatter.query = query\n', ' output = self.format_output(title, cur, headers)\n', ' for line in output:\n', ' click.echo(line, nl=new_line)\n', '\n', ' def format_output(self, title, cur, headers, expanded=False,\n', ' max_width=None):\n', " expanded = expanded or self.formatter.format_name == 'vertical'\n", ' output = []\n', '\n', ' output_kwargs = {\n', " 'dialect': 'unix',\n", " 'disable_numparse': True,\n", " 'preserve_whitespace': True,\n", " 'style': self.output_style\n", ' }\n', '\n', ' if not self.formatter.format_name in sql_format.supported_formats:\n', ' output_kwargs["preprocessors"] = (preprocessors.align_decimals, ' ')\n', '\n', " if title: # Only print the title if it's not None.\n", ' output = itertools.chain(output, [title])\n', '\n', ' if cur:\n', ' column_types = None\n', " if hasattr(cur, 'description'):\n", ' def get_col_type(col):\n', ' col_type = FIELD_TYPES.get(col[1], str)\n', ' return col_type if type(col_type) is type else str\n', ' column_types = [get_col_type(col) for col in ' 'cur.description]\n', '\n', ' if max_width is not None:\n', ' cur = list(cur)\n', '\n', ' formatted = self.formatter.format_output(\n', " cur, headers, format_name='vertical' if expanded else " 'None,\n', ' column_types=column_types,\n', ' **output_kwargs)\n', '\n', ' if isinstance(formatted, str):\n', ' formatted = formatted.splitlines()\n', ' formatted = iter(formatted)\n', '\n', ' if (not expanded and max_width and headers and cur):\n', ' first_line = next(formatted)\n', ' if len(strip_ansi(first_line)) > max_width:\n', ' formatted = self.formatter.format_output(\n', " cur, headers, format_name='vertical', " 'column_types=column_types, **output_kwargs)\n', ' if isinstance(formatted, str):\n', ' formatted = iter(formatted.splitlines())\n', ' else:\n', ' formatted = itertools.chain([first_line], formatted)\n', '\n', ' output = itertools.chain(output, formatted)\n', '\n', '\n', ' return output\n', '\n', ' def get_reserved_space(self):\n', ' """Get the number of lines to reserve for the completion menu."""\n', ' reserved_space_ratio = .45\n', ' max_reserved_space = 8\n', ' _, height = click.get_terminal_size()\n', ' return min(int(round(height * reserved_space_ratio)), ' 'max_reserved_space)\n', '\n', ' def get_last_query(self):\n', ' """Get the last query executed or None."""\n', ' return self.query_history[-1][0] if self.query_history else None\n', '\n', '\n', '@click.command()\n', "@click.option('-h', '--host', envvar='MYSQL_HOST', help='Host address of the " "database.')\n", "@click.option('-P', '--port', envvar='MYSQL_TCP_PORT', type=int, help='Port " "number to use for connection. Honors '\n", " '$MYSQL_TCP_PORT.')\n", "@click.option('-u', '--user', help='User name to connect to the " "database.')\n", "@click.option('-S', '--socket', envvar='MYSQL_UNIX_PORT', help='The socket " "file to use for connection.')\n", "@click.option('-p', '--password', 'password', envvar='MYSQL_PWD', " 'type=str,\n', " help='Password to connect to the database.')\n", "@click.option('--pass', 'password', envvar='MYSQL_PWD', type=str,\n", " help='Password to connect to the database.')\n", "@click.option('--ssh-user', help='User name to connect to ssh server.')\n", "@click.option('--ssh-host', help='Host name to connect to ssh server.')\n", "@click.option('--ssh-port', default=22, help='Port to connect to ssh " "server.')\n", "@click.option('--ssh-password', help='Password to connect to ssh server.')\n", "@click.option('--ssh-key-filename', help='Private key filename (identify " "file) for the ssh connection.')\n", "@click.option('--ssh-config-path', help='Path to ssh configuration.',\n", " default=os.path.expanduser('~') + '/.ssh/config')\n", "@click.option('--ssh-config-host', help='Host to connect to ssh server " "reading from ssh configuration.')\n", "@click.option('--ssl-ca', help='CA file in PEM format.',\n", ' type=click.Path(exists=True))\n', "@click.option('--ssl-capath', help='CA directory.')\n", "@click.option('--ssl-cert', help='X509 cert in PEM format.',\n", ' type=click.Path(exists=True))\n', "@click.option('--ssl-key', help='X509 key in PEM format.',\n", ' type=click.Path(exists=True))\n', "@click.option('--ssl-cipher', help='SSL cipher to use.')\n", "@click.option('--ssl-verify-server-cert', is_flag=True,\n", ' help=(\'Verify server\\\'s "Common Name" in its cert against ' "'\n", " 'hostname used when connecting. This option is disabled " "'\n", " 'by default.'))\n", '# as of 2016-02-15 revocation list is not supported by underling PyMySQL\n', '# library (--ssl-crl and --ssl-crlpath options in vanilla mysql client)\n', "@click.option('-V', '--version', is_flag=True, help='Output mycli\\'s " "version.')\n", "@click.option('-v', '--verbose', is_flag=True, help='Verbose output.')\n", "@click.option('-D', '--database', 'dbname', help='Database to use.')\n", "@click.option('-d', '--dsn', default='', envvar='DSN',\n", " help='Use DSN configured into the [alias_dsn] section of " "myclirc file.')\n", "@click.option('--list-dsn', 'list_dsn', is_flag=True,\n", " help='list of DSN configured into the [alias_dsn] section of myclirc " "file.')\n", "@click.option('--list-ssh-config', 'list_ssh_config', is_flag=True,\n", " help='list ssh configurations in the ssh config (requires " "paramiko).')\n", "@click.option('-R', '--prompt', 'prompt',\n", ' help=\'Prompt format (Default: "{0}").\'.format(\n', ' MyCli.default_prompt))\n', "@click.option('-l', '--logfile', type=click.File(mode='a', " "encoding='utf-8'),\n", " help='Log every query and its results to a file.')\n", "@click.option('--defaults-group-suffix', type=str,\n", " help='Read MySQL config groups with the specified suffix.')\n", "@click.option('--defaults-file', type=click.Path(),\n", " help='Only read MySQL options from the given file.')\n", '@click.option(\'--myclirc\', type=click.Path(), default="~/.myclirc",\n', " help='Location of myclirc file.')\n", "@click.option('--auto-vertical-output', is_flag=True,\n", " help='Automatically switch to vertical output mode if the " "result is wider than the terminal width.')\n", "@click.option('-t', '--table', is_flag=True,\n", " help='Display batch output in table format.')\n", "@click.option('--csv', is_flag=True,\n", " help='Display batch output in CSV format.')\n", "@click.option('--warn/--no-warn', default=None,\n", " help='Warn before running a destructive query.')\n", "@click.option('--local-infile', type=bool,\n", " help='Enable/disable LOAD DATA LOCAL INFILE.')\n", "@click.option('--login-path', type=str,\n", " help='Read this path from the login file.')\n", "@click.option('-e', '--execute', type=str,\n", " help='Execute command and quit.')\n", "@click.option('--init-command', type=str,\n", " help='SQL statement to execute after connecting.')\n", "@click.argument('database', default='', nargs=1)\n", 'def cli(database, user, host, port, socket, password, dbname,\n', ' version, verbose, prompt, logfile, defaults_group_suffix,\n', ' defaults_file, login_path, auto_vertical_output, local_infile,\n', ' ssl_ca, ssl_capath, ssl_cert, ssl_key, ssl_cipher,\n', ' ssl_verify_server_cert, table, csv, warn, execute, myclirc, dsn,\n', ' list_dsn, ssh_user, ssh_host, ssh_port, ssh_password,\n', ' ssh_key_filename, list_ssh_config, ssh_config_path, ' 'ssh_config_host,\n', ' init_command):\n', ' """A MySQL terminal client with auto-completion and syntax ' 'highlighting.\n', '\n', ' \\b\n', ' Examples:\n', ' - mycli my_database\n', ' - mycli -u my_user -h my_host.com my_database\n', ' - mycli mysql://my_user@my_host.com:3306/my_database\n', '\n', ' """\n', '\n', ' if version:\n', " print('Version:', __version__)\n", ' sys.exit(0)\n', '\n', ' mycli = MyCli(prompt=prompt, logfile=logfile,\n', ' defaults_suffix=defaults_group_suffix,\n', ' defaults_file=defaults_file, login_path=login_path,\n', ' auto_vertical_output=auto_vertical_output, warn=warn,\n', ' myclirc=myclirc)\n', ' if list_dsn:\n', ' try:\n', " alias_dsn = mycli.config['alias_dsn']\n", ' except KeyError as err:\n', " click.secho('Invalid DSNs found in the config file. '\\\n", ' \'Please check the "[alias_dsn]" section in myclirc.\',\n', " err=True, fg='red')\n", ' exit(1)\n', ' except Exception as e:\n', " click.secho(str(e), err=True, fg='red')\n", ' exit(1)\n', ' for alias, value in alias_dsn.items():\n', ' if verbose:\n', ' click.secho("{} : {}".format(alias, value))\n', ' else:\n', ' click.secho(alias)\n', ' sys.exit(0)\n', ' if list_ssh_config:\n', ' ssh_config = read_ssh_config(ssh_config_path)\n', ' for host in ssh_config.get_hostnames():\n', ' if verbose:\n', ' host_config = ssh_config.lookup(host)\n', ' click.secho("{} : {}".format(\n', " host, host_config.get('hostname')))\n", ' else:\n', ' click.secho(host)\n', ' sys.exit(0)\n', ' # Choose which ever one has a valid value.\n', ' database = dbname or database\n', '\n', ' ssl = {\n', " 'ca': ssl_ca and os.path.expanduser(ssl_ca),\n", " 'cert': ssl_cert and os.path.expanduser(ssl_cert),\n", " 'key': ssl_key and os.path.expanduser(ssl_key),\n", " 'capath': ssl_capath,\n", " 'cipher': ssl_cipher,\n", " 'check_hostname': ssl_verify_server_cert,\n", ' }\n', '\n', ' # remove empty ssl options\n', ' ssl = {k: v for k, v in ssl.items() if v is not None}\n', '\n', ' dsn_uri = None\n', '\n', " # Treat the database argument as a DSN alias if we're missing\n", ' # other connection information.\n', " if (mycli.config['alias_dsn'] and database and '://' not in database\n", ' and not any([user, password, host, port, login_path])):\n', " dsn, database = database, ''\n", '\n', " if database and '://' in database:\n", " dsn_uri, database = database, ''\n", '\n', ' if dsn:\n', ' try:\n', " dsn_uri = mycli.config['alias_dsn'][dsn]\n", ' except KeyError:\n', " click.secho('Could not find the specified DSN in the config " "file. '\n", ' \'Please check the "[alias_dsn]" section in your ' "'\n", " 'myclirc.', err=True, fg='red')\n", ' exit(1)\n', ' else:\n', ' mycli.dsn_alias = dsn\n', '\n', ' if dsn_uri:\n', ' uri = urlparse(dsn_uri)\n', ' if not database:\n', ' database = uri.path[1:] # ignore the leading fwd slash\n', ' if not user:\n', ' user = unquote(uri.username)\n', ' if not password and uri.password is not None:\n', ' password = unquote(uri.password)\n', ' if not host:\n', ' host = uri.hostname\n', ' if not port:\n', ' port = uri.port\n', '\n', ' if ssh_config_host:\n', ' ssh_config = read_ssh_config(\n', ' ssh_config_path\n', ' ).lookup(ssh_config_host)\n', " ssh_host = ssh_host if ssh_host else ssh_config.get('hostname')\n", " ssh_user = ssh_user if ssh_user else ssh_config.get('user')\n", " if ssh_config.get('port') and ssh_port == 22:\n", " # port has a default value, overwrite it if it's in the config\n", " ssh_port = int(ssh_config.get('port'))\n", ' ssh_key_filename = ssh_key_filename if ssh_key_filename else ' 'ssh_config.get(\n', " 'identityfile', [None])[0]\n", '\n', ' ssh_key_filename = ssh_key_filename and ' 'os.path.expanduser(ssh_key_filename)\n', '\n', ' mycli.connect(\n', ' database=database,\n', ' user=user,\n', ' passwd=password,\n', ' host=host,\n', ' port=port,\n', ' socket=socket,\n', ' local_infile=local_infile,\n', ' ssl=ssl,\n', ' ssh_user=ssh_user,\n', ' ssh_host=ssh_host,\n', ' ssh_port=ssh_port,\n', ' ssh_password=ssh_password,\n', ' ssh_key_filename=ssh_key_filename,\n', ' init_command=init_command\n', ' )\n', '\n', " mycli.logger.debug('Launch Params: \\n'\n", " '\\tdatabase: %r'\n", " '\\tuser: %r'\n", " '\\thost: %r'\n", " '\\tport: %r', database, user, host, port)\n", '\n', ' # --execute argument\n', ' if execute:\n', ' try:\n', ' if csv:\n', " mycli.formatter.format_name = 'csv'\n", ' elif not table:\n', " mycli.formatter.format_name = 'tsv'\n", '\n', ' mycli.run_query(execute)\n', ' exit(0)\n', ' except Exception as e:\n', " click.secho(str(e), err=True, fg='red')\n", ' exit(1)\n', '\n', ' if sys.stdin.isatty():\n', ' mycli.run_cli()\n', ' else:\n', " stdin = click.get_text_stream('stdin')\n", ' try:\n', ' stdin_text = stdin.read()\n', ' except MemoryError:\n', " click.secho('Failed! Ran out of memory.', err=True, fg='red')\n", " click.secho('You might want to try the official mysql client.', " "err=True, fg='red')\n", " click.secho('Sorry... :(', err=True, fg='red')\n", ' exit(1)\n', '\n', ' try:\n', " sys.stdin = open('/dev/tty')\n", ' except (IOError, OSError):\n', " mycli.logger.warning('Unable to open TTY as stdin.')\n", '\n', ' if (mycli.destructive_warning and\n', ' confirm_destructive_query(stdin_text) is False):\n', ' exit(0)\n', ' try:\n', ' new_line = True\n', '\n', ' if csv:\n', " mycli.formatter.format_name = 'csv'\n", ' elif not table:\n', " mycli.formatter.format_name = 'tsv'\n", '\n', ' mycli.run_query(stdin_text, new_line=new_line)\n', ' exit(0)\n', ' except Exception as e:\n', " click.secho(str(e), err=True, fg='red')\n", ' exit(1)\n', '\n', '\n', 'def need_completion_refresh(queries):\n', ' """Determines if the completion needs a refresh by checking if the sql\n', ' statement is an alter, create, drop or change db."""\n', ' for query in sqlparse.split(queries):\n', ' try:\n', ' first_token = query.split()[0]\n', " if first_token.lower() in ('alter', 'create', 'use', '\\\\r',\n", " '\\\\u', 'connect', 'drop', " "'rename'):\n", ' return True\n', ' except Exception:\n', ' return False\n', '\n', '\n', 'def need_completion_reset(queries):\n', ' """Determines if the statement is a database switch such as \'use\' or ' "'\\\\u'.\n", ' When a database is changed the existing completions must be reset before ' 'we\n', ' start the completion refresh for the new database.\n', ' """\n', ' for query in sqlparse.split(queries):\n', ' try:\n', ' first_token = query.split()[0]\n', " if first_token.lower() in ('use', '\\\\u'):\n", ' return True\n', ' except Exception:\n', ' return False\n', '\n', '\n', 'def is_mutating(status):\n', ' """Determines if the statement is mutating based on the status."""\n', ' if not status:\n', ' return False\n', '\n', " mutating = set(['insert', 'update', 'delete', 'alter', 'create', " "'drop',\n", " 'replace', 'truncate', 'load', 'rename'])\n", ' return status.split(None, 1)[0].lower() in mutating\n', '\n', '\n', 'def is_select(status):\n', ' """Returns true if the first word in status is \'select\'."""\n', ' if not status:\n', ' return False\n', " return status.split(None, 1)[0].lower() == 'select'\n", '\n', '\n', 'def thanks_picker(files=()):\n', ' contents = []\n', ' for line in fileinput.input(files=files):\n', " m = re.match('^ *\\* (.*)', line)\n", ' if m:\n', ' contents.append(m.group(1))\n', ' return choice(contents)\n', '\n', '\n', "@prompt_register('edit-and-execute-command')\n", 'def edit_and_execute(event):\n', ' """Different from the prompt-toolkit default, we want to have a choice ' 'not\n', ' to execute a query after editing, hence validate_and_handle=False."""\n', ' buff = event.current_buffer\n', ' buff.open_in_editor(validate_and_handle=False)\n', '\n', '\n', 'def read_ssh_config(ssh_config_path):\n', ' ssh_config = paramiko.config.SSHConfig()\n', ' try:\n', ' with open(ssh_config_path) as f:\n', ' ssh_config.parse(f)\n', ' # Paramiko prior to version 2.7 raises Exception on parse errors.\n', ' # In 2.7 it has become paramiko.ssh_exception.SSHException,\n', " # but let's catch everything for compatibility\n", ' except Exception as err:\n', ' click.secho(\n', " f'Could not parse SSH configuration file " "{ssh_config_path}:\\n{err} ',\n", " err=True, fg='red'\n", ' )\n', ' sys.exit(1)\n', ' except FileNotFoundError as e:\n', " click.secho(str(e), err=True, fg='red')\n", ' sys.exit(1)\n', ' else:\n', ' return ssh_config\n', '\n', '\n', 'if __name__ == "__main__":\n', ' cli()\n'] test = None tests = [] val = valname = 'mycli.main.paramiko' /usr/lib/python3.8/site-packages/_pytest/doctest.py:471: in _mock_aware_unwrap return real_unwrap(func, stop=_is_mocked) func = real_unwrap = stop = None /usr/lib/python3.8/inspect.py:520: in unwrap while _is_wrapper(func): _is_wrapper = ._is_wrapper at 0x7f26ad171700> f = func = memo = {139804091248304: } recursion_limit = 1000 stop = /usr/lib/python3.8/inspect.py:514: in _is_wrapper return hasattr(f, '__wrapped__') and not stop(f) f = stop = mycli/packages/paramiko_stub/__init__.py:25: in __getattr__ sys.exit(1) E SystemExit: 1 dedent = name = '__wrapped__' self = sys = ------------------------------- Captured stdout -------------------------------- To enable certain SSH features you need to install paramiko: pip install paramiko It is required for the following configuration options: --list-ssh-config --ssh-config-host --ssh-host _____________________ ERROR collecting mycli/sqlexecute.py _____________________ /usr/lib/python3.8/doctest.py:939: in find self._find(tests, obj, name, module, source_lines, globs, {}) extraglobs = None file = '/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/sqlexecute.py' globs = {'FIELD_TYPE': , 'FIELD_TYPES': {0: , 1: , 2: , 3: , 4: , 5: , 6: , 7: , 8: , 9: , 10: , 11: , 12: , 13: , 15: , 16: , 246: , 249: , 250: , 251: , 252: , 253: , 254: }, 'SQLExecute': , '__builtins__': {'ArithmeticError': , 'AssertionError': , 'AttributeError': , 'BaseException': , 'BlockingIOError': , 'BrokenPipeError': , 'BufferError': , 'BytesWarning': , 'ChildProcessError': , 'ConnectionAbortedError': , 'ConnectionError': , 'ConnectionRefusedError': , 'ConnectionResetError': , 'DeprecationWarning': , 'EOFError': , 'Ellipsis': Ellipsis, 'EnvironmentError': , 'Exception': , 'False': False, 'FileExistsError': , 'FileNotFoundError': , 'FloatingPointError': , 'FutureWarning': , 'GeneratorExit': , 'IOError': , 'ImportError': , 'ImportWarning': , 'IndentationError': , 'IndexError': , 'InterruptedError': , 'IsADirectoryError': , 'KeyError': , 'KeyboardInterrupt': , 'LookupError': , 'MemoryError': , 'ModuleNotFoundError': , 'NameError': , 'None': None, 'NotADirectoryError': , 'NotImplemented': NotImplemented, 'NotImplementedError': , 'OSError': , 'OverflowError': , 'PendingDeprecationWarning': , 'PermissionError': , 'ProcessLookupError': , 'RecursionError': , 'ReferenceError': , 'ResourceWarning': , 'RuntimeError': , 'RuntimeWarning': , 'StopAsyncIteration': , 'StopIteration': , 'SyntaxError': , 'SyntaxWarning': , 'SystemError': , 'SystemExit': , 'TabError': , 'TimeoutError': , 'True': True, 'TypeError': , 'UnboundLocalError': , 'UnicodeDecodeError': , 'UnicodeEncodeError': , 'UnicodeError': , 'UnicodeTranslateError': , 'UnicodeWarning': , 'UserWarning': , 'ValueError': , 'Warning': , 'ZeroDivisionError': , '__build_class__': , '__debug__': True, '__doc__': 'Built-in functions, exceptions, and other ' 'objects.\n' '\n' "Noteworthy: None is the `nil' object; Ellipsis " "represents `...' in slices.", '__import__': , '__loader__': , '__name__': 'builtins', '__package__': '', '__spec__': ModuleSpec(name='builtins', loader=), 'abs': , 'all': , 'any': , 'ascii': , 'bin': , 'bool': , 'breakpoint': , 'bytearray': , 'bytes': , 'callable': , 'chr': , 'classmethod': , 'compile': , 'complex': , 'copyright': Copyright (c) 2001-2021 Python Software Foundation. All Rights Reserved. Copyright (c) 2000 BeOpen.com. All Rights Reserved. Copyright (c) 1995-2001 Corporation for National Research Initiatives. All Rights Reserved. Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam. All Rights Reserved., 'credits': Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands for supporting Python development. See www.python.org for more information., 'delattr': , 'dict': , 'dir': , 'divmod': , 'enumerate': , 'eval': , 'exec': , 'exit': Use exit() or Ctrl-D (i.e. EOF) to exit, 'filter': , 'float': , 'format': , 'frozenset': , 'getattr': , 'globals': , 'hasattr': , 'hash': , 'help': Type help() for interactive help, or help(object) for help about object., 'hex': , 'id': , 'input': , 'int': , 'isinstance': , 'issubclass': , 'iter': , 'len': , 'license': Type license() to see the full license text, 'list': , 'locals': , 'map': , 'max': , 'memoryview': , 'min': , 'next': , 'object': , 'oct': , 'open': , 'ord': , 'pow': , 'print': , 'property': , 'quit': Use quit() or Ctrl-D (i.e. EOF) to exit, 'range': , 'repr': , 'reversed': , 'round': , 'set': , 'setattr': , 'slice': , 'sorted': , 'staticmethod': , 'str': , 'sum': , 'super': , 'tuple': , 'type': , 'vars': , 'zip': }, '__cached__': '/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/__pycache__/sqlexecute.cpython-38.pyc', '__doc__': None, '__file__': '/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/sqlexecute.py', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f26ad326ca0>, '__name__': 'mycli.sqlexecute', '__package__': 'mycli', '__spec__': ModuleSpec(name='mycli.sqlexecute', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7f26ad326ca0>, origin='/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/sqlexecute.py'), '_logger': , 'conversions': {0: , 1: , 2: , 3: , 4: , 5: , 7: , 8: , 9: , 10: , 11: , 12: , 13: , 15: , 16: , 246: , 249: , 250: , 251: , 252: , 253: , 254: , : , : , : , : , : , : , : , : , : , : , : , : , : , : , : , : , : }, 'convert_date': , 'convert_datetime': , 'convert_timedelta': , 'decoders': {0: , 1: , 2: , 3: , 4: , 5: , 7: , 8: , 9: , 10: , 11: , 12: , 13: , 15: , 16: , 246: , 249: , 250: , 251: , 252: , 253: , 254: }, 'logging': , 'paramiko': , 'pymysql': , 'special': , 'sqlparse': } module = name = 'mycli.sqlexecute' obj = self = <_pytest.doctest.DoctestModule.collect..MockAwareDocTestFinder object at 0x7f26acc16880> source_lines = ['import logging\n', 'import pymysql\n', 'import sqlparse\n', 'from .packages import special\n', 'from pymysql.constants import FIELD_TYPE\n', 'from pymysql.converters import (convert_datetime,\n', ' convert_timedelta, convert_date, ' 'conversions,\n', ' decoders)\n', 'try:\n', ' import paramiko\n', 'except ImportError:\n', ' from mycli.packages.paramiko_stub import paramiko\n', '\n', '_logger = logging.getLogger(__name__)\n', '\n', 'FIELD_TYPES = decoders.copy()\n', 'FIELD_TYPES.update({\n', ' FIELD_TYPE.NULL: type(None)\n', '})\n', '\n', 'class SQLExecute(object):\n', '\n', " databases_query = '''SHOW DATABASES'''\n", '\n', " tables_query = '''SHOW TABLES'''\n", '\n', " version_query = '''SELECT @@VERSION'''\n", '\n', " version_comment_query = '''SELECT @@VERSION_COMMENT'''\n", " version_comment_query_mysql4 = '''SHOW VARIABLES LIKE " '"version_comment"\'\'\'\n', '\n', " show_candidates_query = '''SELECT name from mysql.help_topic WHERE name " 'like "SHOW %"\'\'\'\n', '\n', ' users_query = \'\'\'SELECT CONCAT("\'", user, "\'@\'",host,"\'") FROM ' "mysql.user'''\n", '\n', " functions_query = '''SELECT ROUTINE_NAME FROM " 'INFORMATION_SCHEMA.ROUTINES\n', ' WHERE ROUTINE_TYPE="FUNCTION" AND ROUTINE_SCHEMA = "%s"\'\'\'\n', '\n', " table_columns_query = '''select TABLE_NAME, COLUMN_NAME from " 'information_schema.columns\n', " where table_schema = '%s'\n", ' order by ' "table_name,ordinal_position'''\n", '\n', ' def __init__(self, database, user, password, host, port, socket, ' 'charset,\n', ' local_infile, ssl, ssh_user, ssh_host, ssh_port, ' 'ssh_password,\n', ' ssh_key_filename, init_command=None):\n', ' self.dbname = database\n', ' self.user = user\n', ' self.password = password\n', ' self.host = host\n', ' self.port = port\n', ' self.socket = socket\n', ' self.charset = charset\n', ' self.local_infile = local_infile\n', ' self.ssl = ssl\n', ' self._server_type = None\n', ' self.connection_id = None\n', ' self.ssh_user = ssh_user\n', ' self.ssh_host = ssh_host\n', ' self.ssh_port = ssh_port\n', ' self.ssh_password = ssh_password\n', ' self.ssh_key_filename = ssh_key_filename\n', ' self.init_command = init_command\n', ' self.connect()\n', '\n', ' def connect(self, database=None, user=None, password=None, host=None,\n', ' port=None, socket=None, charset=None, local_infile=None,\n', ' ssl=None, ssh_host=None, ssh_port=None, ssh_user=None,\n', ' ssh_password=None, ssh_key_filename=None, ' 'init_command=None):\n', ' db = (database or self.dbname)\n', ' user = (user or self.user)\n', ' password = (password or self.password)\n', ' host = (host or self.host)\n', ' port = (port or self.port)\n', ' socket = (socket or self.socket)\n', ' charset = (charset or self.charset)\n', ' local_infile = (local_infile or self.local_infile)\n', ' ssl = (ssl or self.ssl)\n', ' ssh_user = (ssh_user or self.ssh_user)\n', ' ssh_host = (ssh_host or self.ssh_host)\n', ' ssh_port = (ssh_port or self.ssh_port)\n', ' ssh_password = (ssh_password or self.ssh_password)\n', ' ssh_key_filename = (ssh_key_filename or self.ssh_key_filename)\n', ' init_command = (init_command or self.init_command)\n', ' _logger.debug(\n', " 'Connection DB Params: \\n'\n", " '\\tdatabase: %r'\n", " '\\tuser: %r'\n", " '\\thost: %r'\n", " '\\tport: %r'\n", " '\\tsocket: %r'\n", " '\\tcharset: %r'\n", " '\\tlocal_infile: %r'\n", " '\\tssl: %r'\n", " '\\tssh_user: %r'\n", " '\\tssh_host: %r'\n", " '\\tssh_port: %r'\n", " '\\tssh_password: %r'\n", " '\\tssh_key_filename: %r'\n", " '\\tinit_command: %r',\n", ' db, user, host, port, socket, charset, local_infile, ssl,\n', ' ssh_user, ssh_host, ssh_port, ssh_password, ssh_key_filename,\n', ' init_command\n', ' )\n', ' conv = conversions.copy()\n', ' conv.update({\n', ' FIELD_TYPE.TIMESTAMP: lambda obj: (convert_datetime(obj) or ' 'obj),\n', ' FIELD_TYPE.DATETIME: lambda obj: (convert_datetime(obj) or ' 'obj),\n', ' FIELD_TYPE.TIME: lambda obj: (convert_timedelta(obj) or obj),\n', ' FIELD_TYPE.DATE: lambda obj: (convert_date(obj) or obj),\n', ' })\n', '\n', ' defer_connect = False\n', '\n', ' if ssh_host:\n', ' defer_connect = True\n', '\n', ' client_flag = pymysql.constants.CLIENT.INTERACTIVE\n', ' if init_command and len(list(special.split_queries(init_command))) > ' '1:\n', ' client_flag |= pymysql.constants.CLIENT.MULTI_STATEMENTS\n', '\n', ' conn = pymysql.connect(\n', ' database=db, user=user, password=password, host=host, ' 'port=port,\n', ' unix_socket=socket, use_unicode=True, charset=charset,\n', ' autocommit=True, client_flag=client_flag,\n', ' local_infile=local_infile, conv=conv, ssl=ssl, ' 'program_name="mycli",\n', ' defer_connect=defer_connect, init_command=init_command\n', ' )\n', '\n', ' if ssh_host:\n', ' client = paramiko.SSHClient()\n', ' client.load_system_host_keys()\n', ' client.set_missing_host_key_policy(paramiko.WarningPolicy())\n', ' client.connect(\n', ' ssh_host, ssh_port, ssh_user, ssh_password,\n', ' key_filename=ssh_key_filename\n', ' )\n', ' chan = client.get_transport().open_channel(\n', " 'direct-tcpip',\n", ' (host, port),\n', " ('0.0.0.0', 0),\n", ' )\n', ' conn.connect(chan)\n', '\n', " if hasattr(self, 'conn'):\n", ' self.conn.close()\n', ' self.conn = conn\n', ' # Update them after the connection is made to ensure that it was a\n', ' # successful connection.\n', ' self.dbname = db\n', ' self.user = user\n', ' self.password = password\n', ' self.host = host\n', ' self.port = port\n', ' self.socket = socket\n', ' self.charset = charset\n', ' self.ssl = ssl\n', ' self.init_command = init_command\n', ' # retrieve connection id\n', ' self.reset_connection_id()\n', '\n', ' def run(self, statement):\n', ' """Execute the sql in the database and return the results. The ' 'results\n', ' are a list of tuples. Each tuple has 4 values\n', ' (title, rows, headers, status).\n', ' """\n', '\n', ' # Remove spaces and EOL\n', ' statement = statement.strip()\n', ' if not statement: # Empty string\n', ' yield (None, None, None, None)\n', '\n', ' # Split the sql into separate queries and run each one.\n', " # Unless it's saving a favorite query, in which case we\n", ' # want to save them all together.\n', " if statement.startswith('\\\\fs'):\n", ' components = [statement]\n', ' else:\n', ' components = special.split_queries(statement)\n', '\n', ' for sql in components:\n', ' # \\G is treated specially since we have to set the expanded ' 'output.\n', " if sql.endswith('\\\\G'):\n", ' special.set_expanded_output(True)\n', ' sql = sql[:-2].strip()\n', '\n', ' cur = self.conn.cursor()\n', ' try: # Special command\n', " _logger.debug('Trying a dbspecial command. sql: %r', sql)\n", ' for result in special.execute(cur, sql):\n', ' yield result\n', ' except special.CommandNotFound: # Regular SQL\n', " _logger.debug('Regular sql statement. sql: %r', sql)\n", ' cur.execute(sql)\n', ' while True:\n', ' yield self.get_result(cur)\n', '\n', ' # PyMySQL returns an extra, empty result set with ' 'stored\n', ' # procedures. We skip it (rowcount is zero and no\n', ' # description).\n', ' if not cur.nextset() or (not cur.rowcount and ' 'cur.description is None):\n', ' break\n', '\n', ' def get_result(self, cursor):\n', ' """Get the current result\'s data from the cursor."""\n', ' title = headers = None\n', '\n', ' # cursor.description is not None for queries that return result ' 'sets,\n', ' # e.g. SELECT or SHOW.\n', ' if cursor.description is not None:\n', ' headers = [x[0] for x in cursor.description]\n', " status = '{0} row{1} in set'\n", ' else:\n', " _logger.debug('No rows in result.')\n", " status = 'Query OK, {0} row{1} affected'\n", ' status = status.format(cursor.rowcount,\n', " '' if cursor.rowcount == 1 else 's')\n", '\n', ' return (title, cursor if cursor.description else None, headers, ' 'status)\n', '\n', ' def tables(self):\n', ' """Yields table names"""\n', '\n', ' with self.conn.cursor() as cur:\n', " _logger.debug('Tables Query. sql: %r', self.tables_query)\n", ' cur.execute(self.tables_query)\n', ' for row in cur:\n', ' yield row\n', '\n', ' def table_columns(self):\n', ' """Yields (table name, column name) pairs"""\n', ' with self.conn.cursor() as cur:\n', " _logger.debug('Columns Query. sql: %r', " 'self.table_columns_query)\n', ' cur.execute(self.table_columns_query % self.dbname)\n', ' for row in cur:\n', ' yield row\n', '\n', ' def databases(self):\n', ' with self.conn.cursor() as cur:\n', " _logger.debug('Databases Query. sql: %r', " 'self.databases_query)\n', ' cur.execute(self.databases_query)\n', ' return [x[0] for x in cur.fetchall()]\n', '\n', ' def functions(self):\n', ' """Yields tuples of (schema_name, function_name)"""\n', '\n', ' with self.conn.cursor() as cur:\n', " _logger.debug('Functions Query. sql: %r', " 'self.functions_query)\n', ' cur.execute(self.functions_query % self.dbname)\n', ' for row in cur:\n', ' yield row\n', '\n', ' def show_candidates(self):\n', ' with self.conn.cursor() as cur:\n', " _logger.debug('Show Query. sql: %r', " 'self.show_candidates_query)\n', ' try:\n', ' cur.execute(self.show_candidates_query)\n', ' except pymysql.DatabaseError as e:\n', " _logger.error('No show completions due to %r', e)\n", " yield ''\n", ' else:\n', ' for row in cur:\n', ' yield (row[0].split(None, 1)[-1], )\n', '\n', ' def users(self):\n', ' with self.conn.cursor() as cur:\n', " _logger.debug('Users Query. sql: %r', self.users_query)\n", ' try:\n', ' cur.execute(self.users_query)\n', ' except pymysql.DatabaseError as e:\n', " _logger.error('No user completions due to %r', e)\n", " yield ''\n", ' else:\n', ' for row in cur:\n', ' yield row\n', '\n', ' def server_type(self):\n', ' if self._server_type:\n', ' return self._server_type\n', ' with self.conn.cursor() as cur:\n', " _logger.debug('Version Query. sql: %r', self.version_query)\n", ' cur.execute(self.version_query)\n', ' version = cur.fetchone()[0]\n', " if version[0] == '4':\n", " _logger.debug('Version Comment. sql: %r',\n", ' self.version_comment_query_mysql4)\n', ' cur.execute(self.version_comment_query_mysql4)\n', ' version_comment = cur.fetchone()[1].lower()\n', ' if isinstance(version_comment, bytes):\n', ' # with python3 this query returns bytes\n', " version_comment = version_comment.decode('utf-8')\n", ' else:\n', " _logger.debug('Version Comment. sql: %r',\n", ' self.version_comment_query)\n', ' cur.execute(self.version_comment_query)\n', ' version_comment = cur.fetchone()[0].lower()\n', '\n', " if 'mariadb' in version_comment:\n", " product_type = 'mariadb'\n", " elif 'percona' in version_comment:\n", " product_type = 'percona'\n", ' else:\n', " product_type = 'mysql'\n", '\n', ' self._server_type = (product_type, version)\n', ' return self._server_type\n', '\n', ' def get_connection_id(self):\n', ' if not self.connection_id:\n', ' self.reset_connection_id()\n', ' return self.connection_id\n', '\n', ' def reset_connection_id(self):\n', ' # Remember current connection id\n', " _logger.debug('Get current connection id')\n", " res = self.run('select connection_id()')\n", ' for title, cur, headers, status in res:\n', ' self.connection_id = cur.fetchone()[0]\n', " _logger.debug('Current connection id: %s', self.connection_id)\n", '\n', ' def change_db(self, db):\n', ' self.conn.select_db(db)\n', ' self.dbname = db\n'] tests = [] /usr/lib/python3.8/site-packages/_pytest/doctest.py:522: in _find doctest.DocTestFinder._find( # type: ignore doctest = globs = {'FIELD_TYPE': , 'FIELD_TYPES': {0: , 1: , 2: , 3: , 4: , 5: , 6: , 7: , 8: , 9: , 10: , 11: , 12: , 13: , 15: , 16: , 246: , 249: , 250: , 251: , 252: , 253: , 254: }, 'SQLExecute': , '__builtins__': {'ArithmeticError': , 'AssertionError': , 'AttributeError': , 'BaseException': , 'BlockingIOError': , 'BrokenPipeError': , 'BufferError': , 'BytesWarning': , 'ChildProcessError': , 'ConnectionAbortedError': , 'ConnectionError': , 'ConnectionRefusedError': , 'ConnectionResetError': , 'DeprecationWarning': , 'EOFError': , 'Ellipsis': Ellipsis, 'EnvironmentError': , 'Exception': , 'False': False, 'FileExistsError': , 'FileNotFoundError': , 'FloatingPointError': , 'FutureWarning': , 'GeneratorExit': , 'IOError': , 'ImportError': , 'ImportWarning': , 'IndentationError': , 'IndexError': , 'InterruptedError': , 'IsADirectoryError': , 'KeyError': , 'KeyboardInterrupt': , 'LookupError': , 'MemoryError': , 'ModuleNotFoundError': , 'NameError': , 'None': None, 'NotADirectoryError': , 'NotImplemented': NotImplemented, 'NotImplementedError': , 'OSError': , 'OverflowError': , 'PendingDeprecationWarning': , 'PermissionError': , 'ProcessLookupError': , 'RecursionError': , 'ReferenceError': , 'ResourceWarning': , 'RuntimeError': , 'RuntimeWarning': , 'StopAsyncIteration': , 'StopIteration': , 'SyntaxError': , 'SyntaxWarning': , 'SystemError': , 'SystemExit': , 'TabError': , 'TimeoutError': , 'True': True, 'TypeError': , 'UnboundLocalError': , 'UnicodeDecodeError': , 'UnicodeEncodeError': , 'UnicodeError': , 'UnicodeTranslateError': , 'UnicodeWarning': , 'UserWarning': , 'ValueError': , 'Warning': , 'ZeroDivisionError': , '__build_class__': , '__debug__': True, '__doc__': 'Built-in functions, exceptions, and other ' 'objects.\n' '\n' "Noteworthy: None is the `nil' object; Ellipsis " "represents `...' in slices.", '__import__': , '__loader__': , '__name__': 'builtins', '__package__': '', '__spec__': ModuleSpec(name='builtins', loader=), 'abs': , 'all': , 'any': , 'ascii': , 'bin': , 'bool': , 'breakpoint': , 'bytearray': , 'bytes': , 'callable': , 'chr': , 'classmethod': , 'compile': , 'complex': , 'copyright': Copyright (c) 2001-2021 Python Software Foundation. All Rights Reserved. Copyright (c) 2000 BeOpen.com. All Rights Reserved. Copyright (c) 1995-2001 Corporation for National Research Initiatives. All Rights Reserved. Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam. All Rights Reserved., 'credits': Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands for supporting Python development. See www.python.org for more information., 'delattr': , 'dict': , 'dir': , 'divmod': , 'enumerate': , 'eval': , 'exec': , 'exit': Use exit() or Ctrl-D (i.e. EOF) to exit, 'filter': , 'float': , 'format': , 'frozenset': , 'getattr': , 'globals': , 'hasattr': , 'hash': , 'help': Type help() for interactive help, or help(object) for help about object., 'hex': , 'id': , 'input': , 'int': , 'isinstance': , 'issubclass': , 'iter': , 'len': , 'license': Type license() to see the full license text, 'list': , 'locals': , 'map': , 'max': , 'memoryview': , 'min': , 'next': , 'object': , 'oct': , 'open': , 'ord': , 'pow': , 'print': , 'property': , 'quit': Use quit() or Ctrl-D (i.e. EOF) to exit, 'range': , 'repr': , 'reversed': , 'round': , 'set': , 'setattr': , 'slice': , 'sorted': , 'staticmethod': , 'str': , 'sum': , 'super': , 'tuple': , 'type': , 'vars': , 'zip': }, '__cached__': '/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/__pycache__/sqlexecute.cpython-38.pyc', '__doc__': None, '__file__': '/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/sqlexecute.py', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f26ad326ca0>, '__name__': 'mycli.sqlexecute', '__package__': 'mycli', '__spec__': ModuleSpec(name='mycli.sqlexecute', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7f26ad326ca0>, origin='/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/sqlexecute.py'), '_logger': , 'conversions': {0: , 1: , 2: , 3: , 4: , 5: , 7: , 8: , 9: , 10: , 11: , 12: , 13: , 15: , 16: , 246: , 249: , 250: , 251: , 252: , 253: , 254: , : , : , : , : , : , : , : , : , : , : , : , : , : , : , : , : , : }, 'convert_date': , 'convert_datetime': , 'convert_timedelta': , 'decoders': {0: , 1: , 2: , 3: , 4: , 5: , 7: , 8: , 9: , 10: , 11: , 12: , 13: , 15: , 16: , 246: , 249: , 250: , 251: , 252: , 253: , 254: }, 'logging': , 'paramiko': , 'pymysql': , 'special': , 'sqlparse': } module = name = 'mycli.sqlexecute' obj = seen = {139804091334224: 1} self = <_pytest.doctest.DoctestModule.collect..MockAwareDocTestFinder object at 0x7f26acc16880> source_lines = ['import logging\n', 'import pymysql\n', 'import sqlparse\n', 'from .packages import special\n', 'from pymysql.constants import FIELD_TYPE\n', 'from pymysql.converters import (convert_datetime,\n', ' convert_timedelta, convert_date, ' 'conversions,\n', ' decoders)\n', 'try:\n', ' import paramiko\n', 'except ImportError:\n', ' from mycli.packages.paramiko_stub import paramiko\n', '\n', '_logger = logging.getLogger(__name__)\n', '\n', 'FIELD_TYPES = decoders.copy()\n', 'FIELD_TYPES.update({\n', ' FIELD_TYPE.NULL: type(None)\n', '})\n', '\n', 'class SQLExecute(object):\n', '\n', " databases_query = '''SHOW DATABASES'''\n", '\n', " tables_query = '''SHOW TABLES'''\n", '\n', " version_query = '''SELECT @@VERSION'''\n", '\n', " version_comment_query = '''SELECT @@VERSION_COMMENT'''\n", " version_comment_query_mysql4 = '''SHOW VARIABLES LIKE " '"version_comment"\'\'\'\n', '\n', " show_candidates_query = '''SELECT name from mysql.help_topic WHERE name " 'like "SHOW %"\'\'\'\n', '\n', ' users_query = \'\'\'SELECT CONCAT("\'", user, "\'@\'",host,"\'") FROM ' "mysql.user'''\n", '\n', " functions_query = '''SELECT ROUTINE_NAME FROM " 'INFORMATION_SCHEMA.ROUTINES\n', ' WHERE ROUTINE_TYPE="FUNCTION" AND ROUTINE_SCHEMA = "%s"\'\'\'\n', '\n', " table_columns_query = '''select TABLE_NAME, COLUMN_NAME from " 'information_schema.columns\n', " where table_schema = '%s'\n", ' order by ' "table_name,ordinal_position'''\n", '\n', ' def __init__(self, database, user, password, host, port, socket, ' 'charset,\n', ' local_infile, ssl, ssh_user, ssh_host, ssh_port, ' 'ssh_password,\n', ' ssh_key_filename, init_command=None):\n', ' self.dbname = database\n', ' self.user = user\n', ' self.password = password\n', ' self.host = host\n', ' self.port = port\n', ' self.socket = socket\n', ' self.charset = charset\n', ' self.local_infile = local_infile\n', ' self.ssl = ssl\n', ' self._server_type = None\n', ' self.connection_id = None\n', ' self.ssh_user = ssh_user\n', ' self.ssh_host = ssh_host\n', ' self.ssh_port = ssh_port\n', ' self.ssh_password = ssh_password\n', ' self.ssh_key_filename = ssh_key_filename\n', ' self.init_command = init_command\n', ' self.connect()\n', '\n', ' def connect(self, database=None, user=None, password=None, host=None,\n', ' port=None, socket=None, charset=None, local_infile=None,\n', ' ssl=None, ssh_host=None, ssh_port=None, ssh_user=None,\n', ' ssh_password=None, ssh_key_filename=None, ' 'init_command=None):\n', ' db = (database or self.dbname)\n', ' user = (user or self.user)\n', ' password = (password or self.password)\n', ' host = (host or self.host)\n', ' port = (port or self.port)\n', ' socket = (socket or self.socket)\n', ' charset = (charset or self.charset)\n', ' local_infile = (local_infile or self.local_infile)\n', ' ssl = (ssl or self.ssl)\n', ' ssh_user = (ssh_user or self.ssh_user)\n', ' ssh_host = (ssh_host or self.ssh_host)\n', ' ssh_port = (ssh_port or self.ssh_port)\n', ' ssh_password = (ssh_password or self.ssh_password)\n', ' ssh_key_filename = (ssh_key_filename or self.ssh_key_filename)\n', ' init_command = (init_command or self.init_command)\n', ' _logger.debug(\n', " 'Connection DB Params: \\n'\n", " '\\tdatabase: %r'\n", " '\\tuser: %r'\n", " '\\thost: %r'\n", " '\\tport: %r'\n", " '\\tsocket: %r'\n", " '\\tcharset: %r'\n", " '\\tlocal_infile: %r'\n", " '\\tssl: %r'\n", " '\\tssh_user: %r'\n", " '\\tssh_host: %r'\n", " '\\tssh_port: %r'\n", " '\\tssh_password: %r'\n", " '\\tssh_key_filename: %r'\n", " '\\tinit_command: %r',\n", ' db, user, host, port, socket, charset, local_infile, ssl,\n', ' ssh_user, ssh_host, ssh_port, ssh_password, ssh_key_filename,\n', ' init_command\n', ' )\n', ' conv = conversions.copy()\n', ' conv.update({\n', ' FIELD_TYPE.TIMESTAMP: lambda obj: (convert_datetime(obj) or ' 'obj),\n', ' FIELD_TYPE.DATETIME: lambda obj: (convert_datetime(obj) or ' 'obj),\n', ' FIELD_TYPE.TIME: lambda obj: (convert_timedelta(obj) or obj),\n', ' FIELD_TYPE.DATE: lambda obj: (convert_date(obj) or obj),\n', ' })\n', '\n', ' defer_connect = False\n', '\n', ' if ssh_host:\n', ' defer_connect = True\n', '\n', ' client_flag = pymysql.constants.CLIENT.INTERACTIVE\n', ' if init_command and len(list(special.split_queries(init_command))) > ' '1:\n', ' client_flag |= pymysql.constants.CLIENT.MULTI_STATEMENTS\n', '\n', ' conn = pymysql.connect(\n', ' database=db, user=user, password=password, host=host, ' 'port=port,\n', ' unix_socket=socket, use_unicode=True, charset=charset,\n', ' autocommit=True, client_flag=client_flag,\n', ' local_infile=local_infile, conv=conv, ssl=ssl, ' 'program_name="mycli",\n', ' defer_connect=defer_connect, init_command=init_command\n', ' )\n', '\n', ' if ssh_host:\n', ' client = paramiko.SSHClient()\n', ' client.load_system_host_keys()\n', ' client.set_missing_host_key_policy(paramiko.WarningPolicy())\n', ' client.connect(\n', ' ssh_host, ssh_port, ssh_user, ssh_password,\n', ' key_filename=ssh_key_filename\n', ' )\n', ' chan = client.get_transport().open_channel(\n', " 'direct-tcpip',\n", ' (host, port),\n', " ('0.0.0.0', 0),\n", ' )\n', ' conn.connect(chan)\n', '\n', " if hasattr(self, 'conn'):\n", ' self.conn.close()\n', ' self.conn = conn\n', ' # Update them after the connection is made to ensure that it was a\n', ' # successful connection.\n', ' self.dbname = db\n', ' self.user = user\n', ' self.password = password\n', ' self.host = host\n', ' self.port = port\n', ' self.socket = socket\n', ' self.charset = charset\n', ' self.ssl = ssl\n', ' self.init_command = init_command\n', ' # retrieve connection id\n', ' self.reset_connection_id()\n', '\n', ' def run(self, statement):\n', ' """Execute the sql in the database and return the results. The ' 'results\n', ' are a list of tuples. Each tuple has 4 values\n', ' (title, rows, headers, status).\n', ' """\n', '\n', ' # Remove spaces and EOL\n', ' statement = statement.strip()\n', ' if not statement: # Empty string\n', ' yield (None, None, None, None)\n', '\n', ' # Split the sql into separate queries and run each one.\n', " # Unless it's saving a favorite query, in which case we\n", ' # want to save them all together.\n', " if statement.startswith('\\\\fs'):\n", ' components = [statement]\n', ' else:\n', ' components = special.split_queries(statement)\n', '\n', ' for sql in components:\n', ' # \\G is treated specially since we have to set the expanded ' 'output.\n', " if sql.endswith('\\\\G'):\n", ' special.set_expanded_output(True)\n', ' sql = sql[:-2].strip()\n', '\n', ' cur = self.conn.cursor()\n', ' try: # Special command\n', " _logger.debug('Trying a dbspecial command. sql: %r', sql)\n", ' for result in special.execute(cur, sql):\n', ' yield result\n', ' except special.CommandNotFound: # Regular SQL\n', " _logger.debug('Regular sql statement. sql: %r', sql)\n", ' cur.execute(sql)\n', ' while True:\n', ' yield self.get_result(cur)\n', '\n', ' # PyMySQL returns an extra, empty result set with ' 'stored\n', ' # procedures. We skip it (rowcount is zero and no\n', ' # description).\n', ' if not cur.nextset() or (not cur.rowcount and ' 'cur.description is None):\n', ' break\n', '\n', ' def get_result(self, cursor):\n', ' """Get the current result\'s data from the cursor."""\n', ' title = headers = None\n', '\n', ' # cursor.description is not None for queries that return result ' 'sets,\n', ' # e.g. SELECT or SHOW.\n', ' if cursor.description is not None:\n', ' headers = [x[0] for x in cursor.description]\n', " status = '{0} row{1} in set'\n", ' else:\n', " _logger.debug('No rows in result.')\n", " status = 'Query OK, {0} row{1} affected'\n", ' status = status.format(cursor.rowcount,\n', " '' if cursor.rowcount == 1 else 's')\n", '\n', ' return (title, cursor if cursor.description else None, headers, ' 'status)\n', '\n', ' def tables(self):\n', ' """Yields table names"""\n', '\n', ' with self.conn.cursor() as cur:\n', " _logger.debug('Tables Query. sql: %r', self.tables_query)\n", ' cur.execute(self.tables_query)\n', ' for row in cur:\n', ' yield row\n', '\n', ' def table_columns(self):\n', ' """Yields (table name, column name) pairs"""\n', ' with self.conn.cursor() as cur:\n', " _logger.debug('Columns Query. sql: %r', " 'self.table_columns_query)\n', ' cur.execute(self.table_columns_query % self.dbname)\n', ' for row in cur:\n', ' yield row\n', '\n', ' def databases(self):\n', ' with self.conn.cursor() as cur:\n', " _logger.debug('Databases Query. sql: %r', " 'self.databases_query)\n', ' cur.execute(self.databases_query)\n', ' return [x[0] for x in cur.fetchall()]\n', '\n', ' def functions(self):\n', ' """Yields tuples of (schema_name, function_name)"""\n', '\n', ' with self.conn.cursor() as cur:\n', " _logger.debug('Functions Query. sql: %r', " 'self.functions_query)\n', ' cur.execute(self.functions_query % self.dbname)\n', ' for row in cur:\n', ' yield row\n', '\n', ' def show_candidates(self):\n', ' with self.conn.cursor() as cur:\n', " _logger.debug('Show Query. sql: %r', " 'self.show_candidates_query)\n', ' try:\n', ' cur.execute(self.show_candidates_query)\n', ' except pymysql.DatabaseError as e:\n', " _logger.error('No show completions due to %r', e)\n", " yield ''\n", ' else:\n', ' for row in cur:\n', ' yield (row[0].split(None, 1)[-1], )\n', '\n', ' def users(self):\n', ' with self.conn.cursor() as cur:\n', " _logger.debug('Users Query. sql: %r', self.users_query)\n", ' try:\n', ' cur.execute(self.users_query)\n', ' except pymysql.DatabaseError as e:\n', " _logger.error('No user completions due to %r', e)\n", " yield ''\n", ' else:\n', ' for row in cur:\n', ' yield row\n', '\n', ' def server_type(self):\n', ' if self._server_type:\n', ' return self._server_type\n', ' with self.conn.cursor() as cur:\n', " _logger.debug('Version Query. sql: %r', self.version_query)\n", ' cur.execute(self.version_query)\n', ' version = cur.fetchone()[0]\n', " if version[0] == '4':\n", " _logger.debug('Version Comment. sql: %r',\n", ' self.version_comment_query_mysql4)\n', ' cur.execute(self.version_comment_query_mysql4)\n', ' version_comment = cur.fetchone()[1].lower()\n', ' if isinstance(version_comment, bytes):\n', ' # with python3 this query returns bytes\n', " version_comment = version_comment.decode('utf-8')\n", ' else:\n', " _logger.debug('Version Comment. sql: %r',\n", ' self.version_comment_query)\n', ' cur.execute(self.version_comment_query)\n', ' version_comment = cur.fetchone()[0].lower()\n', '\n', " if 'mariadb' in version_comment:\n", " product_type = 'mariadb'\n", " elif 'percona' in version_comment:\n", " product_type = 'percona'\n", ' else:\n', " product_type = 'mysql'\n", '\n', ' self._server_type = (product_type, version)\n', ' return self._server_type\n', '\n', ' def get_connection_id(self):\n', ' if not self.connection_id:\n', ' self.reset_connection_id()\n', ' return self.connection_id\n', '\n', ' def reset_connection_id(self):\n', ' # Remember current connection id\n', " _logger.debug('Get current connection id')\n", " res = self.run('select connection_id()')\n", ' for title, cur, headers, status in res:\n', ' self.connection_id = cur.fetchone()[0]\n', " _logger.debug('Current connection id: %s', self.connection_id)\n", '\n', ' def change_db(self, db):\n', ' self.conn.select_db(db)\n', ' self.dbname = db\n'] tests = [] /usr/lib/python3.8/doctest.py:998: in _find if ((inspect.isroutine(inspect.unwrap(val)) globs = {'FIELD_TYPE': , 'FIELD_TYPES': {0: , 1: , 2: , 3: , 4: , 5: , 6: , 7: , 8: , 9: , 10: , 11: , 12: , 13: , 15: , 16: , 246: , 249: , 250: , 251: , 252: , 253: , 254: }, 'SQLExecute': , '__builtins__': {'ArithmeticError': , 'AssertionError': , 'AttributeError': , 'BaseException': , 'BlockingIOError': , 'BrokenPipeError': , 'BufferError': , 'BytesWarning': , 'ChildProcessError': , 'ConnectionAbortedError': , 'ConnectionError': , 'ConnectionRefusedError': , 'ConnectionResetError': , 'DeprecationWarning': , 'EOFError': , 'Ellipsis': Ellipsis, 'EnvironmentError': , 'Exception': , 'False': False, 'FileExistsError': , 'FileNotFoundError': , 'FloatingPointError': , 'FutureWarning': , 'GeneratorExit': , 'IOError': , 'ImportError': , 'ImportWarning': , 'IndentationError': , 'IndexError': , 'InterruptedError': , 'IsADirectoryError': , 'KeyError': , 'KeyboardInterrupt': , 'LookupError': , 'MemoryError': , 'ModuleNotFoundError': , 'NameError': , 'None': None, 'NotADirectoryError': , 'NotImplemented': NotImplemented, 'NotImplementedError': , 'OSError': , 'OverflowError': , 'PendingDeprecationWarning': , 'PermissionError': , 'ProcessLookupError': , 'RecursionError': , 'ReferenceError': , 'ResourceWarning': , 'RuntimeError': , 'RuntimeWarning': , 'StopAsyncIteration': , 'StopIteration': , 'SyntaxError': , 'SyntaxWarning': , 'SystemError': , 'SystemExit': , 'TabError': , 'TimeoutError': , 'True': True, 'TypeError': , 'UnboundLocalError': , 'UnicodeDecodeError': , 'UnicodeEncodeError': , 'UnicodeError': , 'UnicodeTranslateError': , 'UnicodeWarning': , 'UserWarning': , 'ValueError': , 'Warning': , 'ZeroDivisionError': , '__build_class__': , '__debug__': True, '__doc__': 'Built-in functions, exceptions, and other ' 'objects.\n' '\n' "Noteworthy: None is the `nil' object; Ellipsis " "represents `...' in slices.", '__import__': , '__loader__': , '__name__': 'builtins', '__package__': '', '__spec__': ModuleSpec(name='builtins', loader=), 'abs': , 'all': , 'any': , 'ascii': , 'bin': , 'bool': , 'breakpoint': , 'bytearray': , 'bytes': , 'callable': , 'chr': , 'classmethod': , 'compile': , 'complex': , 'copyright': Copyright (c) 2001-2021 Python Software Foundation. All Rights Reserved. Copyright (c) 2000 BeOpen.com. All Rights Reserved. Copyright (c) 1995-2001 Corporation for National Research Initiatives. All Rights Reserved. Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam. All Rights Reserved., 'credits': Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands for supporting Python development. See www.python.org for more information., 'delattr': , 'dict': , 'dir': , 'divmod': , 'enumerate': , 'eval': , 'exec': , 'exit': Use exit() or Ctrl-D (i.e. EOF) to exit, 'filter': , 'float': , 'format': , 'frozenset': , 'getattr': , 'globals': , 'hasattr': , 'hash': , 'help': Type help() for interactive help, or help(object) for help about object., 'hex': , 'id': , 'input': , 'int': , 'isinstance': , 'issubclass': , 'iter': , 'len': , 'license': Type license() to see the full license text, 'list': , 'locals': , 'map': , 'max': , 'memoryview': , 'min': , 'next': , 'object': , 'oct': , 'open': , 'ord': , 'pow': , 'print': , 'property': , 'quit': Use quit() or Ctrl-D (i.e. EOF) to exit, 'range': , 'repr': , 'reversed': , 'round': , 'set': , 'setattr': , 'slice': , 'sorted': , 'staticmethod': , 'str': , 'sum': , 'super': , 'tuple': , 'type': , 'vars': , 'zip': }, '__cached__': '/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/__pycache__/sqlexecute.cpython-38.pyc', '__doc__': None, '__file__': '/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/sqlexecute.py', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f26ad326ca0>, '__name__': 'mycli.sqlexecute', '__package__': 'mycli', '__spec__': ModuleSpec(name='mycli.sqlexecute', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7f26ad326ca0>, origin='/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/sqlexecute.py'), '_logger': , 'conversions': {0: , 1: , 2: , 3: , 4: , 5: , 7: , 8: , 9: , 10: , 11: , 12: , 13: , 15: , 16: , 246: , 249: , 250: , 251: , 252: , 253: , 254: , : , : , : , : , : , : , : , : , : , : , : , : , : , : , : , : , : }, 'convert_date': , 'convert_datetime': , 'convert_timedelta': , 'decoders': {0: , 1: , 2: , 3: , 4: , 5: , 7: , 8: , 9: , 10: , 11: , 12: , 13: , 15: , 16: , 246: , 249: , 250: , 251: , 252: , 253: , 254: }, 'logging': , 'paramiko': , 'pymysql': , 'special': , 'sqlparse': } module = name = 'mycli.sqlexecute' obj = seen = {139804091334224: 1} self = <_pytest.doctest.DoctestModule.collect..MockAwareDocTestFinder object at 0x7f26acc16880> source_lines = ['import logging\n', 'import pymysql\n', 'import sqlparse\n', 'from .packages import special\n', 'from pymysql.constants import FIELD_TYPE\n', 'from pymysql.converters import (convert_datetime,\n', ' convert_timedelta, convert_date, ' 'conversions,\n', ' decoders)\n', 'try:\n', ' import paramiko\n', 'except ImportError:\n', ' from mycli.packages.paramiko_stub import paramiko\n', '\n', '_logger = logging.getLogger(__name__)\n', '\n', 'FIELD_TYPES = decoders.copy()\n', 'FIELD_TYPES.update({\n', ' FIELD_TYPE.NULL: type(None)\n', '})\n', '\n', 'class SQLExecute(object):\n', '\n', " databases_query = '''SHOW DATABASES'''\n", '\n', " tables_query = '''SHOW TABLES'''\n", '\n', " version_query = '''SELECT @@VERSION'''\n", '\n', " version_comment_query = '''SELECT @@VERSION_COMMENT'''\n", " version_comment_query_mysql4 = '''SHOW VARIABLES LIKE " '"version_comment"\'\'\'\n', '\n', " show_candidates_query = '''SELECT name from mysql.help_topic WHERE name " 'like "SHOW %"\'\'\'\n', '\n', ' users_query = \'\'\'SELECT CONCAT("\'", user, "\'@\'",host,"\'") FROM ' "mysql.user'''\n", '\n', " functions_query = '''SELECT ROUTINE_NAME FROM " 'INFORMATION_SCHEMA.ROUTINES\n', ' WHERE ROUTINE_TYPE="FUNCTION" AND ROUTINE_SCHEMA = "%s"\'\'\'\n', '\n', " table_columns_query = '''select TABLE_NAME, COLUMN_NAME from " 'information_schema.columns\n', " where table_schema = '%s'\n", ' order by ' "table_name,ordinal_position'''\n", '\n', ' def __init__(self, database, user, password, host, port, socket, ' 'charset,\n', ' local_infile, ssl, ssh_user, ssh_host, ssh_port, ' 'ssh_password,\n', ' ssh_key_filename, init_command=None):\n', ' self.dbname = database\n', ' self.user = user\n', ' self.password = password\n', ' self.host = host\n', ' self.port = port\n', ' self.socket = socket\n', ' self.charset = charset\n', ' self.local_infile = local_infile\n', ' self.ssl = ssl\n', ' self._server_type = None\n', ' self.connection_id = None\n', ' self.ssh_user = ssh_user\n', ' self.ssh_host = ssh_host\n', ' self.ssh_port = ssh_port\n', ' self.ssh_password = ssh_password\n', ' self.ssh_key_filename = ssh_key_filename\n', ' self.init_command = init_command\n', ' self.connect()\n', '\n', ' def connect(self, database=None, user=None, password=None, host=None,\n', ' port=None, socket=None, charset=None, local_infile=None,\n', ' ssl=None, ssh_host=None, ssh_port=None, ssh_user=None,\n', ' ssh_password=None, ssh_key_filename=None, ' 'init_command=None):\n', ' db = (database or self.dbname)\n', ' user = (user or self.user)\n', ' password = (password or self.password)\n', ' host = (host or self.host)\n', ' port = (port or self.port)\n', ' socket = (socket or self.socket)\n', ' charset = (charset or self.charset)\n', ' local_infile = (local_infile or self.local_infile)\n', ' ssl = (ssl or self.ssl)\n', ' ssh_user = (ssh_user or self.ssh_user)\n', ' ssh_host = (ssh_host or self.ssh_host)\n', ' ssh_port = (ssh_port or self.ssh_port)\n', ' ssh_password = (ssh_password or self.ssh_password)\n', ' ssh_key_filename = (ssh_key_filename or self.ssh_key_filename)\n', ' init_command = (init_command or self.init_command)\n', ' _logger.debug(\n', " 'Connection DB Params: \\n'\n", " '\\tdatabase: %r'\n", " '\\tuser: %r'\n", " '\\thost: %r'\n", " '\\tport: %r'\n", " '\\tsocket: %r'\n", " '\\tcharset: %r'\n", " '\\tlocal_infile: %r'\n", " '\\tssl: %r'\n", " '\\tssh_user: %r'\n", " '\\tssh_host: %r'\n", " '\\tssh_port: %r'\n", " '\\tssh_password: %r'\n", " '\\tssh_key_filename: %r'\n", " '\\tinit_command: %r',\n", ' db, user, host, port, socket, charset, local_infile, ssl,\n', ' ssh_user, ssh_host, ssh_port, ssh_password, ssh_key_filename,\n', ' init_command\n', ' )\n', ' conv = conversions.copy()\n', ' conv.update({\n', ' FIELD_TYPE.TIMESTAMP: lambda obj: (convert_datetime(obj) or ' 'obj),\n', ' FIELD_TYPE.DATETIME: lambda obj: (convert_datetime(obj) or ' 'obj),\n', ' FIELD_TYPE.TIME: lambda obj: (convert_timedelta(obj) or obj),\n', ' FIELD_TYPE.DATE: lambda obj: (convert_date(obj) or obj),\n', ' })\n', '\n', ' defer_connect = False\n', '\n', ' if ssh_host:\n', ' defer_connect = True\n', '\n', ' client_flag = pymysql.constants.CLIENT.INTERACTIVE\n', ' if init_command and len(list(special.split_queries(init_command))) > ' '1:\n', ' client_flag |= pymysql.constants.CLIENT.MULTI_STATEMENTS\n', '\n', ' conn = pymysql.connect(\n', ' database=db, user=user, password=password, host=host, ' 'port=port,\n', ' unix_socket=socket, use_unicode=True, charset=charset,\n', ' autocommit=True, client_flag=client_flag,\n', ' local_infile=local_infile, conv=conv, ssl=ssl, ' 'program_name="mycli",\n', ' defer_connect=defer_connect, init_command=init_command\n', ' )\n', '\n', ' if ssh_host:\n', ' client = paramiko.SSHClient()\n', ' client.load_system_host_keys()\n', ' client.set_missing_host_key_policy(paramiko.WarningPolicy())\n', ' client.connect(\n', ' ssh_host, ssh_port, ssh_user, ssh_password,\n', ' key_filename=ssh_key_filename\n', ' )\n', ' chan = client.get_transport().open_channel(\n', " 'direct-tcpip',\n", ' (host, port),\n', " ('0.0.0.0', 0),\n", ' )\n', ' conn.connect(chan)\n', '\n', " if hasattr(self, 'conn'):\n", ' self.conn.close()\n', ' self.conn = conn\n', ' # Update them after the connection is made to ensure that it was a\n', ' # successful connection.\n', ' self.dbname = db\n', ' self.user = user\n', ' self.password = password\n', ' self.host = host\n', ' self.port = port\n', ' self.socket = socket\n', ' self.charset = charset\n', ' self.ssl = ssl\n', ' self.init_command = init_command\n', ' # retrieve connection id\n', ' self.reset_connection_id()\n', '\n', ' def run(self, statement):\n', ' """Execute the sql in the database and return the results. The ' 'results\n', ' are a list of tuples. Each tuple has 4 values\n', ' (title, rows, headers, status).\n', ' """\n', '\n', ' # Remove spaces and EOL\n', ' statement = statement.strip()\n', ' if not statement: # Empty string\n', ' yield (None, None, None, None)\n', '\n', ' # Split the sql into separate queries and run each one.\n', " # Unless it's saving a favorite query, in which case we\n", ' # want to save them all together.\n', " if statement.startswith('\\\\fs'):\n", ' components = [statement]\n', ' else:\n', ' components = special.split_queries(statement)\n', '\n', ' for sql in components:\n', ' # \\G is treated specially since we have to set the expanded ' 'output.\n', " if sql.endswith('\\\\G'):\n", ' special.set_expanded_output(True)\n', ' sql = sql[:-2].strip()\n', '\n', ' cur = self.conn.cursor()\n', ' try: # Special command\n', " _logger.debug('Trying a dbspecial command. sql: %r', sql)\n", ' for result in special.execute(cur, sql):\n', ' yield result\n', ' except special.CommandNotFound: # Regular SQL\n', " _logger.debug('Regular sql statement. sql: %r', sql)\n", ' cur.execute(sql)\n', ' while True:\n', ' yield self.get_result(cur)\n', '\n', ' # PyMySQL returns an extra, empty result set with ' 'stored\n', ' # procedures. We skip it (rowcount is zero and no\n', ' # description).\n', ' if not cur.nextset() or (not cur.rowcount and ' 'cur.description is None):\n', ' break\n', '\n', ' def get_result(self, cursor):\n', ' """Get the current result\'s data from the cursor."""\n', ' title = headers = None\n', '\n', ' # cursor.description is not None for queries that return result ' 'sets,\n', ' # e.g. SELECT or SHOW.\n', ' if cursor.description is not None:\n', ' headers = [x[0] for x in cursor.description]\n', " status = '{0} row{1} in set'\n", ' else:\n', " _logger.debug('No rows in result.')\n", " status = 'Query OK, {0} row{1} affected'\n", ' status = status.format(cursor.rowcount,\n', " '' if cursor.rowcount == 1 else 's')\n", '\n', ' return (title, cursor if cursor.description else None, headers, ' 'status)\n', '\n', ' def tables(self):\n', ' """Yields table names"""\n', '\n', ' with self.conn.cursor() as cur:\n', " _logger.debug('Tables Query. sql: %r', self.tables_query)\n", ' cur.execute(self.tables_query)\n', ' for row in cur:\n', ' yield row\n', '\n', ' def table_columns(self):\n', ' """Yields (table name, column name) pairs"""\n', ' with self.conn.cursor() as cur:\n', " _logger.debug('Columns Query. sql: %r', " 'self.table_columns_query)\n', ' cur.execute(self.table_columns_query % self.dbname)\n', ' for row in cur:\n', ' yield row\n', '\n', ' def databases(self):\n', ' with self.conn.cursor() as cur:\n', " _logger.debug('Databases Query. sql: %r', " 'self.databases_query)\n', ' cur.execute(self.databases_query)\n', ' return [x[0] for x in cur.fetchall()]\n', '\n', ' def functions(self):\n', ' """Yields tuples of (schema_name, function_name)"""\n', '\n', ' with self.conn.cursor() as cur:\n', " _logger.debug('Functions Query. sql: %r', " 'self.functions_query)\n', ' cur.execute(self.functions_query % self.dbname)\n', ' for row in cur:\n', ' yield row\n', '\n', ' def show_candidates(self):\n', ' with self.conn.cursor() as cur:\n', " _logger.debug('Show Query. sql: %r', " 'self.show_candidates_query)\n', ' try:\n', ' cur.execute(self.show_candidates_query)\n', ' except pymysql.DatabaseError as e:\n', " _logger.error('No show completions due to %r', e)\n", " yield ''\n", ' else:\n', ' for row in cur:\n', ' yield (row[0].split(None, 1)[-1], )\n', '\n', ' def users(self):\n', ' with self.conn.cursor() as cur:\n', " _logger.debug('Users Query. sql: %r', self.users_query)\n", ' try:\n', ' cur.execute(self.users_query)\n', ' except pymysql.DatabaseError as e:\n', " _logger.error('No user completions due to %r', e)\n", " yield ''\n", ' else:\n', ' for row in cur:\n', ' yield row\n', '\n', ' def server_type(self):\n', ' if self._server_type:\n', ' return self._server_type\n', ' with self.conn.cursor() as cur:\n', " _logger.debug('Version Query. sql: %r', self.version_query)\n", ' cur.execute(self.version_query)\n', ' version = cur.fetchone()[0]\n', " if version[0] == '4':\n", " _logger.debug('Version Comment. sql: %r',\n", ' self.version_comment_query_mysql4)\n', ' cur.execute(self.version_comment_query_mysql4)\n', ' version_comment = cur.fetchone()[1].lower()\n', ' if isinstance(version_comment, bytes):\n', ' # with python3 this query returns bytes\n', " version_comment = version_comment.decode('utf-8')\n", ' else:\n', " _logger.debug('Version Comment. sql: %r',\n", ' self.version_comment_query)\n', ' cur.execute(self.version_comment_query)\n', ' version_comment = cur.fetchone()[0].lower()\n', '\n', " if 'mariadb' in version_comment:\n", " product_type = 'mariadb'\n", " elif 'percona' in version_comment:\n", " product_type = 'percona'\n", ' else:\n', " product_type = 'mysql'\n", '\n', ' self._server_type = (product_type, version)\n', ' return self._server_type\n', '\n', ' def get_connection_id(self):\n', ' if not self.connection_id:\n', ' self.reset_connection_id()\n', ' return self.connection_id\n', '\n', ' def reset_connection_id(self):\n', ' # Remember current connection id\n', " _logger.debug('Get current connection id')\n", " res = self.run('select connection_id()')\n", ' for title, cur, headers, status in res:\n', ' self.connection_id = cur.fetchone()[0]\n', " _logger.debug('Current connection id: %s', self.connection_id)\n", '\n', ' def change_db(self, db):\n', ' self.conn.select_db(db)\n', ' self.dbname = db\n'] test = None tests = [] val = valname = 'mycli.sqlexecute.paramiko' /usr/lib/python3.8/site-packages/_pytest/doctest.py:471: in _mock_aware_unwrap return real_unwrap(func, stop=_is_mocked) func = real_unwrap = stop = None /usr/lib/python3.8/inspect.py:520: in unwrap while _is_wrapper(func): _is_wrapper = ._is_wrapper at 0x7f26acec6790> f = func = memo = {139804091248304: } recursion_limit = 1000 stop = /usr/lib/python3.8/inspect.py:514: in _is_wrapper return hasattr(f, '__wrapped__') and not stop(f) f = stop = mycli/packages/paramiko_stub/__init__.py:25: in __getattr__ sys.exit(1) E SystemExit: 1 dedent = name = '__wrapped__' self = sys = ------------------------------- Captured stdout -------------------------------- To enable certain SSH features you need to install paramiko: pip install paramiko It is required for the following configuration options: --list-ssh-config --ssh-config-host --ssh-host =============================== warnings summary =============================== mycli/main.py:484 /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/main.py:484: DeprecationWarning: invalid escape sequence \e """Editor command is any query that is prefixed or suffixed by a '\e'. mycli/main.py:1294 /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/main.py:1294: DeprecationWarning: invalid escape sequence \* m = re.match('^ *\* (.*)', line) mycli/packages/parseutils.py:14 /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/packages/parseutils.py:14: DeprecationWarning: invalid escape sequence \s 'all_punctuations': re.compile('([^\s]+)$'), mycli/packages/parseutils.py:18 /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/packages/parseutils.py:18: DeprecationWarning: invalid escape sequence \d """ mycli/packages/special/iocommands.py:118 /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/packages/special/iocommands.py:118: DeprecationWarning: invalid escape sequence \e pattern = re.compile('(^\\\e|\\\e$)') mycli/packages/special/iocommands.py:216 /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/packages/special/iocommands.py:216: DeprecationWarning: invalid escape sequence \d match = re.search('\\$\d+', query) mycli/sqlcompleter.py:62 /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/mycli/sqlcompleter.py:62: DeprecationWarning: invalid escape sequence \$ self.name_pattern = compile("^[_a-z][_a-z0-9\$]*$") test/conftest.py:7 /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/test/conftest.py:7: PytestDeprecationWarning: @pytest.yield_fixture is deprecated. Use @pytest.fixture instead; they are the same. @pytest.yield_fixture(scope="function") test/test_sqlexecute.py:169 /var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2/test/test_sqlexecute.py:169: DeprecationWarning: invalid escape sequence \G results = run(executor, "\\f test-ae \G") -- Docs: https://docs.pytest.org/en/stable/warnings.html =========================== short test summary info ============================ ERROR mycli/main.py - SystemExit: 1 ERROR mycli/sqlexecute.py - SystemExit: 1 !!!!!!!!!!!!!!!!!!! Interrupted: 2 errors during collection !!!!!!!!!!!!!!!!!!!! ======================== 9 warnings, 2 errors in 0.74s ========================= * ERROR: dev-db/mycli-1.22.2_p20201026::gentoo failed (test phase): * pytest failed with python3.8 * * Call stack: * ebuild.sh, line 125: Called src_test * environment, line 2796: Called distutils-r1_src_test * environment, line 1301: Called _distutils-r1_run_foreach_impl 'python_test' * environment, line 607: Called distutils-r1_run_phase 'python_test' * environment, line 1240: Called python_test * environment, line 2769: Called epytest '--capture=sys' '--doctest-modules' '--doctest-ignore-import-errors' '--ignore=setup.py' '--ignore=mycli/magic.py' '--ignore=mycli/packages/parseutils.py' '--ignore=test/features' '--ignore=mycli/packages/paramiko_stub/__init__.py' * environment, line 1614: Called die * The specific snippet of code: * "${@}" || die -n "pytest failed with ${EPYTHON}"; * * If you need support, post the output of `emerge --info '=dev-db/mycli-1.22.2_p20201026::gentoo'`, * the complete build log and the output of `emerge -pqv '=dev-db/mycli-1.22.2_p20201026::gentoo'`. * The complete build log is located at '/var/log/emerge-log/build/dev-db/mycli-1.22.2_p20201026:20210523-115928.log'. * For convenience, a symlink to the build log is located at '/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/temp/build.log'. * The ebuild environment file is located at '/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/temp/environment'. * Working directory: '/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2' * S: '/var/tmp/portage/dev-db/mycli-1.22.2_p20201026/work/mycli-1.22.2'